Forum: Ruby on Rails cascading select box

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
3a66057e3dd3e076964a1559ade6cfa0?d=identicon&s=25 dhaval (Guest)
on 2007-06-04 14:24
(Received via mailing list)
hey people i am trying to create dynamic drowns with three select
boxes and using one model ...if i change first drop down then the
second gets updated but the third one doesnt get updated...could u
please tell me wat is the problem


here is the controller code

class AdminController < ApplicationController
 def state_update
   return unless request.xhr?
   cities = State.find_by_sql("select distinct city_name from states
where state_id=#{params[:state_id]}")
   render :update do |page|
   page << update_select_box( "city_id",
   cities,
   {:text => :city_name,
      :clear => ['area_id']})
   end
 end
  def city_update
   return unless request.xhr?
   areas = State.find( :all, :conditions => ["city_id=?",
params[:ecosite_index]])
     flash[:notice]="#{params[:ecosite_index]}"
   render :update do |page|
   page << update_select_box( "area_id",
   areas,
   {:text => :area_name} )
    end
  end

 def index
   @states=State.find_by_sql("select distinct name,state_id from
states")

 end
end


here is the view

<script language="javascript">
function update_select_options( target, opts_array,
clear_select_list ) {

    if( $(target).type.match("select" ) ){ // Confirm the target is a
select box

        // Remove existing options from the target and the
clear_select_list
        clear_select_list[clear_select_list.length] = target //
Include the target in the clear list

        for( k=0;k < clear_select_list.length;k++){
            obj = $(clear_select_list[k]);
            if( obj.type.match("select") ){
                len = obj.childNodes.length;
                for( var i=0;i < len;i++)
{obj.removeChild(obj.firstChild);}
            }
        }

        // Populate the new options
        for(i=0;i < opts_array.length;i++){
            o = document.createElement( "option" );
            o.appendChild( document.createTextNode( opts_array[i]
[0] ) );
            o.setAttribute( "value", opts_array[i][1] );
            obj.appendChild(o);
        }
    }
}
</script>
<%= javascript_include_tag :defaults %>
 <%= start_form_tag %>
 <% options = [["Select State", " "]] + @states.collect { |c|
[c.name,c.state_id] } %>
 <%= select("state", "id", options) %>
 <%= select( "city", "id", [] ) %>
 <%= select( "area", "id", [] ) %>
 <%= submit_tag %>
 <%= end_form_tag %>

 <%= observe_field "state_id",
 {:url => {:action => 'state_update'},
 :with => "state_id"} %>


  <%= observe_field "city_id",
 {:url => {:action => 'city_update'},
 :with => "ecosite_index"} %>


this is the helper code

def update_select_box( target_dom_id, collection, options={} )

   # Set the default options
   options[:text] ||= 'name'
   options[:value] ||= 'id'
   options[:include_blank] ||= true
   options[:clear] ||= []
   pre = options[:include_blank] ? [['select ','select ']] : []

   out = "update_select_options( $('" << target_dom_id.to_s << "'),"
   out << "#{(pre + collection.collect{ |c| [c.send(options[:text]),
c.send(options[:value])]}).to_json}" << ","
   out << "#{options[:clear].to_json} )"
  end
This topic is locked and can not be replied to.