In the view there is a regular Rails form and a javascript function that will be triggered when the country select field is changed. The javascript function will make an ajax request to the country_select url with the country code passed as the id variable, e.g., /country_code/us for the United States. I'm also using the Carmen plugin for this example which will provide a list of countries and their respective states/provinces. Not all countries are full supported. More information on Carmen can be found at http://autonomousmachine.com/2009/4/1/carmen-a-rails-plugin-for-geographic-names-and-abbreviations and http://github.com/jim/carmen
<%form_for(@model) do |f| %> <script type="text/javascript" charset="utf-8"> function change_state_select(state_code) { new Ajax.Request('/country_select/'+state_code, { method: 'get', onSuccess: function(transport) { $('state_select').replace(transport.responseText); } }); } </script> <%= f.select :country, Carmen::COUNTRIES, {}, { :onchange => "change_state_select(this.options[this.selectedIndex].value);" } %> <div id='state_select'></div>***Note the : onchange should really be one word but an emoticon shows up otherwise :onchange :(*** Since not all countries are supported I need to execute some conditional logic in the action country_select. If the country is supported I'll return a snippet of html containing a select field that my form will use. If the country is not supported I'll return a text field so that the user can write in their state/province.
class CountrySelectController < ApplicationController def country_selecet begin @states = Carmen::states(params[:id]) rescue @states = nil end render :partial => "country_select/states" end endIn the final partial that is rendered there is either a select field or a text field
<div id="state_select"> <% if @states.nil? %> <%= text_field_tag :model, :state %> <% else %> <%= select :model, :state, @states%> <% end %> </div>
Just finishing up brewing up some fresh ground comments...