I have two models Employee , EmployeeDepartment. I made a dynamic select menu so when I choose a department it will filter employees depending on that department using the following code by simple_form
<%= f.input :employee_id , collection: #departments, as: :grouped_select, group_method: :employees, include_blank: false %>
Note: #departments = EmployeeDepartment.order(:name)
What I want to do is:
Before having dynamic selection I used this code in order to fetch specific employees
<%= f.association :employee, :collection => #supervisors_list, :label_method => :full_name, :value_method => :id, include_blank: false %>
Note that: #supervisors_list = Employee.where('guidance_supervisor' => true).order(:first_name)
guidance_supervisors.js.coffee
jQuery ->
$('#guidance_supervisor_employee_id').parent().hide()
employee = $('#guidance_supervisor_employee_id').html()
$('#guidance_supervisor_employee_department_id').change ->
department = $('#guidance_supervisor_employee_department_id :selected').text()
escaped_department = department.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(employee).filter("optgroup[label='#{escaped_department}']").html()
if options
$('#guidance_supervisor_employee_id').html(options)
$('#guidance_supervisor_employee_id').parent().show()
else
$('#guidance_supervisor_employee_id').empty()
$('#guidance_supervisor_employee_id').parent().hide()
After adding the dynamic select I am not able to use #supervisors_list which makes the menu fetch all employees. I need to be able to use #supervisors_list again, is there any way to achieve that ?
You need to use something like Gon. It has a watch feature that can help reload data without reloading page see here
Te problem with your code is only that it filters the page without reloading it. So basically being the #supervisors_list built server side you can:
use an ajax method to get the new filtered #supervisor_list from the server (gon watch or directly use jQuery .ajax)
add the #supervisor_list data to your page javascript and filter it after department filtering (also through gon or read this railscast)
There is a simple way to implement the same.
https://gist.github.com/romansklenar/3077281
This may help you to fix the problem.
Related
I'm building an app where a user can customize components in a pc(system), based on components that are available in their respective tables (eg. motherboards table, cpus table.. etc)
I would like the user to be able to select the components via a dropdown select in the system form.
I have been able to achieve this by using collection_select like this
<%= collection_select(:system, :motherboard_id, Motherboard.all, :id, :model, prompt: true) %>
However, the collection_select displays all components in the table, and I wish to only display those components that have an available: true attribute.
I have tried
<%= collection_select(:system, :motherboard_id, Motherboard.any? {|mobo| mobo.available?} , :id, :model, prompt: true) %>
which results in undefined method 'map' for false:FalseClass screenshot:
I thought about adding a before_save callback that checks each items availability, but if that's not the only way to get it to work, I think that would be a poor decision in terms of UX
You can use
<%= collection_select(:system, :motherboard_id, Motherboard.where(available: true), :id, :model, prompt: true) %>
I thought this would be fairly easy, but I'm not finding any help by Googling.
I have a form (simple_form) with numerous inputs with select lists (collections) that are populated from the database, so many it is slowing down the initial page load. I thought I could speed it up by only populating those drop down lists as the user selects them using Ajax. Is there something built in like remote => true for the form itself? Can someone point me in the right direction?
EDIT:
I found this SO question but I cannot figure out how to implement the answer.
Currently, my form looks like this;
= simple_form_for(#account)
= f.input :account_number
= f.input :area, collection: #areas
= f.submit nil, :class => 'btn btn-primary'
Based on the answer in the linked question, I should add something like this, but of course it is not working
= simple_form_for(#account)
= f.input :account_number
= f.input :area, collection: #areas, :input_html => {"data-remote" => true, "data-url" => "/my_areas", "data-type" => :json}
= f.submit nil, :class => 'btn btn-primary'
I can think of two ways to go about this if you don't want to load the contents initially when the page loads. One way is to run a script after the DOM has loaded to change the options for the select tag and the other is to collect the options when you click on the drop-down on the select element. I might go for the first way because there wouldn't be latency when a user clicks on the select element--they wouldn't have to wait for the options to populate.
So you'd run a jQuery script on document ready that makes an AJAX call to a method in your controller, which then returns the collections you want, then you iterate through the select elements you want to change with JQuery scripts. It might look something like this.
# in view with the select options to be changed
$(document).ready(function() {
$.get(change_selects_path, function(response) {
$.each(response, function(args) {
// code for each select element to be changed
$('.class_of_select_element').html(<%= j options_from_collection_for_select(args) %>);
});
});
)};
# in controller
def change_selects
# make db calls and store in variables to feed to $.get request
end
Note that this not tested but should give you a good start towards a solution. For further info on the each loop, you can check out this documentation.
Not sure if this fits your exact use case (please clarify if not), but I also have a few collection selects that have a large amount of database rows behind them. I use the select2-rails gem to take care of this. Users can begin to type in the name and the relevant results will show up (it will also show a few initially if they don't type something).
Check it out here: https://github.com/argerim/select2-rails
Edit: For a cascading dropdown, I recommend this gem: https://github.com/ryanb/nested_form
I have form for adding a new job. On my form I have a select drop-down list. I need to associate the new job to a customer. The following works great.
<%= f.collection_select :customer_id, Customer.all, :id, :business_name %>
But, what if I want to also be able to send in a customer_id to the new form? Can I have the form's select drop-down show all the possible customers, as above, but have it auto select the customer_id I pass into the form, if a customer_id is passed in?
url = ...jobs/new
OR
url = ...jobs/new?customer_id=5
I apologize if I did not explain this well enough.
Thanks in advance.
--jc
I think you do what you're trying to achieve this by populating the customer_id field on the job you're creating in your controller if customer_id is present in the request params. This should make that particular customer be the initially selected option in the form.
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
e.g. Something like.
if params[:customer_id].present?
job.customer_id = params[:customer_id]
end
If you declaring the instance variable #customer in your controller action then you can use selected option as:
<%= f.collection_select :customer_id, Customer.all, :id, :business_name, {:selected => #customer.id} %>
How can I create a select box that has the following given 4 results for User.departments:
Department.title (Department.abbreviation)
Department.title (Department.abbreviation)
Department.title (Department.abbreviation)
Department.title (Department.abbreviation)
-----
Add New Department
Based on the following models:
User.department_id
Departments (id, title, abbreviation)
What I can't figure out is how add the two options at the bottom that say Add New Department.
Here is what I have so far:
<%= collection_select(:user, :department_id, Department.where(:id => current_user.department_id), :id, :title, {:prompt => true}) %>
Thanks
Your best bet is to use select instead of collection_select for this, here is an example of how I would do it.
<%= f.select(:user, Department.where(:id => current_user.department_id).collect {|p| [[p.title,' (', p.abbreviation,')'], p.id] } + ['Add New Department']) %>
Then you could use something like javascript to do something when 'Add New Department' got selected or however you planned on using it.
Hope this helps and happy coding.
In my app, there are two models: rfq and standard. Their relationship is many-to-many. In rfq creating screen, the code below displays a list of available for selection in drop down list:
<%= simple_form_for #rfq do |f| %>
<%= f.association :standards, :collection => Standard.active_std.all(:order => 'name'), :label_method => :name, :value_method => :id %>
<% end %>
The problem is that the list is not collapsed, which means there are multiple standards displayed in a multi-line boxes. How can I reduce the box to one line only?
Thanks.
UPDATED: here is the screen shot of multiple line list box:
It's creating a multi-select because one rfq can have many standards, so it allows you to ctrl-click to select many standards.
You could try adding :input_html => { :size =>'1' } but I'm not sure that will preserve the scrollbar. It definitely won't drop down.
Here's someone else who wanted to do the same thing: HTML muliple select should look like HTML select. One of the answers refers to a Dropdown Check List implemented in jQuery, but that would take some work to integrate with SimpleForm.
SimpleForm has a very helpful Google Group--you might get more ideas there:
http://groups.google.com/group/plataformatec-simpleform
You can add as: :collection_select
Use
=f.collecion_select, model_associated_ids, collection, value, label
in your is like this
=f.collection_select, :standard_ids, Standard.active_std.all, :id, :name
you can find more info here
https://github.com/plataformatec/simple_form