Contingent Select Boxes - 2 Q's

I have a form with contingent select boxes (the state is contingent on the country selected, so when the country selected changes, the state changes -- I am using the Carmen plugin for getting my state names and country names together, but not the functionality I am interested in achieving).

Everything works fine except I cannot figure out how to amend my code such that: A. When the form is first rendered the state select box is empty (even if there is a country showing, and the user (what I am calling an "Associate" in terms of the model) HAS a state selected in his model. - and- B.If I have, say, a state selected, I change the country, don't select a state for that country, then go back and select the original country (for which I have a state selected) it still doesn't display the selected state -- just the list of states, unselected, in the state select box (I believe the solution to #1, above, should solve this too).

Ive scoured the net for examples of related matters, but cannot find one similar to this. I am certain the solution must be little more than a few lines of code which I am entirely oblivious to. Can someone help me here? -JannaB

Here is the code I am using:

First, I have a model called Associates (for simplicity in demonstration here, the only two members of Associates are state and country, both Strings), and the /views/associates/_form.html.erb, as follows:

<% form_for @associate do |f| %>   <%= f.error_messages %> <p>      <%= f.label :city %><br />      <%= f.text_field :city %>   </p>   <p>     <%= f.label :state %><br />   <select id="state" name="state">     <option></option>   <%= render :partial => 'get_states' %>   </select>   </p> <p>      <%= f.label :country %><br />   <%= f.country_select :country, Carmen.default_country, {},     {       :onChange => remote_function( :url => { :action => '_get_states' }, :update => "state", :with => "'country=' +value")     } %>    </p>   <p><%= f.submit "Submit" %></p> <% end %>

" Note that I have a partial that gets called, /views/associates/ _get_states.html.erb:

<% if @states !=nil %> <% for state in @states %>   <option value="<%= state[1] %>"><%= state[0] %></option> <% end %> <% end %>

Then, in my AssociatesController, I put in the method _get_states:

def _get_states #essentially, this requires the 2 letter code for the country selected, so if 'united_kingdom' is selected #it converts to UK and gets its "states". It also handles the default, which is already specified properly      q = params[:country]      if(q!=Carmen.default_country)         q1 = q.gsub!("_", " ")         if(q1!=q && q1!=nil)             q = q1.titleize         else             q.capitalize!         end         q = Carmen::country_code(q)      end     @states = Carmen::states(q)    end

A select box has a selected value if one of its option tags has selected="selected". You never do this to you option tags and so your select box will never show the selected value. Why not use one of the rails helpers for generating option tags ?

Fred

Fred,

What do you mean "use one of the rails helpers for generating option tags?" Where can I see an example of this? Thanks, Janna B

api.rubyonrails.org has examples.

options_for_select (ActionView::Helpers::FormOptionsHelper)

options_from_collection_for_select (ActionView::Helpers::FormOptionsHelper)

Julian.

Yes, I understand -- and am looking at it -- Im just not sure where to cobble it in (in what files, amending what files) given what I have working here. -JannaB

Yes, I understand -- and am looking at it -- Im just not sure where to cobble it in (in what files, amending what files) given what I have working here. -JannaB

You know what I really like to do? put a debugger into your view, and then mess with the method in the console... it's good. Go do it now... (just don't forget to take out the debugger later)

Just now I wacked a <% debugger %> into the layout of one of my apps, and loaded up mongrel, then hit the root url...

bam... up pops a console, and you're "in" a view... you can mess with it... you get stack traces if you write the wrong thing, but it's good all the same...

Phatty:sensei julian$ mongrel_rails start -p 3003 ** Starting Mongrel listening at 0.0.0.0:3003 ** Starting Rails with development environment... ** Rails loaded. ** Loading any Rails specific GemPlugins ** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart). ** Rails signals registered. HUP => reload (without restart). It might not work well. ** Mongrel 1.1.5 available at 0.0.0.0:3003 ** Use CTRL-C to stop.

---- HERE IS WHERE I LOADED THE ROOT OF MY APP IN A BROWSER: localhost:3003 --

/Users/julian/code/rails/sensei/app/views/layouts/application.html.erb:15 <% debugger %> (rdb:1) irb >> options_for_select("hi") => "<option value=\"hi\">hi</option>" >> options_for_select([1]) => "<option value=\"1\">1</option>" >> options_for_select([1,2]) => "<option value=\"1\">1</option>\n<option value=\"2\">2</option>" >> options_for_select([1,2,3]) => "<option value=\"1\">1</option>\n<option value=\"2\">2</option>\n<option value=\"3\">3</option>" >> options_for_select([[1,2],[3,4]]) => "<option value=\"2\">1</option>\n<option value=\"4\">3</option>" >> options_for_select([[:hello,2],[:yes,4]]) => "<option value=\"2\">hello</option>\n<option value=\"4\">yes</

"

>> options_for_select ArgumentError: wrong number of arguments (0 for 1)   from (irb):2:in `options_for_select'   from (irb):2:in `send'   from /Users/julian/code/rails/sensei/app/views/layouts/application.html.erb:15:in `send'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/renderable.rb:34:in `render'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/base.rb:301:in `with_template'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/renderable.rb:30:in `render'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/template.rb:194:in `render_template'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/base.rb:260:in `render'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/base.rb:347:in `_render_with_layout'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_view/base.rb:257:in `render'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_controller/base.rb:1241:in `render_for_file'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_controller/base.rb:937:in `render_without_benchmark'   from /Users/julian/code/rails/sensei/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:51:in `render'   from /Users/julian/code/rails/sensei/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms'   from /Users/julian/code/rails/sensei/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:10:in `realtime'   from /Users/julian/code/rails/sensei/vendor/rails/activesupport/lib/active_support/core_ext/benchmark.rb:17:in `ms' ... 46 levels...   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:158:in `process_client'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `initialize'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `new'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:285:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `initialize'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `new'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel.rb:268:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:282:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `each'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/configurator.rb:281:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/command.rb:212:in `run'   from /Library/Ruby/Gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281   from /usr/bin/mongrel_rails:19:in `load'   from /usr/bin/mongrel_rails:19 >> exit /Users/julian/code/rails/sensei/app/views/layouts/application.html.erb:15 <% debugger %> (rdb:1) cont

Julian - <% debugger %> will only work if you are running in irb, yes? I am running in Mongrel and I get nothing. -Janna B

My question then boils down to this -- how do I access the string value of Associate.state from within my partial /views/associates/ _get_states,html.erb so as to perform the conditional on line 4, below? -Janna B (state[0] might == "NY" but the right side of the == needs to be Associate.state. how do I get at that from in here?

<% if @states !=nil %>   <% for state in @states %>     <option value="<%= state[1] %>"     <% if state[0]==state %>       selected="selected"     <% end %>     >     <%= state[0] %></option>   <% end %> <% end %>

No debugger will work in mongrel if you have required the debugger in your environments/development.rb file

require "ruby-debug"

Julian.

Or you can start your dev server with the --debugger option