dependant dropdowns (select menus) using rails

There are multiple solutions on the net for dynamic select menus. By saying “dynamic menus” I mean that we have a form with two select dropdowns. When we change the first one, the content of the second one is updated.
The most promising that I have found are:
A. http://railscasts.com/episodes/88-dynamic-select-menus
This one includes writing JS code. I don’t like writing JS code.
B. http://github.com/splendeo/dependent_select
This one does not use AJAX. It generates the whole thing in JS and sends it to the client. Can be useful when dealing with not big data.
C. http://pullmonkey.com/2008/3/30/dynamic-select-boxes-ruby-on-rails/
A very nice one but in my opinion a bit complicated for a beginner.

I had to develop my own solution. This is what I came up with. Lets assume we have a form for Foo model that has a select dropdown with Bar1 model and select dropdown with Bar2 model, that is dependent on Bar1 current selection.
A. In the Foo model form, add a field observer:

  <%= observe_field :foo_box1_id, :url => { :action => :box2_select_box },
      :update => :foo_box2_id,
      :with => :box1_id
      %>

B. In the FooController add:

  def box2_select_box
    @box1 = Box1.find(params[:box1_id]) unless params[:box1_id].empty?
    render :layout => false
  end

C. In the view for the above action (box2_select_box.html.erb) put:

<%=
if @box1
  options_from_collection_for_select(@box1.box2s, :id, :name)
else
  options_for_select([["Nothing to select", ""]])
end
%>


No JS code writing. Working with AJAX. Simple.

EDIT:
In reply to Rob Bean’s comment (thanks!) I attach a full rails project with a sample.
The “@box1.box2s” comes from models association. box1 has_many box2s (see box1.rb)

This entry was posted on Thu, 12 Nov 2009 22:37:00 GMT and Posted in . You can follow any any response to this entry through the Atom feed. You can leave a comment .
Tags , , , , ,


Comments

Leave a response

  1. Rob Bean 5 days later:

    In this code: <%= if @box1 optionsfromcollectionforselect(@box1.box2s, :id, :name) else optionsforselect([[“Nothing to select”, “”]]) end %>

    Where did box2s come from?

    Also, is this code nested inside a select_tag.

    I like how clean this is, but some context would really help flesh out this tutorial.

  2. powertoaster 16 days later:

    Very clean and dry.

    Exactly what I was looking for. I especially like that you provided a full project to test with.

  3. Mathias 27 days later:

    very good clean and simple solution

    thank you

  4. baster about 1 month later:

    it doesn’t work to me on rails 2.3.5 :/

  5. wojtek about 1 month later:

    @baster: Well, it should work, I just checked. What errors do you get? Have you checked the logs?

  6. baster about 1 month later:

    Processing FoosController#box2selectbox (for 127.0.0.1 at 2009-12-30 12:04:21) [POST] Parameters: {“box1id”=>”1”, “controller”=>”foos”, “action”=>”box2select_box”}

    ActiveRecord::RecordNotFound (Couldn’t find foo without an ID):

  7. baster about 1 month later:

    sorry all works fine I have a problem with declarativeauthorization, which I dont know why blocking all the time box2select_box method :/

Leave a comment

Please enter the outcome of the equation:
Draw_image