首先:确定数据库的设计,下面将省市地区数据以如下方式存入数据库的cities表:
+--------+--------------+
| id | cname |
+--------+--------------+
| 110000 | 北京市 | 第1级
| 110100 | 北京市 | 第2级
| 110101 | 东城区 | 第3级
| 110102 | 西城区 | 第3级
+--------+--------------+
那么,要取所有省(直辖市)的数据,可通过下面语句:
mysql> select * from cities where (id mod 10000 = 0 );
取某个省(直辖市)的所有市的数据,可通过下面语句:
mysql> select * from cities where (id mod 100 = 0 ) and (id div 10000 = #{province_id} div 10000 )
and (id != #{province_id});
取第三级数据:
mysql> select * from cities where(id div 100 = #{city_id} div 100 ) and (id != #{city_id});
下面开始写rails 应用:步骤如下
①、ruby script/generate scaffold city cname:string
②、写取所有省(直辖市)的数据的函数
class City < ActiveRecord::Base
def self.get_province_select_options
City.find_by_sql("select * from cities where (id mod 10000 =0 )").collect { |row| [row.cname,row.id] }.insert(0,["--请选择--",0])
end
end
③、假设这个省市地区级联应用是出现在公司(Company)的视图上,而且companies表里有相应的字段province_id、city_id、area_id。
首先在./views/layouts/companies.html.erb
添加<%= javascript_include_tag 'prototype' %> 以便定义Ajax请求,
接着就可以修改视图了Company的new/eidt视图如下:
%table
%tr
%td
=f.select(:province_id, City.get_province_select_options,{},
"onchange" => remote_function(
:with => " 'province_id = '+ value + '&partial = select_city' ",
:update =>"cityid", :complete => "Element.hide('areaid') ",
:url =>{:controller => :cities, :action => :index_city} ),
:style=>"width:150px")
%td
%div{:id=>'cityid'}
%td
%div{:id=>'areaid'}
注意:对于haml模板,上面的分行是会出错的,f.select()最好写成一行。
接着就要相应修改:controller、:action、:partial
④、修改CitiesController,主要是定义 action ——index_city
class CitiesController < ApplicationController
def index_city
if params[:province_id]
province_id = params[:province_id]
@cities = City.find_by_sql("select * from cities where (id mod 100 =0 )and (id div 10000 = #{province_id} div 10000 )
and (id != #{province_id})").collect {|c| [c.cname, c.id]}.insert(0,["--请选择--",0])
else
@cities = City.find(:all).collect {|c| [c.cname, c.id]}
end
respond_to do |format|
format.html { render :partial => params[:partial]}
format.xml { render: xml => @cities.to_xml }
end
end
end
⑤、写partial—— select_city, 在./views/cities新建一个
_select_city.html.erb,内容如下:
<%= select(:company, :city_id, @cities,{},
"onchange" => remote_function( :with => "'city_id='+value+ '&partial = select_area' ",
:update => "areaid",:complete => "Element.show('areaid')",
:url =>{:controller => :cities,:action => :index_area} ),
:style=>"width:160px")
%>
同理,要写一个action —— index_area,和一个partial ——select_area
class CitiesController < ApplicationController
def index_area
if params[:city_id]
city_id = params[:city_id]
@areas = City.find_by_sql("select * from cities where (id mod 100 =0 )
and (id div 10000 = #{city_id } div 10000 ) and
(id != #{city_id })").collect {|c| [c.cname, c.id]}.insert(0,["--请选择--",0])
else
@areas = City.find(:all).collect {|c| [c.cname, c.id]}
end
respond_to do |format|
format.html { render :partial => params[:partial]}
format.xml { render: xml => @areas.to_xml }
end
end
end
在./views/cities新建一个_select_area.html.erb,内容如下:
<%= select(:company, :area_id, @areas,{},:style=>"width:150px")%>
OK, 在Compnay的视图中使用这个三级联动菜单,已经没问题了。
来自: http://lzqustc.iteye.com/