If you want a solution that is more Rails-centric...
First, I created some helper methods just for convenience. (I only
needed the state_options one but created the others for testing this
solution). The xxx_options simply creates an acceptable collection
for populating a Rails select. The xxx_option_tags return a string of
option tags with the line breaks removed. That's necessary for their
inclusion in a js function below:
in application_helper.rb:
..
def state_options
Address::STATES.collect{|state| [state, state]}
end
def province_options
Address::PROVINCES.collect{|state| [state, state]}
end
def state_option_tags
options_for_select(state_options).gsub("\n", "")
end
def province_option_tags
options_for_select(province_options).gsub("\n", "")
end
...
I've got an address partial because I will capture addresses for all
kinds of different things (people, customers, businesses, etc). My
address partial just consists of a normal 'fields_for :address'.
Here's the part relevant to the discussion:
<%= f.select :state, state_options %>
<%= f.text_field :postal_code %>
<%= f.country_select :country, ['United States',
'Canada'], :selected=>'United States' %>
<%= observe_field :address_country,
:function=> "switch(value){ case 'United
States': $('address_state').show();$
('address_state').update('#{state_option_tags}'); break; case
'Canada': $('address_state').show();$
('address_state').update('#{province_option_tags}'); break; default: $
('address_state').hide();}" %>
Okay, so what's going on... I'm making use of the prototype library
packaged with Rails and the baked-in "observe_field" helper. This
helper observes the country select field and fires on a change (the
country select is rendered with US and Canada at the top before an
alphabetical listing of countries, and US is selected by default).
The :function=>... part is passing a js-function that will become the
method responsible for handling the change in the observe field. It
will be wrapped in a function block that looks like: function(object,
value) {}. That's where the 'value' field comes from. The rest of
the string is just a switch-statement that loads the appropriate
values into the select box or hides it all together.
The #{state_option_tag} is where the application_helper.rb comes into
play. That is evaluated at run time to give the select options you
need. The net effect is that the js swaps out the <option> tags in
the address_select field.