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