Question

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'
Was it helpful?

Solution

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.

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top