5

I'm working on a rails app but cannot find how to handle dependent drop down lists. I have 3 models: - Category which has several groups - Group which has several members - Member

When a category is selected, I'd like the groups within this category to populate the second drop down list (and same thing between group and member).

I have the following form (obviously this is not working how I'd like as I take all the items for the particular model)...

<div class="field">
<%= f.collection_select(:category, Category.find(:all), :id, :name, {:include_blank => 'Category'}) %>
</div>
<div class="field">
<%= f.collection_select(:group, Group.find(:all), :id, :name, {:include_blank => 'Group'}) %>
</div>
<div class="field">
<%= f.collection_select(:member, Member.find(:all), :id, :name, {:include_blank => 'Member'}) %>
</div>
<div class="actions">
<%= f.submit %>
</div>

What would be the best way to make those fields dependent ? I found several topics regarding this on the web but could not really find an answer.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Luc
  • 16,604
  • 34
  • 121
  • 183

2 Answers2

5

The best way of doing it is AJAX call. In the starting just populate category drop-down. And on change of category make an ajax call and populate groups. And do same for the members on groups drop-down change.

Try something like this:

$("#category']").click(function(){
  var url = '/get_drop_down_options?category_id=' + $(this).val()
  $("#group").removeOption(/./)
  $.get(url, function(data) {
    $('#group').addOption(data, false);
  });
});

In your controller:

def get_drop_down_options
  val = params[:category_id]
  #Use val to find records
  options = YourModel.collect{|x| "'#{x.id}' : '#{x.label}'"}    
  render :text => "{#{options.join(",")}}" 
end

Now you dont need partial.

mabu
  • 286
  • 8
  • 26
Ashish
  • 5,723
  • 2
  • 24
  • 25
  • Yes. jQuery will be most suitable for your requirement – Ashish Mar 15 '11 at 12:28
  • hmmm... I still have a strange thing when I use JQuery. $.getJSON will retrieve something like {'1' : 'first','2' : 'second'} but this JSON guy is flagged as invalid JSON... would you have any idea ? – Luc Mar 15 '11 at 20:55
  • Yes, I understood, it should be {"1" : "first","2" : "second"}, with double cote instead of single one. – Luc Mar 15 '11 at 21:00
  • Definitely the right approach. I was not able to get .click to work in Chrome, but .change works fine, and has the added benefit of only making the AJAX/JSON call when the selection is changed. – steakchaser Jul 12 '12 at 16:54
  • 1
    Does one need some sort of plugin for this? When I try this solution, I get a TypeError that "addOption" is not a method for that object. – melancholyfleur Aug 10 '12 at 18:01
  • You need only jQuery for this solution. – Ashish Aug 28 '12 at 06:45
  • 1
    [There is no such jQuery function called `.addOption()`](http://jquery.com/?s=addOption). – Sparky Nov 19 '14 at 17:47
  • great idea you save my day – Asnad Atta Nov 27 '14 at 07:21
0

I would have a different Id for each field, and use some jquery animation and ajax magic: When a field is clicked I would do an ajax call to retrieve all the records of the subgroup, once i got them, make appear that div with a slide down animation, or similar.

Pizzicato
  • 1,473
  • 1
  • 16
  • 32