Topic: Best way to client-side load or hide state/province drop down?

Hi folks. First post, with hopefully a rudimentary answer. Maybe I'm just trying too hard, because I have done this plenty of times with plain old javascript before Rails entered my life. But now that I'm trying to work within the Rails form_for system, I am finding that what should be a simple task has become arduous beyond compare. I'm ready to tear out what little hair I have left, and I have yet to find anything online that addresses what I thought
would be a common scenario.

So, the scenario:
A user create/edit page. When a user selects US or Canada, the state/province drop down loads accordingly. If he selects a different country, the dropdown disappears. When the form is submitted, the user and his address are saved accordingly.

User model: has_one :address
Address model: has_one :state, has_one :country
State and Country are models with database values.

edit.rhtml:
--------------
<% form_for :user, :url => {:action => "update", :id => @user} do |f| %>
        <%= render :partial => "user_form", :locals => {:f => f} %>
<% end %>

_user_form.rhtml:
--------------
First name: <%= f.text_field :first_name %><br />
Last name: <%= f.text_field :first_name %><br />
<% fields_for :address do |a| %><br />
   City: <%= a.text_field :city %><br />
   Country: <%= a.select :country_id, COUNTRIES %><br />
   State: <%= a.select :state_id, STATES %><br />
<% end %>

At first, I tried putting the state selector and text in its own partial, thinking that via a custom onchange event on the country selector and by using RJS I would be able to reload the state selector from a controller method or hide it altogether. But in practice it can't be done because the state selector needs a form reference and the controller can't pass that in. It got ugly real fast.

So where I stand now, I'm looking at writing a custom javascript method, fired from an onchange event on the country selector, that would reload the contents of the state selector. Have I missed some magical rails ingredient or helper that would make this better? Has it just been too long a day? Any help appreciated.

Re: Best way to client-side load or hide state/province drop down?

Addendum: I found a similar post on the forum where the author gave up on using a form_for select and used an html select instead. I have done the same thing, replacing the partial via ajax and all seems well for now, even if it does feel a bit hackish. Will post my solution when I'm not so frazzled.

Re: Best way to client-side load or hide state/province drop down?

Hello,

Can you help me with the client-side load on the state/province drop down.  I've been pulling my hair out on this and I can't seem to find the answer to what I would think is a simple question.

I have a similar problem where I want to create a dynamic drop-down for car's make and model.  I was wondering if you could provide me with your code snippets of your hack.  Currently, I'm using "form_for".

A

Re: Best way to client-side load or hide state/province drop down?

Ah, I was supposed to post my solution! Apologies. I'll post code snippets later today, once I've woken up. smile

Re: Best way to client-side load or hide state/province drop down?

Okay, let's see here...

Note, country_list is a helper method that returns a list of select-formatted countries from my DB. You can use a hard-coded list or whatever suits your fancy. has_regions is a helper method that determines if the specified country has any regions. This should all translate easily to any other parent-child relationship.

Controller:

def edit
  @address = user.address
  @country = (@address.blank? || @address.country_id.blank?) ? nil : user.address.country
end

def country_changed
  country = Country.find(params[:id])
  render :partial => "region", :locals => {:country => country}
end

def update
  #specific to your app
end


edit.rhtml:
<% remote_form_for :address, :url => {:action => "update", :id => @address} do |f| %>

<%= f.select :country_id, country_list,
  {:prompt => "Choose one..."},
  {:onChange => "new Ajax.Updater('regions',
   '/profile/country_changed/' + this[this.selectedIndex].value,
   {asynchronous:true, evalScripts:true});"} %>

<%= render :partial => "region", :locals => {:country => @country}%>

<% end %>


_region.rhtml
<% if has_regions(country) -%>
  <%= select "address", "region_id", region_list(country) %>
<% end -%>

That oughta do it!

Re: Best way to client-side load or hide state/province drop down?

I'm sorry, i'm just another newbie again...
you said that has_regions is a helper method bla bla bla, so we need to definitely create that method in application_helper aren't we?? thanks for your answer

Re: Best way to client-side load or hide state/province drop down?

That's right esarijal