Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails Country/State Select Enigma

I am trying to implement something seemingly very simple, and I have been beating my head against it for days at this point.

My desired end result is a Country select drop-down, tied to a State select drop-down, in such a way that when a given country is selected, IF states are known THEN those states are displayed in a select drop down, and if NO states are known for that country, then a text field is displayed instead.

I feel like I am almost there. At this point the interface will actually generate that list of states based on the persons' country, except it is refusing to update the drop-down dynamically.

The portion of my view where country and state location is gathered looks like:

# _person_setup.html.erb
         <td>
        <%= f.label :country, 'Select your country' %>*<br />
        <%= f.select :country, Carmen::country_names, {}, 
          {:style => 'width: 200px', 
          :id => 'country_select',
          :onchange => remote_function(
            :url => {:action => 'update_states'},
            :with => "'country='+value")} %>            
      </td><td>
        <p>
        <div id="states_div">
            <%= render :partial => 'states', 
                :object => Carmen::states(
                            Carmen::country_code(
                              @person.country)),
                :locals => {:form => f} %>
       </div>
        </p>            
      </td>    

The partial being referenced in the DIV is as follows:

 # _states.html.erb
<% unless states.nil? or states.empty? %>
    <%= form.label :state, 'Select your state' %>*<br />
    <%= form.select :state, states.collect{|s| [s[0], s[0]]} %>
<% else %>
    <%= form.label :state, 'Please enter state or province' %>*<br />
    <%= form.text_field :state %>
<% end %>

Finally, the controller code which is intended to update the list of states dynamically:

def update_states    
puts "Attempting to update states..."    
q = params[:country]    
states = Carmen::states(Carmen::country_code(q))
puts "Country = #{q}, states = #{states.collect{|s| s[0]}.join(", ")}."
render :update do |page|
    page.replace_html "states_div", 
      :partial => 'states',
      :object => states,
      :locals => {:form => form_for(@person)}
end
puts "OK"
end

Now, this code is being called at the proper time and generating the appropriate lists of states. For example, when the user clicks Australia, "Attempting to update states... Country = Australia, states = Australian Capital Territory, New South Wales, Northern Territory, Queensland, South Australia, Tasmania, Victoria, Western Australia" shows up in the server process. However it doesn't update the page, and won't print the "OK" at the end. In short the line which is failing is undoubtedly

page.replace_html "states_div", 
      :partial => 'states',
      :object => states,
      :locals => {:form => form_for(@person)}

Note that replacing this line with

page.replace_html 'states_div', "<b>is it working</b>" 

properly replaces the div, but of course not with anything useful.

Can someone help me understand what is going on here?

like image 397
Joseph Weissman Avatar asked Jun 10 '09 15:06

Joseph Weissman


2 Answers

It looks like you're assuming that the @person variable is still available from your original action. This could be set up by a filter for the current person but you don't show that in your question.

If you do need to lookup the @person again you'll have to pass the id through in your remote_function I think.

like image 88
Shadwell Avatar answered Nov 15 '22 05:11

Shadwell


Ryan Bates has a Railscast that shows how to select a category for a product or create a new category by typing the name. It sounds like a similar scenario to what you have, so you might want to check it out: Create Model Through Text Field.

like image 25
John Topley Avatar answered Nov 15 '22 06:11

John Topley