Hey all, I''ve been trying for days, without much success to add a ''Select Location'' option to my site. I want to use observe_field so that a user can select a Country, and then another list is populated with the appropriate cities. This must be something that is needed all the time, but I just can''t seem to find a decent tutorial (i''m a pretty new programmer!) Here are my models... lu_countries id country lu_cities id city country_id Can anyone help me? Thanks guys! Ps. Happy Holidays from here in London :-) -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
This is exactly what I''ve been working on, but I just can''t seem to get my head around it either. Perhaps we could work it through on here and then put together a definitive tutorial? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi James, James Kelly wrote:> > I''ve been trying for days, without much success to add a ''Select Location'' > option to my site. I want to use observe_field so that a user > can select a Country, and then another list is populated with the > appropriate cities.> This must be something that is needed all the time, but I just can''t seem > to find a decent tutorial (i''m a pretty new programmer!)If you search the archives you''ll find numerous discussions of this over the last year. In general, the easiest way to accomplish this is to set the observe_field on your Country select so that it sends back the selected value using :with => whatever_you_want_the_param_to_be_named, then in the controller do a find on your Cities using the Country passed back in that param, then in your rjs template replace the content of the <div> containing your Cities select. hth, Bill --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Based on your example, try this: In your models (PS: I stripped the lu_ prefix on the class in my example so I explicitly reference the proper table based on your example): class Country < ActiveRecord::Base has_many :cities def self.table_name() "lu_countries" end end class City < ActiveRecord::Base belongs_to :country def self.table_name() "lu_cities" end end In your controller, somewhere appropriate, populate @countries: @countries = Country.find(:all) Also, add a new method to your controller to respond to the "observe_field" callback: def country_changed @cities = Country.find(params[:country_id]).cities render :partial => ''layouts/city_options'', :layout => false end In your view: <select name="country_id" id="country_id"> <%= render(:partial => ''layouts/country_options'', :layout => false) %> <%= observe_field "country_id", :url => {:controller => "YOUR_CONTROLLER", :action => "country_changed"}, :with => "country_id", :update => "city_id" %> </select> <select name="city_id" id="city_id"> </select> Create two partial views (I have them in the /layouts subdirectory): _country_options.rhtml <%= options_from_collection_for_select(@countries, :id, :country) %> _city_options.rhtml <%= options_from_collection_for_select(@cities, :id, :city) %> The way I have it currently setup, the cities drop down will only be populated when you select a country. But you could set the country to a default for the user, populate the @cities variable as I''m doing in the country_changed method, and then render the city_options partial in the view. -Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Paul Corcoran wrote:> Based on your example, try this: > > In your models (PS: I stripped the lu_ prefix on the class in my > example so I explicitly reference the proper table based on your > example): > > class Country < ActiveRecord::Base > has_many :cities > def self.table_name() "lu_countries" end > end > > class City < ActiveRecord::Base > belongs_to :country > def self.table_name() "lu_cities" end > end > > In your controller, somewhere appropriate, populate @countries: > > @countries = Country.find(:all) > > Also, add a new method to your controller to respond to the > "observe_field" callback: > > def country_changed > @cities = Country.find(params[:country_id]).cities > render :partial => ''layouts/city_options'', :layout => false > end > > In your view: > > <select name="country_id" id="country_id"> > <%= render(:partial => ''layouts/country_options'', :layout => > false) %> > <%= observe_field "country_id", > :url => {:controller => "YOUR_CONTROLLER", :action => > "country_changed"}, > :with => "country_id", > :update => "city_id" %> > </select> > <select name="city_id" id="city_id"> > </select> > > Create two partial views (I have them in the /layouts subdirectory): > > _country_options.rhtml > <%= options_from_collection_for_select(@countries, :id, :country) %> > > _city_options.rhtml > <%= options_from_collection_for_select(@cities, :id, :city) %> >Hey. Thanks for that. I tried it, but the second select list just won''t update. I assume i need to include.. <script src="/javascripts/prototype.js" type="text/javascript"></script> in my head? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Yes, absolutely. Hope it works for you... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Paul Corcoran wrote:> Yes, absolutely. Hope it works for you...Hoorah! That worked great! Is it possible to have the users country and city already selected when the form is loaded? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Yes. Go ahead and populate @countries as I showed you but also set some variable to the id of the user''s country like @user_country_id. Also, populate the @cities variable as well based on the users country like we were doing in the country_changed method. Then change _country_options.rhtml as follows: <%= options_from_collection_for_select(@countries, :id, :country, selected_value = @user_country_id) %> Or if you had a @user object that had the country_id you could code it as "selected_value = @user.country_id". The important thing is that it is the "id" of the country you need to specify in the selected_value parameter. Do something similar for the city. Also, in my first example I wasn''t populating the city drop down so you would need to do that in your view now as well: <select name="city_id" id="city_id"> <%= render(:partial => ''layouts/city_options'', :layout => false) %> </select> -Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hey Paul, Thanks for such a quick response! The "selected_value = @user_country_id" works great - when the page is loaded, the users country is selected! However, the city list remains blank, and I''m a little confused as to what you are saying with regards to populating that. Here is my code so far... ****ProfileController**** def edit user = session[:user_id] @profile = Profile.find(:first, :conditions => ["user_id = ?", user]) @countries = Country.find(:all) @user_country_id = @profile.country_id end def country_changed @cities = Country.find(params[:country_id]).cities end ****Partials**** _country_options.rhtml <%= options_from_collection_for_select(@countries, :id, :country, selected_value = @user_country_id) %> _city_options.rhtml <%= options_from_collection_for_select(@cities, :id, :city) %> ****View**** <select name="profile[country_id]" id="profile_country_id"> <%= render(:partial => ''country_options'', :layout => false) %> </select> <%= observe_field "profile_country_id", :url => {:controller => "profile", :action => "country_changed"}, :with => "country_id", :update => "profile_city_id" %> <select name="profile[city_id]" id="profile_city_id"> <%= render(:partial => ''city_options'', :layout => false) %> </select> The error message I get is.. You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occured while evaluating nil.inject Any ideas? Thanks again (really appreciate it!) -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Scott, To populate the cities list you need to add a line (2nd to the last line) to your "edit" method as follows: def edit user = session[:user_id] @profile = Profile.find(:first, :conditions => ["user_id = ?", user]) @countries = Country.find(:all) @user_country_id = @profile.country_id @cities = Country.find(@profile.country_id).cities @user_city_id = @profile.city_id end Additionally, if you wanted to select the users city, you would need to set a variable like @user_city_id (see last line) and add ", selected_value = @user_city_id" to the _city_options.rhtml partial like we did with the countries. -Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Fantastic! That all works now. Just what I wanted - Thank you! And for the others, here is my final code... This code is for an "update my profile" page which is part of the"profile" controller ****Head of page**** <%= javascript_include_tag "prototype" %> ****ProfileController**** def edit user = session[:user_id] @profile = Profile.find(:first, :conditions => ["user_id = ?",user]) @countries = Country.find(:all) @user_country_id = @profile.country_id @cities = Country.find(@profile.country_id).cities @user_city_id = @profile.city_id end def country_changed @cities = Country.find(params[:country_id]).cities render(:partial => ''city_options'', :layout => false) end ****Partials**** _country_options.rhtml <%= options_from_collection_for_select(@countries, :id, :country, selected_value = @user_country_id ) %> _city_options.rhtml <%= options_from_collection_for_select(@cities, :id, :city, selected_value = @user_city_id) %> ****View**** <p><label for="profile_country_id">Country</label><br/> <select name="profile[country_id]" id="profile_country_id" style="width: 200px"> <%= render(:partial => ''country_options'', :layout => false) %> </select> <%= observe_field "profile_country_id", :url => {:controller => "profile", :action => "country_changed"}, :with => "country_id", :update => "profile_city_id", :frequency => 0.25 %> <p><label for="profile_city_id">City</label><br/> <select name="profile[city_id]" id="profile_city_id" style="width: 200px"> <%= render(:partial => ''city_options'', :layout => false) %> </select> -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thats great! Now that I see your Profile class, there is one last thing you could do to simplify your code just a bit. Since you have the country_id and city_id available in the @profile variable, there really is no need to put them into the varaibles @user_country_id and @user_city_id. We can simply retrieve that data from the @profile variable when needed. So you could remove the following 2 lines from the "edit" method: @user_country_id = @profile.country_id @user_city_id = @profile.city_id And then replace @user_country_id with @profile.country_id in _country_options.rhtml and @user_city_id with @profile.city_id in _city_options.rhtml. -Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Paul Corcoran wrote:> Thats great! Now that I see your Profile class, there is one last thing > you could do to simplify your code just a bit. Since you have the > country_id and city_id available in the @profile variable, there really > is no need to put them into the varaibles @user_country_id and > @user_city_id. We can simply retrieve that data from the @profile > variable when needed. So you could remove the following 2 lines from > the "edit" method: > > @user_country_id = @profile.country_id > @user_city_id = @profile.city_id > > And then replace @user_country_id with @profile.country_id in > _country_options.rhtml and @user_city_id with @profile.city_id in > _city_options.rhtml. > > -PaulBugger! Even though it works fine on FF and Safari, I''ve just tested it on IE 7 and it doesn''t work :-( When the page loads, the second box is loaded with the correct city options, but when I change the country the city list goes blank. Any ideas? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
It fails for me in IE as well. What I had to do to get this to work was to wrap the <select> tag for city in a <div> and tell "observe_field" to update the div rather than the select. This means changing some stuff. First off, change your view from: <select name="profile[city_id]" id="profile_city_id" style="width: 200px"> <%= render(:partial => ''city_options'', :layout => false) %> </select> to: <div id="city_select_div"> <%= render(:partial => ''city_options'', :layout => false) %> </div> Then change the _city_options partial to: <select name="profile[city_id]" id="profile_city_id" style="width: 200px"> <%= options_from_collection_for_select(@cities, :id, :city, selected_value = @user_city_id) %> </select> And finally, change the update parameter of "observe_field" from :update => "profile_city_id" to :update => "city_select_div". That should take care of it. I am begining to come to the realization that ajax updates work better when the tag is wrapped in a div. Being a block level statement, I think it forces the browser to "work harder" when the DOM changes. I have yet to see someone make a blanket recommendation to this effect but I am starting to lean that way. -Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I''ve just got around to updating my code and it works a treat! Thanks!! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Just discovered this very useful thread and am curious (I''ll go try it in a bit but, when encountering problems, it''s always nice to know if it''s SUPPOSED to work... :) if these things can be daisy chained. That is, can I expect to be able to expand the above example to have kingdom -> phylum -> class -> order -> species (It''s just an example, please ignore the "old" hierarchy and discussion of The New Taxonomy! :) where each popup triggers a callback to the next, which is pre-filled with a default value (likely the 1st item on the list), so the last popup is adjusted according to changes in any of the ones above it? Will that work? Thanks! -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---