select层叠的AJAX实现

假设我们有两个select,子select的内容需要随父select而动态改变,这篇指南将向你演示如何实现AJAX方式的select层叠:

1. 创建三个资源:country,city,person

ruby script/generate scaffold_resource country name:strin
ruby script/generate scaffold_resource city country_id:int name:string
ruby script/generate scaffold_resource person country_id:int city_id:int name:string

2. 执行rake db:migrate
3. 修改app/views/layouts/people.rhtml,包含prototype:

<%= javascript_include_tag 'prototype' %>

4. 修改app/views/people/new.rhtml:

<p>
  <b>Country</b><br />
  <%= f.select (:country_id, Country.find_all.collect {|c| [ c.name, c.id ] },
    { :include_blank => true },
     :o nchange => remote_function(:update => "cities",
       :method => "get",
       :with => "'country_id=' + value + '&partial=select'",
       :url => { :controller => :cities,
         :action => :index}))
  %>
</p>
<p>
  <b>City</b><br />
  <div id="cities">
  <%= f.select (:city_id, []) %>
  </div>
</p>

这段代码为country select定义了onchange函数,它会在country select的选择项变化时重新请求cities/index,并更新city select。

5. 现在打开http://localhost:3000/people/new,你会看到:

6. 但是别着急,工作还没完成,cities/index并不会自动帮你返回一个select,因此我们需要修改cities_controller的index方法:

def index
  if params[:country_id]
    @cities = City.find(:all, :conditions => ["country_id = ?", params[:country_id]])
  else
    @cities = City.find(:all)
  end
  respond_to do |format|
    format.html { render :partial => params[:partial]}
    format.xml { render :x ml => @districts.to_xml }
  end
end

现在,index action会根据:country_id参数返回指定国家的城市,并根据partial参数来决定如何对数据进行渲染:

format.html { render :partial => params[:partial]}

要将结果渲染为一个select,我们需要定义_select.rhtml,它很简单:

<%= select(:person, :city_id, @cities.collect {|c| [c.name, c.id]}) %>

7. 一切搞掂,现在再次打开http://localhost:3000/people/new,选择中国,你会发现,city select已经跟随你的选择而动态更新了:

8. 很简单,但是还有个问题需要说明,由于IE不支持替换select的innerHTML,因此我们在_select.rhtml中返回了整个 select(本来应该只要options就足够了),注意select的第一个参数是:people,也就是说这个select将只能够为 people/new工作,如果你想要让_select.rhtml更通用些,那就需要再增加一个参数(比如owner)来充当select的第一个参 数。(完)

This entry was posted in AJAX, 指南. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

无觅相关文章插件,快速提升流量