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
-~----------~----~----~----~------~----~------~--~---