#88
Jan 13, 2008

Dynamic Select Menus

See how to dynamically change a select menu based on another select menu using Javascript. In this episode everything is kept client side which leads to a more responsive user interface.
Tags: forms views ajax
Download (18.1 MB, 7:02)
alternative download for iPod & Apple TV (10.9 MB, 7:02)
# javascripts_controller.rb
def dynamic_states
  @states = State.find(:all)
end

# application_helper.rb
def javascript(*files)
  content_for(:head) { javascript_include_tag(*files) }
end

def stylesheet(*files)
  content_for(:head) { stylesheet_link_tag(*files) }
end
<!-- people/new.html.erb -->
<% javascript 'dynamic_states' %>
...
<p>
  <label for="person_country_id">Country:</label>
  <%= f.collection_select :country_id, Country.find(:all), :id, :name, :prompt => "Select a Country" %>
</p>
<p id="state_field">
  <label for="person_state_id">State or Province:</label>
  <%= f.collection_select :state_id, State.find(:all), :id, :name, :prompt => "Select a State" %>
</p>
// javascripts/dynamic_states.js.erb
var states = new Array();
<% for state in @states -%>
  states.push(new Array(<%= state.country_id %>, '<%=h state.name %>', <%= state.id %>));
<% end -%>

function countrySelected() {
  country_id = $('person_country_id').getValue();
  options = $('person_state_id').options;
  options.length = 1;
  states.each(function(state) {
    if (state[0] == country_id) {
      options[options.length] = new Option(state[1], state[2]);
    }
  });
  if (options.length == 1) {
    $('state_field').hide();
  } else {
    $('state_field').show();
  }
}

document.observe('dom:loaded', function() {
  countrySelected();
  $('person_country_id').observe('change', countrySelected);
});

Note
I changed the above javascript slightly to call the countrySelected() function upon dom:loaded instead of hiding the states menu. This way if a country is already selected the states will reflect this.

RSS Feed for Episode Comments 159 comments

1. Philipp Jan 14, 2008 at 00:53

hey! first comment comes from germany. great episode, ryan! every monday 9:00 in the morning, it's time to watch railscasts! philipp


2. Dr Nic Jan 14, 2008 at 02:10

The <code>content_for(:head)</code> is very sweet!


3. Matt Darby Jan 14, 2008 at 03:09

I was just going to figure out how to do this today! Thanks for saving me time and effort once again!!


4. Chris McCauley Jan 14, 2008 at 03:30

Wow, some very great tips on using Javascript in Rails. How about an episode on the efficient use of Javascript e.g. compression or caching of large libraries such as prototype?

Thanks!

Chris


5. pnowak Jan 14, 2008 at 04:04

Railscast is like Knoppers, every morning at 9:30 in Poland :)


6. clouder Jan 14, 2008 at 05:21

Very cool, I'm making a site right now and I was using rjs, but got stuck at the how do I observe at load (my js skills are very poor). Now I get the onload update and faster updates :D However I am doing this on Rails 1.2.3, so there are a few differences. I had to name my view dynamic_states.rhtml, but I still put the :controller/:aciton.:format route, and it works just fine. I also had to get prototype 1.6.0 because I was getting a javascript error that there was no document.observe function. I also recommend getting the latest scriptaculous because without it I was getting a javascript recursion error on another part of my site. Now I just cross my fingers and hope that the new javascript libs and old Rails play nice together for the duration of the site being built :D


7. clouder Jan 14, 2008 at 07:06

oops, I forgot to mention that I also had to put render :layout => false inside the dynamic_states controller so that I don't get all my html headers in what's supposed to be a javascript file


8. strider Jan 14, 2008 at 07:20

hey, u guys are doing a great job. i happened to come to ur site from www.techscreencast.com. They have a section full of videos on ror... some of the videos are from here... just wanted to say my thanks for ur efforts...


9. Dean Holdren Jan 14, 2008 at 07:50

haha. I JUST implemented this a couple days ago (non-AJAX cascading selects). I'll have to revisit my code now that you've got this up. thanks for all the great screencasts


10. Brian Beers Jan 14, 2008 at 08:16

Ryan - thanks a lot for doing this episode. It's been hard to find a solid tutorial on dynamic select menus.


11. Carl Jan 14, 2008 at 17:51

Why can't I see the video on my iphone? I only hear the audio. I'm subscribed to the ipod version.

Anyhow, keep up the good work, nice podcasts! I wish I could watch them at the gym, though ;-)


12. nicolash Jan 15, 2008 at 07:12

hey, i guess it would be easier (less js), more responsive (no dom-(re)generation), more accessible (optgroups do logic grouping), cleaner (no global vars in js) to just group the options and show or hide the group-of-options according to the selected country...
<select>
 <optgroup label="..." id="x">
  <option></option>
 </optgroup>

 <optgroup label="..." id="y">
  <option></option>
 </optgroup>

 <optgroup label="..." id="z">
  <option></option>
 </optgroup>
</select>
... but as always... thank you for your efforts


13. flaubert Jan 15, 2008 at 07:39

great job/idea!!

here in brazil, for example, we always use something like this with States and Cities, and we have over 5000 cities and 27 states. for this case, isn´t ajax the best solution ?? could u show us how??

congratulations for this screencast!!


14. Jonathan Bartlett Jan 16, 2008 at 06:57

If anyone is interested, I have a plugin called applicability that does something like this automatically. Mine, however, is for turning parts of a form on or off based on a select menu.

http://code.google.com/p/applicability/

Jon


15. Pascal Ehlert Jan 16, 2008 at 10:31

Thank you Ryan, that's one more neat screencast which came exactly when I needed it most.

Unfortunately there is at least one major issue:
What if you want to edit the stuff later? The child item won't be select, you have to choose again :(


16. Peter Marks Jan 21, 2008 at 15:57

Thanks for putting this up. Dynamic selects menus without buggy js plugins is exactly what I've been looking for. I'm having some trouble implementing though.

myhost/javascripts/dynamic_states.js renders normally. The script seems to load in the 'new' action given the html source of my view, though I noticed your helper method doesn't spit errors when given non-existent javascripts. The select id tags in dynamic_states line up with the ones in my the view. Still no action upon selecting country though. Any idea what I might be missing? I assume this works with remote_form_for?


17. David Lowry Jan 23, 2008 at 06:51

Similar to Peter I'm having a few problems implementing this.

With implementation identical to yours navigating to
http://0.0.0.0:3000/javascripts/dynamic_show_requirements.js
renders:
"Missing template ....requirements.rhtml"
(nb. filename is "...requirements.js.erb")

Any quick tips as to how to get this moving?
Rails v 2.0.2 and Ruby v1.8.6

Thanks for the podcast! :)


18. David Lowry Jan 23, 2008 at 08:30

Scrap that - folks make sure you've got rails (including environment.rb) updated to latest and got your javascripts (as mentioned above updated to latest) using the command:
rake rails:update:javascripts

Thanks Ryan!


19. Jordan Isip Jan 24, 2008 at 10:28

This episode was great! Thanks!


20. Peter Marks Jan 25, 2008 at 10:56

Taking out "countrySelected();" in the amended javascript makes this work for my app on rails 2.0.2.

I would like to filter the states list by the pre-selected country though. What might I be missing?


21. Junrey Beduya Jan 28, 2008 at 03:18

After having been working on something like this episode, rails seems unable to render my javascript and I need to update my routes and add the following line:

<code> map.connect ':controller/:action.:format'</code>

Great article though...


22. Junrey Beduya Jan 28, 2008 at 03:25

Sorry, it's not a great article but a great rails screencast. :)


23. Brian Jan 29, 2008 at 06:34

Just as a note, all javascripts should be included at the bottom of the page right before the body close tag. It's better performance wise.


24. Oskar Jan 29, 2008 at 09:52

Thanks for this episode

What's the use of "*files" in the helper method, looks like some kind of dereferenced pointer to me - I'm certainly not a ruby guru ;-)


25. Tom Jan 31, 2008 at 05:03

Ryan. I have followed the tutorial to the letter and i still can't get it to work. When i look at the javascript file /javascripts/dynamic/states.js i get the same as you do. However when i load a page the dynamicness just doesn't work... any ideas?


26. Andreas and Björn Feb 05, 2008 at 10:19

Hi Ryan,
thanks for your wonderful series. We had some trouble with your javascript. If there is only one state in a selected country, your script displayed that state twice. To fix that we changed "options.length = 1;" to "options.length = 0;" and also the if clause to "if(options.length == 0)"


27. Sigfrid Feb 08, 2008 at 17:17

Hello Ryan,
great tutorial, exactly what I was looking for.

Thanks for this and all your terrific podcasts


28. Brian Feb 15, 2008 at 13:54

Is it possible to implement the same logic using 3 dynamic menus?


29. stephen Feb 25, 2008 at 12:43

Hey Ryan,

Great tutorial. However, if a validation error occurs on one of the fields on the same page and the page is re-rendered with an error message the state drop down gets messed up. The prompt message is no longer there and the first state in the DB is there instead. Any ideas....?


30. Vysogot Mar 05, 2008 at 00:34

How can it work with your 3-part complex forms casts?
When you add new task and each task on page will have those related dropdown how you refer to them?
When you add new task the div that you create in "simplify_views_for_rails_2.0" has id="new_task".
Each has id="new_task" and it is mark-up error.
Can you figure that out, cause that will be helpful!:)
ps. great railscasts! continue!


31. Vysogot Mar 05, 2008 at 02:29

Ok I've solved it.
You got to modify your js.erb file, so it won't observe since you can't get the elements with the same ID from the js file.
So in partial with countries and states do:
f.collection_select(:country, Country.find(:all), :id, :name, {:include_blank => true }, :onchange => "collectionSelected(this);")

And your js.erb will look like:

// array generation

function collectionSelected(e) {
  country_id = e.getValue();
  options = e.next(1).options;
  options.length = 1;
  states.each(function(model) {
    if (state[0] == country_id) {
      options[options.length] = new Option(state[1], state[2]);
    }
  });
}

and thats it :)


32. BillBris Mar 13, 2008 at 10:36

Interesting, as usual.

I would love to see this same problem solved using Ajax. I am doing the exact same thing you show here (country -> states), however, I've put together a couple of lookup tables (using the United Nations website) that has every country, and all the "states" for each and every country.

This "state" list contains about 3500 records and I just don't think that I want to use javascript for that every single time.

So, I humbly ask if you would do the same Railscast to show the Ajax method as an alternative.

Thanks!
B.


33. Designer Mar 18, 2008 at 03:41

Ryan, you just saved me a few hours of blood, sweat and tears! Thank you very much!


34. Captain Zhan Mar 21, 2008 at 13:05

Thanks first.
I've managed to make this work, but had two problems.
First, a non-related state option will display for every country, this is solved by modifying the first options.length = 1; to options.length = 0;
The other problem: On edit page, which also is using these codes, I find the saved state information is lost. The selector's default value fixs to the first option available for the country. I have no idea to fix this.

FireBug reports:

document.observe is not a function
[Break on this error] document.observe('dom:loaded', function() {


35. Thinkcast Mar 25, 2008 at 15:26

@Captain Zhan

check you have included <%= javascript_include_tag 'prototype' %> in your layout used in the edit page otherwise you need to check your $('person_country_id').observe('change', countrySelected); and ensure that person_country_id is the correct id in your edit view.


36. Jacques Mar 29, 2008 at 10:02

Thanks for the great podcast. I am still very new at programming in Rails, so please forgive this comment if it's already obvious to everyone else.
I was using Prototype Javascript 1.5.0 as part of RailsI so I too was getting the "document.observe is not a function" error message. I decided to upgrade to "RailsII" which includes Prototype 1.6.0.
But the error persisted, until I noticed that the "public/javascripts" folder in my application code tree that I had copied over from RailsI included the older versions of the Prototype library.
Just copying the newer Prototype library into the "public/javascripts" folder seemed to do the trick.
Hope this is helpful.


37. Alan Harper Apr 07, 2008 at 17:40

Internet Explorer needs var added to new variables to avoid the 'Object or method not found'

// javascripts/dynamic_states.js.erb
var states = new Array();
<% for state in @states -%>
  states.push(new Array(<%= state.country_id %>, '<%=h state.name %>', <%= state.id %>));
<% end -%>

function countrySelected() {
  var country_id = $('person_country_id').getValue();
  var options = $('person_state_id').options;
  options.length = 1;
  states.each(function(state) {
    if (state[0] == country_id) {
      options[options.length] = new Option(state[1], state[2]);
    }
  });
  if (options.length == 1) {
    $('state_field').hide();
  } else {
    $('state_field').show();
  }
}

document.observe('dom:loaded', function() {
  countrySelected();
  $('person_country_id').observe('change', countrySelected);
});


38. Sara Apr 18, 2008 at 21:19

Is it me, or is there a lot of stuff missing if you don't follow these tutorials in order?

I tried following along with this one (Dynamic Select Menus) and all of a sudden kept running into things that were not mentioned in the video: for example, creating the "new" action, creating the Countries and States tables in the db, modifying the routes.rb file (OK, that one was mentioned, just late in the video), etc.

It's impossible to follow along when you don't have the groundwork covered, and now I don't know where the info is that I missed.


39. Martin Apr 22, 2008 at 14:17

por favor me dicen cuales serian las rutas routes.rb

me genera el siguiente error:
ActionController::RoutingError (No route matches "/javascripts/dynamic_states.js" with {:method=>:get}):


40. william Apr 22, 2008 at 14:37

gracias. es posible ajustarlos para dos combobox mas?

saludos


41. joahking Apr 23, 2008 at 10:17

hi,
great work.

I have give you approach a try and it works pretty fine.

One thing though is that this way you end up with a two round call to rails to fulfill the request, one call to the people_controller and another to the javascripts_controller, with the repeating of bussiness processing if the thing get too complex.

If you want to try another approach this one looks fine:
http://railsenvy.com/2008/1/3/unobtrusive-javascript

keep on the good work


42. joahking Apr 23, 2008 at 10:23

oops sorry (I've made a two round posting here :-> )

@martin:
las rutas por defecto de rails funcionan, fijate si no las has eliminado en alguna refactorizacion REST, sino hay otro screencast sobre custom_routes en REST

that's it


43. joahking Apr 24, 2008 at 05:05

sorry about posting in spanish, but:
en este
<a href="http://qvitta.net/articles/2008/04/24/javascript-no-obstrusivo-o-cuando-ajax-es-un-problema">post comento un poco los problemas de ajax, este enfoque y demas</a> en español! si os lo quereis mirar.


44. Lee Apr 24, 2008 at 16:09

Great stuff Ryan!

I have a question though (for anyone).

What if I want to record the country name and state name in the person model (rather than their id?) But I still want to record country_id in the state model. Can anyone point me in the right direction?


45. Dave Apr 26, 2008 at 12:12

I love these tips! It would be very nice if you could package the files for examination. I'm having trouble understanding were your view code includes the state field.


46. Dave Apr 27, 2008 at 12:02

I made some progress and discovered that my problem is trying to use this technique with a DIV that gets updated with RJS. I can't seem to get the javascript to be interpreted unless I put it on the main page, but then the observed fields are not available.

Any ideas on how to use this technique for partials that come and go with RJS/Ajax?


47. caius Apr 27, 2008 at 20:42

Thanks a million mate. Beautiful code as always. Took me a minute in to realize I needed rails 2 to get .js.erb templates working (Doh!).

Cheers
C


48. Becca May 05, 2008 at 16:55

Is it possible to use this same concept to build a list to use with Drag and Drop? I'd like to load the lists and display only those states related to the country, but instead of a select list, the user is dragging and dropping values to create a list of items.

If so, any ideas on how to modify the function countrySelected to create my list elements?

THANKS!


49. chawei May 21, 2008 at 14:12

I am using the Rails 1.2.3, and follow the instruction that clouder said. But it looks like I still miss the dynamic_states.js, even I have correct output in http://localhost:3000/javascripts/dynamic_states. Could someone give any suggestion? Thanks!


50. pimpmaster May 22, 2008 at 08:36

FYI: I had problems in Rails 2.0.2 until I added this line to that dynamic states action

respond_to do |format|
  format.js
end

I also had to add this to routes.rb:

map.js ':controller/:action.:format'

And now everything works

Hope it helps someone :)


51. Friseur May 24, 2008 at 13:07

Extremely useful, thanks! This just saved me a couple of hours of searching the net. Thanks, Ryan!


52. Sh May 27, 2008 at 20:57

I have tried everything in the tutorial and the comments including May 22 08 comment by "pi_p master" for respond_to do format etc. and here is my predicament; my application works on my development machine just fine; when I transport it to my production environment it does not call the javascripts controller; I have the following error : <script type="text/javascript" src="/javascripts/dynamic_units.js">
1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2<html><head>
3<title>404 Not Found</title>
4</head><body>
5<h1>Not Found</h1>
6<p>The requested URL /javascripts/dynamic_units.js was not found on this server.</p>
7</body></html>

Now I have even tried putting in explicitly map.connect ':controller/:action.:format'

as well as :

  map.js '/javascripts/dynamic_units.js' , :controller=>'javascripts', :action =>'dynamic_units'

and whatever permutation I could fathom but to no avail. Help please.


53. Harry J Jun 06, 2008 at 11:04

I am having the same exact problem as Captain Zhan. This script totally borks out on the edit action. It forgets the state I selected even though I see it clearly saved in the database.

All of my javascripts are definitely included and the script still works - if I change the country, the state list changes, but the initial load is screwed up and automatically selects the first state in the list, instead of the state saved in the DB.

As a temporary solution, I simply do not load the script i current action is edit, but thats not too cool of a fix.

Anyone else deal with this?

Where is Ryan???? *shines Bat Signal*


54. Harry J Jun 06, 2008 at 11:51

For those of you pulling your hair out with this complicated solution, there is an excellent pluin that handles all this fun stuff in just a few lines of helper code.

"Check it out!":http://dvisionfactory.googlecode.com/svn/rails/plugins/related_select_forms/

It also works well on edit!


55. Luiz Arão A. Carvalho Jun 12, 2008 at 07:29

Tanks for this screencast!


56. Dovadi Jun 13, 2008 at 01:20

@Harry J The plugin you mentioned works great!

Having said that, I also think the screencast is excellent, because it is all about learning and seeing new or 'unknown' techniques.


57. Foncho Jun 20, 2008 at 11:36

Hola tengo un problema con este tutorial. Hice exactamente cada paso pero aplicado a mi proyecto y me sale el siguiente error.

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

Extracted source (around line #2):

1: var versions = new Array();
2: <% for producto in @productos -%>
3: versions.push(new Array(<%= version.producto_id %>, '<%=h version.verprod %>', <%= version.id %>));
4: <% end -%>
5:


58. Adam Teale Jul 09, 2008 at 23:15

hey guys,

I am trying to do this with a has_many :through relationship.

job, division, job_division

i am unsure whether to use the job_division 'join' table as the model in the js.erb file

Any ideas?


59. mellifluidic Jul 23, 2008 at 20:20

Hi, I'm trying to get this up and running in a scenario in which a person has a state and a state has a country, but a person doesn't have a country except through the state. In this case, the collection_select for country won't work. I'm trying to use a combined call to select_tag and options_from_collection_select to give me just the tags, but I haven't been able to get it to work yet.

I've also taken pimpmaster's suggestion about formatting, and should also mention that as with Vysogot, I'm trying to do this with something structurally similar to the projects/tasks application which is explored in the three part complex forms series. I haven't gotten too deep into trying Vysogot's solution for this to see if that get's things working, but I figured I would see if anyone could could me a quick suggestion on approach - I'll post more when I figure out more.

Cheers


60. Peer Allan Jul 24, 2008 at 12:35

In relation to the edit form not remembering the child. I got around it by added another onload observer to set the value.

<script>
document.observe('dom:loaded', function() {
  $('person_state_id').value = <%= @person.state_id %>;
});
</script>

Not the most elegant, but it works! Good Luck!


61. mellifluidic Jul 25, 2008 at 14:48

I was able to successfully implement this with the 3-part complex forms application. Vysogot's solution worked, but I had to make a couple of further modifications. Here is the code from my _task partial

...
<label for="task_country_id">Country:</label>
<%= task_form.collection_select :country_id, Country.find(:all), :id, :name, {:prompt => "Select a Country"}, {:onchange => "collectionSelected(this);"} %>

<label for="task_state_id">State or Province:</label>
<%= task_form.collection_select :state_id, State.find(:all), :id, :name, :prompt => "Select a State" %>
  </p>
...

Here's what I changed:
-I had to call :country_id (not :country) in the collection_select
-I put the collection_selects in the the same <p> element so that the call to .next() works properly.
-I put the :onchange call in {} brackets
-'model' in the def of collectionSelected() should have been 'state'

I think that that's it for the complex forms application. I'm still not sure how to get this to work with my application, since as I mentioned I can't use collection_select, as what will effectively be the person in my application has a state, but a country only through a state. I'll keep working on it, but if anyone knows what to use instead of a collection_select I would appreciate a comment on it.

Oh, and thanks to Ryan and everyone else who helps everyone out here - Awesome!


62. mellifluidic Jul 26, 2008 at 15:57

Alright, so I got it to work using options_from_from_collection_for_select to get the options and then feeding them into a select_tag method. It works, but a) it seems like there is a prettier way to do it and b) I'm not sure how to specify a prompt. I've tried putting :prompt => "Select a such and Such" both at the end of the select_tag call and the options_ from_col.. call, and neither works. If anyone has solutions to these minor queries, answers would be welcome and appreciated.

Thanks again!


63. Leandro Jul 28, 2008 at 09:25

I'm having some trouble with the edit using this method.
For example:
When I go to the edit, and i have several countries associated to it's continents, it keeps the value selected (for example China for the Asian continent). When I change the continent in the parent select it replaces all the select but not the prompted edit value (in this case China).
The question is, how can I replace that first value in the edit view?

nice screencast! thanks!


64. Lohberger Aug 20, 2008 at 07:23

Just as a note, all javascripts should be included at the bottom of the page right before the body close tag. It's better performance wise.


65. Voyance Aug 25, 2008 at 02:51

It's very interesting


66. Werbeagentur Graz Aug 25, 2008 at 06:34

I am using the Rails 1.2.3, and follow the instruction that clouder said. But it looks like I still miss the dynamic_states.js, even I have correct output in http://localhost:3000/javascripts/dynamic_states. Could someone give any suggestion? Thanks!


67. Johnny Sep 02, 2008 at 07:50

@Werbeagentur,

Try http://localhost:3000/javascripts/dynamic_states.js


68. Johnny Sep 02, 2008 at 07:53

@Werbeagentur,

Sorry! I misunderstood your question! I had the same problem actually. What does your HTML look like for your "states" in your form?


69. best acne treatment Sep 03, 2008 at 11:38

Tanks for this screencast!


70. Honda Civic Parts Sep 21, 2008 at 07:27

Great work there..


71. Matt Sep 21, 2008 at 18:35

I get this error. I'm using rails 2.1

No route matches "/javascripts/dynamics_states.js" with {:method=>:get}


72. Herbalife Sep 22, 2008 at 11:14

@ Matt it doesn´t work with 2.1 ! I have already tried it!


73. Stephen Tudor Sep 23, 2008 at 13:39

[@Matt, @Herbalife] It does work with 2.1. There's a route you have to set - see http://gist.github.com/12391


74. Befreiphone Reloaded Sep 27, 2008 at 14:13

Sorry! I misunderstood your question! I had the same problem actually. What does your HTML look like for your "states" in your form?


75. Potenzmittel Oct 03, 2008 at 03:20

@ Johny: many thanks!


76. Aloe Vera Oct 04, 2008 at 02:54

Very complicated but I´ll try it!
Thank you.


77. voyance Oct 06, 2008 at 13:17

Merci pour ces infos. Apres tout il n'y a pas que la voyance dans la vie!


78. LR Kosmetik Oct 17, 2008 at 11:03

Not to easy. But if you read carefully it works


79. Samir Jajjawi Oct 21, 2008 at 14:45

Very interesting write up. But its difficult to understand!


80. genf20 hgh Oct 21, 2008 at 22:08

thanks for the awesome script.. i'm just wondering which one is better compare to using ajax..


81. SEO Beratung Oct 26, 2008 at 06:28

Seems a little complicated first, but when reading it carefully, it works...


82. tercüme Nov 08, 2008 at 06:36

Extremely useful, thanks! This just saved me a couple of hours of searching the net. Thanks
Tercüme hizmetleri


83. çeviri Nov 08, 2008 at 06:37

This episode was great! Thanks!
Çeviri bürosu yeminli çeviri


84. ingilizce tercüme Nov 08, 2008 at 06:40

This episode was great! Thanks.
ingilizce tercüme


85. Guy Collins Nov 16, 2008 at 20:41

Thank you! You just saved me a bunch of time figuring out how to put this menu into my template.


86. Joaquin Nov 17, 2008 at 08:07

Very nice post! Thanks for sharing you make programer's live easier


87. Albert Nov 19, 2008 at 11:45

Very interesting write up.


88. Pipus Nov 19, 2008 at 11:49

Good very good!!


89. Werbegeschenk Nov 20, 2008 at 10:54

Great tutorial but not easy to understand. Thanks a lot for our help.


90. Craig Nov 22, 2008 at 09:23

This broke for me when upgrading to 2.2.2

The content_for capture in application_helper.rb doesn't fail, but it also doesn't insert the stylesheet/javascript into the template.

Any ideas?


91. Matratze Nov 24, 2008 at 04:22

This description really helped me a lot. Thanks. ;)


92. DSL Anbieter Nov 26, 2008 at 00:42

Very helpful screencast, thanks!


93. Gayrimenkul degerleme Nov 26, 2008 at 01:30

Thanks Ryan,I think this is one of the most wonderful sites. I have great admiration for you.Gayrimenkul degerleme ekspertiz


94. Emlak kiralık Nov 26, 2008 at 01:34

This broke for me when upgrading to 4 5 kiralık satılık emlak gayrimenkul


95. Dornbracht Armaturen Nov 26, 2008 at 06:22

This episode helped me a lot. Thanks for sharing this infos with us. ;-)


96. Colostrum Dec 03, 2008 at 03:59

You really helped me out with this. Thank you very much!


97. Rezepte für Diabetiker Dec 03, 2008 at 07:58

I searched for dynamic menus in Ruby and your article helps me a lot... Thanks for posting it. Great help!


98. rhodri Dec 03, 2008 at 20:03

can this be used in os commerce?


99. Types of microscopes Dec 05, 2008 at 17:00

I should try those codes, thanks


100. sleep creep Dec 07, 2008 at 06:41

tons of free sleepcreep.com videos for free at http://www.sleepcreep1.com


101. Wellnesshotel Dec 07, 2008 at 14:31

Why can't I see the video on my iphone? I only hear the audio. I'm subscribed to the ipod version.
Greets Wellnesshotel


102. Holz-Export Dec 07, 2008 at 14:32

Great job and good idea !
Congratulations for this screencast !! Best Regards Holz-Export


103. Christ's Church Dec 10, 2008 at 12:00

The first time I tried this I was using Rails 1.2.3 so I skipped the js.erb file and implemented the javascript directly in the html page.
  
Now I'm working on another project using Rails 2.2.2 and was able to implement the way you show. It works great.

Thanks to Peer Allan for sharing how he fixed the edit form issue.


104. gaveeno Dec 11, 2008 at 14:20

Any ideas why I'm getting "Missing layout layouts/application.erb in view path /myapp/app/views"?

For some reason when rendering the .js template my app is trying to use the wrong (non-existant) layout mentioned above.


105. Patrick Berkeley Dec 17, 2008 at 01:26

It's probably better to use double quotes around the state name in the js file since a state name might contain a single quote. Ex. "Provence-Alpes-Cote d'Azur"

In dynamic_states.js change '<%=h state.name %>' to "<%=h state.name %>"


106. Alargamiento Pene Dec 18, 2008 at 09:09

Nice post :D


107. itkin Jan 05, 2009 at 06:16

Any Idea how to include javascript file from a partial loaded via rjs ?

Thanks !


108. itkin Jan 08, 2009 at 01:09

To answer my question post 131, couldn't find a way to execute javascript_include_tag in a partial loaded through .rjs.

I used javascript_tag straight in the view to refresh js global variable.


109. Patrick Berkeley Jan 09, 2009 at 16:13

The suggested code doesn't select the state from the drop-down if it's already selected for me. Not sure what I'm doing differently from the suggested code.

Adding an if statement and a few parameters to the 'new Option(name, id, false, true)' are what worked: http://gist.github.com/45324


110. jerik Jan 24, 2009 at 09:13

I aggree. Amazing and helpful. Love Rails ;)


111. Nellboy Jan 30, 2009 at 06:33

@Stephen Tudor

thanks for the tip in post 78, helped me get this working in Rails2.2.2... great tutorial btw... spot on!!

"[@Matt, @Herbalife] It does work with 2.1. There's a route you have to set - see http://gist.github.com/12391"


112. Deger Feb 22, 2009 at 00:21

Thanks! I have successfully used the feature (including cache in next episode) for a model.
I have a problem to reuse this js for many models. Because we specify the model name 'person' in RJS like 'person_country_id', the f.select and f.collection_select always automatically set the ID for us. I want to get rid of the "person_" part. But
How to get rid of the "person_" part by manually specify the DOM ID in
f.select or f.collection_select

Hope I make myself understood.


113. Michae; Feb 26, 2009 at 06:29

I'm still not able to get this to work in 2.2.2. I have added the following to my router per #78
map.js ':controller/:action.:format'

I am using this with a partial and so am not sure if this is affecting anything.

Could anyon who has got this working in 2.2.2 share the code?

cheers
Michael


114. Daniel James Mar 02, 2009 at 15:43

Awesome thanks for the tutorial and everyone's comments for the help. Just to let everyone else know to get this to work in the edit view I had to do the following additions:
 
comment #26. Andreas and Björn

and
 
comment #61. Peer Allan (this code goes in the edit view and for some reason for me I couldn't use a partial for the form...)

Hope this helps anyone. thanks again Ryan!!


115. Daniel James Mar 12, 2009 at 15:05

So i got it working and all, and I am using it to let users select a State, County, and then city.

Now there are 26,000 cities in the US, and it loads them all in the browser and it goes really really slow.

Does anyone know how to make it so it only loads the counties that are related to the state and cities that are related to that county...? instead of loading all the options in DOM in the browser.


116. Toby Mar 31, 2009 at 08:55

Thanks for the good information, great site!


117. Marco Apr 01, 2009 at 06:36

Thanks for posting it's beeen a great help


118. Tony Apr 06, 2009 at 12:06

I don't care that I am the 160th person to say some variation of this...you are awesome! Just saved me hours, and got some new rails code architecture tips


119. justin Apr 16, 2009 at 17:44

In response to Stephen's (29.) issue with error messages messing up the second select, I used Peer's solution (61.) placed in the view template, along with a line to update that first option in the select so it didn't show the first option in the list: http://gist.github.com/96784


120. Jack Zelig Apr 24, 2009 at 12:19

@pimpmaster (no. 51),
Thanks ever so much for taking the time to post your solution here. I was tearing my hair out as this wouldn't work until I read your suggestion (adding map.js ':controller/:action.:format' to routes.rb).
Cheers buddy.


121. Notebook Handy Apr 25, 2009 at 12:41

Hi, can I implemente the "plugin" in a drupal system? If yes in whitch file?


122. michael sommer Apr 30, 2009 at 05:03

Thanks for posting. Great Work.


123. Joey May 07, 2009 at 14:36

I think that the use of "*files" in the helper method, looks like some kind of dereferenced pointer , but is a kind of understandig. God work - thx!

JOEY


124. niber May 21, 2009 at 05:33

Could it be possible to send parameters to the javascript functions ?


125. Qaiser May 27, 2009 at 00:26

Nice RailsCast. I just have a quick question, what if i want to use the same fields in multiple forms, how will i achieve that?


126. Valery Jun 02, 2009 at 05:45

This one is for jQuery

<script src="http://gist.github.com/122221.js"></script>


127. Don Jun 30, 2009 at 12:23

Is there anyway to get this to work with ajax, because i need to load 4000 cities. I have searched every where and found nothing. Please Help


128. Dessous Jul 02, 2009 at 00:08

Your screencast for dynamic select menus helped me. Thx for sharing it!


129. omin Jul 02, 2009 at 00:39

I am really looking for a JQuery solution for this as the current code as is, is not working properly.

I do not know JQuery much so any help in fixing this will be helpful.


130. Enregy Infos Jul 06, 2009 at 09:04

Thanks for Posting . Fine Job


131. Quee Jul 10, 2009 at 19:42

an issue i came across is when using nginx as a front for live server. nginx conf file is set to redirect all the /javascripts/ request to the public/javascripts folder.

this means the call to the dynamic files will never return the correct file.

What can we do in this case?


132. estetik Jul 20, 2009 at 03:52

thank you very nice plugin


133. tatil Jul 27, 2009 at 01:12

thnak you very best in formation


134. LR Jul 28, 2009 at 10:23

Internet Explorer needs var added to new variables to avoid the 'Object or method not found'

// javascripts/dynamic_states.js.erb
var states = new Array();
<% for state in @states -%>
  states.push(new Array(<%= state.country_id %>, '<%=h state.name %>', <%= state.id %>));
<% end -%>

function countrySelected() {
  var country_id = $('person_country_id').getValue();
  var options = $('person_state_id').options;
  options.length = 1;
  states.each(function(state) {
    if (state[0] == country_id) {
      options[options.length] = new Option(state[1], state[2]);
    }
  });
  if (options.length == 1) {
    $('state_field').hide();
  } else {
    $('state_field').show();
  }
}

document.observe('dom:loaded', function() {
  countrySelected();
  $('person_country_id').observe('change', countrySelected);
});

I tried it and now it works fine...


135. Michael Jul 30, 2009 at 09:46

I have this running fine. However, it seems that the javascript is either running before the controller has finished running, or the javascript is not able to use variables form the controller

Any thoughts on this one?

Michael


136. manuka honig Aug 14, 2009 at 02:14

railscuts is really good help for programmers
thanks a lot


137. kikito Aug 16, 2009 at 14:10

Hi everyone,

I've implemented a plugin called dependent_select on

http://github.com/splendeo/dependent_select/tree/master

The syntax is very similar to collection_select - you just add another method for "filtering".

<%= f.dependent_collection_select :state_id, State.find(:all), :id, :name, :country_id, :prompt => "Select a State" %>

This will generate all the needed javascript - with the exception of the main function, that should be included on the layout.

Note that the current implementation downloads everything at the begining on a big javascript array; if you are looking for an AJAX solution you'll have to look elsewhere - for now :) at least.

Regards!


138. Unify Industry Sep 05, 2009 at 09:33

code is very nice


139. Elias Farah Sep 25, 2009 at 17:09

não entendi


140. Free Samples By Mail Oct 05, 2009 at 12:28

Thanks for the java script code. Do you happen to know any code for HTML? I'm editing my blog right now and I prefer HTML than java. thanks


141. kablo Oct 06, 2009 at 05:23

thank you


142. Gordon Oct 07, 2009 at 02:54

hey Ryan

 there's been a lot of feedback here

1) care to respond to some of them at least?
2) a non-fully client side approach is to use Ajax. Could you please do a railscast on how to achieve the same effect using ajax?


143. Prem Oct 08, 2009 at 00:14

One thing is not clear to me. Is the action dynamic_states expected to be called manually everytime the contries/states get changed? If not, how does it get invoked? In the tutorial, Ryan invoked the method directly using the URL. If that is not done, is this still going to work?


144. dugun salonu Oct 22, 2009 at 12:54

thank. your article is succesful


145. Jorge Oct 22, 2009 at 13:50

thanks for this cast, Ryan, it made my day a few weeks ago.

How would you do this with Ajax, though?


146. fruehschwangerschaft Oct 26, 2009 at 05:27

very nice


147. tinnitus treatment Oct 29, 2009 at 06:34

Thanks for this tutorial. I've been looking for some time for a decent one on dynamic select menus. You'd be surprised how much trash info there is out there.

cheers


148. Strom Vergleich Nov 02, 2009 at 13:54

thx for this information and thanks for the work for this. the code works


149. cece Nov 03, 2009 at 02:54

great tutorial. thanks a lot mate.
took me a week to make this work but still a great code


150. trauringe Nov 03, 2009 at 10:14

thank you for the great help
the wedding rings are very nice
Thanks


151. wojtek Nov 12, 2009 at 14:53

Checkout my solution that neads no JavaScript code writing, and requires fever lines of code: http://programmers-blog.com/2009/11/12/dependant-dropdowns-select-menus-using-rails


152. cheminée éthanol Dec 02, 2009 at 14:38

nice job!


153. Silber kaufen Dec 15, 2009 at 01:38

thank you for the great help and greetings from me


154. Jeremy Dec 15, 2009 at 12:36

Very good article guys!


155. Darren Dec 23, 2009 at 17:04

Anyone have any experience doing dynamic selects menus with very large numbers of option data? I've tried just JS and Ajax and both options are very slow on the first change. My first select has about 700 options, the second over 5000.


156. lead Jan 10, 2010 at 12:49

Thanks for this tutorial. I've been looking for some time for a decent one on dynamic select menus. You'd be surprised how much trash info there is out there.<a href="http://oynetwork.com/">lead</a>


157. Suchmaschinenoptimierung Beratung Jan 22, 2010 at 07:59

This article was very helpful, thanks!


158. seo agentur köln Jan 22, 2010 at 17:52

thanks for help and greetings from cologne


159. Gold verkaufen Feb 02, 2010 at 14:44

i alo thanks for this article and some helpful informations...well done

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source