参考代码:
JQuery中国省市区街道三级、四级联动下拉菜单插件
(将代码中单纯的四级联动提取出来,对其中的bug进行了修正,并完善了一些不完美的地方)
先通过最终效果看一下功能:
代码如下:
- index.html:(注:请将代码中的jquery.min.js替换成你本地的jquery地址)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery四级联动下拉菜单代码</title>
<script type="text/javascript" src="script/jquery.min.js"></script>
<script type="text/javascript" src="script/jquery.citys.js"></script>
</head>
<body>
<div id="demo3" class="citys">
<p>
<select name="province" id="province"></select>
<select name="city"></select>
<select name="area"></select>
<select name="town"></select>
</p>
</div>
<script type="text/javascript">
var selectedAddress = {\'province\':\'\', \'city\':\'\', \'area\':\'\', \'town\':\'\'};
var $town = $(\'select[name="town"]\');
var clearTown = function(){
$town.hide().empty();
}
var townFormat = function(info){
clearTown();
if(info[\'code\']%1e4&&info[\'code\']<7e5){ //是否为“区”且不是港澳台地区
$.ajax({
url:\'http://passer-by.com/data_location/town/\'+info[\'code\']+\'.json\',
dataType:\'json\',
success:function(town){
$town.show();
$town.append(\'<option value=""> - 街道、乡镇 - </option>\');
for(i in town){
$town.append(\'<option value="\'+i+\'">\'+town[i]+\'</option>\');
}
}
});
}
};
$(\'#demo3\').citys({
onChange: function(info){
clearTown();
selectedAddress.province = info.province;
selectedAddress.city = info.city;
selectedAddress.area = info.area;
},
onAreaChange:function(info){
townFormat(info);
}
},function(api){
var info = api.getInfo();
townFormat(info);
});
$town.on(\'change\', function(){
selectedAddress.town = $(this).find("option:selected").text();
});
console.log(selectedAddress); //输出最终选择的省、市、区县、街道
</script>
</body>
</html>
- jquery.cities.js:
;(function (factory) {
if (typeof define === "function" && (define.amd || define.cmd) && !jQuery) {
// AMD或CMD
define([ "jquery" ],factory);
} else if (typeof module === \'object\' && module.exports) {
// Node/CommonJS
module.exports = function( root, jQuery ) {
if ( jQuery === undefined ) {
if ( typeof window !== \'undefined\' ) {
jQuery = require(\'jquery\');
} else {
jQuery = require(\'jquery\')(root);
}
}
factory(jQuery);
return jQuery;
};
} else {
//Browser globals
factory(jQuery);
}
}(function ($) {
$.support.cors = true;
$.fn.citys = function(parameter,getApi) {
if(typeof parameter == \'function\'){ //重载
getApi = parameter;
parameter = {};
}else{
parameter = parameter || {};
getApi = getApi||function(){};
}
var defaults = {
dataUrl:\'http://passer-by.com/data_location/list.json\', //数据库地址
dataType:\'json\', //数据库类型:\'json\'或\'jsonp\'
provinceField:\'province\', //省份字段名
cityField:\'city\', //城市字段名
areaField:\'area\', //地区字段名
valueType:\'code\', //下拉框值的类型,code行政区划代码,name地名
code:0, //地区编码
province:0, //省份,可以为地区编码或者名称
city:0, //城市,可以为地区编码或者名称
area:0, //地区,可以为地区编码或者名称
required: false, //是否必须选一个
nodata: \'hidden\', //当无数据时的表现形式:\'hidden\'隐藏,\'disabled\'禁用,为空不做任何处理
onChange:function(){}, //地区切换时触发,回调函数传入地区数据
onAreaChange:function(){} //区县切换时触发
};
var options = $.extend({}, defaults, parameter);
return this.each(function() {
//对象定义
var _api = {};
var $this = $(this);
var $province = $this.find(\'select[name="\'+options.provinceField+\'"]\'),
$city = $this.find(\'select[name="\'+options.cityField+\'"]\'),
$area = $this.find(\'select[name="\'+options.areaField+\'"]\');
$.ajax({
url:options.dataUrl,
type:\'GET\',
crossDomain: true,
dataType:options.dataType,
jsonpCallback:\'jsonp_location\',
success:function(data){
var province,city,area,hasCity;
if(options.code){ //如果设置地区编码,则忽略单独设置的信息
var c = options.code - options.code%1e4;
if(data[c]){
options.province = c;
}
c = options.code - (options.code%1e4 ? options.code%1e2 : options.code);
if(data[c]){
options.city = c;
}
c = options.code%1e2 ? options.code : 0;
if(data[c]){
options.area = c;
}
}
var updateData = function(){
province = {},city={},area={};
hasCity = false; //判断是非有地级城市
for(var code in data){
if(!(code%1e4)){ //获取所有的省级行政单位
province[code]=data[code];
if(options.required&&!options.province){
if(options.city&&!(options.city%1e4)){ //省未填,并判断为直辖市
options.province = options.city;
}else{
options.province = code;
}
}else if(data[code].indexOf(options.province)>-1){
options.province = isNaN(options.province)?code:options.province;
}
}else{
var p = code - options.province;
if(options.province&&p>0&&p<1e4){ //同省的城市或地区
if(!(code%100)){
hasCity = true;
city[code]=data[code];
if(data[code].indexOf(options.city)>-1){
options.city = isNaN(options.city)?code:options.city;
}
}else if(p>9000){ //省直辖县级行政单位
city[code] = data[code];
if(data[code].indexOf(options.city)>-1){
options.city = isNaN(options.city)?code:options.city;
}
}else if(hasCity){ //非直辖市
var c = code-options.city;
if(options.city&&c>0&&c<100){ //同个城市的地区
area[code]=data[code];
if(data[code].indexOf(options.area)>-1){
options.area = isNaN(options.area)?code:options.area;
}
}
}else{
area[code]=data[code]; //直辖市
if(data[code].indexOf(options.area)>-1){
options.area = isNaN(options.area)?code:options.area;
}
}
}
}
}
};
var format = {
province:function(){
$province.empty();
if(!options.required){
$province.append(\'<option value=""> - 所在省 - </option>\');
}
for(var i in province){
$province.append(\'<option value="\'+(options.valueType==\'code\'?i:province[i])+\'" data-code="\'+i+\'">\'+province[i]+\'</option>\');
}
if(options.province){
var value = options.valueType==\'code\'?options.province:province[options.province];
$province.val(value);
}
this.city();
},
city:function(){
$city.empty();
if(!hasCity){
$city.css(\'display\',\'none\');
}else{
$city.css(\'display\',\'\');
if(!options.required){
$city.append(\'<option value=""> - 所在市 - </option>\');
}
if(options.nodata==\'disabled\'){
$city.prop(\'disabled\',$.isEmptyObject(city));
}else if(options.nodata==\'hidden\'){
$city.css(\'display\',$.isEmptyObject(city)?\'none\':\'\');
}
for(var i in city){
$city.append(\'<option value="\'+(options.valueType==\'code\'?i:city[i])+\'" data-code="\'+i+\'">\'+city[i]+\'</option>\');
}
if(options.city){
var value = options.valueType==\'code\'?options.city:city[options.city];
$city.val(value);
}else if(options.area){
var value = options.valueType==\'code\'?options.area:city[options.area];
$city.val(value);
}
}
this.area();
},
area:function(){
$area.empty();
if(!options.required){
$area.append(\'<option value=""> - 所在区、县 - </option>\');
}
if(options.nodata==\'disabled\'){
$area.prop(\'disabled\',$.isEmptyObject(area));
}else if(options.nodata==\'hidden\'){
$area.css(\'display\',$.isEmptyObject(area)?\'none\':\'\');
}
for(var i in area){
$area.append(\'<option value="\'+(options.valueType==\'code\'?i:area[i])+\'" data-code="\'+i+\'">\'+area[i]+\'</option>\');
}
if(options.area){
var value = options.valueType==\'code\'?options.area:area[options.area];
$area.val(value);
}
}
};
//获取当前地理信息
_api.getInfo = function(){
var status = {
direct:!hasCity,
province:data[options.province]||\'\',
city:data[options.city]||\'\',
area:data[options.area]||\'\',
code:options.area||options.city||options.province
};
return status;
};
//事件绑定
$province.on(\'change\',function(){
options.province = $(this).find(\'option:selected\').data(\'code\')||0; //选中节点的区划代码
options.city = 0;
options.area = 0;
updateData();
format.city();
options.onChange(_api.getInfo());
});
$city.on(\'change\',function(){
options.city = $(this).find(\'option:selected\').data(\'code\')||0; //选中节点的区划代码
options.area = 0;
updateData();
format.area();
options.onChange(_api.getInfo());
});
$area.on(\'change\',function(){
options.area = $(this).find(\'option:selected\').data(\'code\')||0; //选中节点的区划代码
options.onChange(_api.getInfo());
options.onAreaChange(_api.getInfo());
});
//初始化
updateData();
format.province();
if(options.code){
options.onChange(_api.getInfo());
}
getApi(_api);
}
});
});
};
}));