參考代碼:
JQuery中國省市區街道三級、四級聯動下拉菜單插件
(將代碼中單純的四級聯動提取出來,對其中的bug進行了修正,並完善了一些不完美的地方)javascript
先經過最終效果看一下功能:
css
代碼以下:html
<!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>
;(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); } }); }); }; }));