还记得前面的那个Ajax Select的例子吗?实际上实现像国家,城市这样option已经确定的select的级联并没有必要使用Ajax,通过客户端JS就可以轻松实现,而不必向服务端发送请求。
1. 生成person resource
script/generate person country:string state:string
由于不再需要向服务端发送请求,因此没有必要生成一个单独的city resource。
2. 执行rake db:migrate
3. 修改app/views/layouts/people.rhtml,包含prototype:
<%= javascript_include_tag 'prototype' %>
4. 修改app/views/people/new.rhtml:
<%= update_page_tag do |page|
page << "function change_state(country_value) {"
page << 'if(country_value == "United States")'
page['person_state'].replace_html options_for_select(US_STATES)
page << 'else if(country_value == "China")'
page['person_state'].replace_html options_for_select(CHINA_STATES)
page << 'else'
page['person_state'].replace_html options_for_select([['Not applicable', '']])
page << "}"
end
%>
<p>
<b>Country</b><br />
<%= f.country_select :country, ['China', 'United States'], {:selected=>'China'},
nchange => 'change_state(this.options[this.selectedIndex].value)'
%>
</p>
<p>
<b>States</b><br />
<%= f.select :state, CHINA_STATES %>
</p>
相比于上一篇,new.rhtml的改动还是比较大的:
- 我们使用country_select来自动生成国家select
-
nchange方法现在指向本地的JS函数change_state,而非remote_function生成的一个AJAX函数。 - change_state函数没有向服务器发送请求,它在本地保存了所有支持国家的省份信息
5. 当然,我们需要定义两个名为US_STATES和CHINA_STATES的常量来保存两个国家的省份信息:
US_STATES = [["Please select", ""], [ "Alabama", "AL" ], [ "Alaska", "AK" ], ..........
CHINA_STATES = [["Please select", ""], [ "Beijing", "BJ" ], [ "Shanghai", "SH" ], ..........
6. 默认:
7. 选择United States:
8. 选择其他国家:
参考:
