/** * jquery.citys.js 1.0 * http://jquerywidget.com */ ; (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 = { wrapClass: '.picker-item', dataUrl: '/dist/dataLocation/list.json', //数据库地址 crossDomain: true, //是否开启跨域 dataType: 'json', //数据库类型:'json'或'jsonp' provinceField: 'province', //省份字段名 cityField: 'city', //城市字段名 areaField: 'area', //地区字段名 townField: 'town', // -- 添加四级的字段名 镇/街道 -- 添加 valueType: 'code', //下拉框值的类型,code行政区划代码,name地名 code: 0, //地区编码 province: 0, //省份,可以为地区编码或者名称 city: 0, //城市,可以为地区编码或者名称 area: 0, //地区,可以为地区编码或者名称 town: 0, //-- 街道, 可以为地区编码或者名称 required: true, //是否必须选一个 nodata: 'hidden', //当无数据时的表现形式:'hidden'隐藏,'disabled'禁用,为空不做任何处理 onChange: 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 + '"]'), $town = $this.find('select[name="' + options.townField + '"]'); // 数据规律: // province: "130 000":"河北省", // city: "130 100":"石家庄市", // area: "130 102":"长安区", // town: /down/130102.json "130 102 001":"建北街道"; 130 133 100 赵州镇 110 102 001 西长安街街道 $.ajax({ url: options.dataUrl, type: 'GET', crossDomain: options.crossDomain, dataType: options.dataType, jsonpCallback: 'jsonp_location', success: function (data) { var province, city, area, hasCity, town, setTown; setTown = options.town ? 1 : 0; // 是否设置了 twon 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 = {}, town = {}; hasCity = false; // 判断是非有地级城市 hastown = 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 (isNaN(options.province) && data[code].indexOf(options.province) > -1) { // 填写默认值 解析为code; 如果切换省 options.province = code; } } else { // cityCode var p = code - options.province; if (options.province && p > 0 && p < 1e4) { //同省的城市或地区 if (!(code % 100)) { hasCity = true; city[code] = data[code]; if (options.required && !options.city) { options.city = code; } else if (isNaN(options.city) && data[code].indexOf(options.city) > -1) { options.city = code; } } else if (p > 8000) { //省直辖县级行政单位 city[code] = data[code]; if (options.required && !options.city) { options.city = code; } else if (isNaN(options.city) && data[code].indexOf(options.city) > -1) { options.city = code; } } else if (hasCity) { //非直辖市 var c = code - options.city; if (options.city && c > 0 && c < 100) { //同个城市的地区 area[code] = data[code]; if (options.required && !options.area) { options.area = code; } else if (isNaN(options.area) && data[code].indexOf(options.area) > -1) { options.area = code; } } } else { area[code] = data[code]; //直辖市 if (options.required && !options.area) { options.area = code; } else if (isNaN(options.area) && data[code].indexOf(options.area) > -1) { options.area = code; } } } } } // 更新数据 // 镇:130133100 街道110102001 // 初始化 town $.ajax({ url: '/dist/dataLocation/town/' + options.area + '.json', dataType: 'json', async: false, // 去掉异步 success: function (data) { $town.empty(); for (var i in data) { if (!options.town) {// 未定义 if (i % 100 === 0 || i % 100 === 1 || i % 100 === 2 || i % 100 === 3) { options.town = data[i]; } } $town.append(''); } } }); }; var format = { province: function () { $province.empty(); if (!options.required) { $province.append(''); } for (var i in province) { $province.append(''); } 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').parents(options.wrapClass).css('display', 'none'); } else { $city.css('display', '').parents(options.wrapClass).css('display', '');; if (!options.required) { $city.append(''); } if (options.nodata == 'disabled') { $city.prop('disabled', $.isEmptyObject(city)); } else if (options.nodata == 'hidden') { $city.css('display', $.isEmptyObject(city) ? 'none' : '').parents(options.wrapClass).css('display', $.isEmptyObject(city) ? 'none' : ''); } for (var i in city) { $city.append(''); } 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(''); } if (options.nodata == 'disabled') { $area.prop('disabled', $.isEmptyObject(area)); } else if (options.nodata == 'hidden') { $area.css('display', $.isEmptyObject(area) ? 'none' : '').parents(options.wrapClass).css('display', $.isEmptyObject(area) ? 'none' : ''); } for (var i in area) { $area.append(''); } if (options.area) { var value = options.valueType == 'code' ? options.area : area[options.area]; $area.val(value); } this.town(); }, // 添加第四级 街道/镇 town: function () { if (!options.required) { $town.append(''); } if (options.town) { var value = options.town; $town.val(value); } } }; //获取当前地理信息 _api.getInfo = function () { var _status = { direct: !hasCity, province: data[options.province] || '', city: data[options.city] || '', area: data[options.area] || '', // 添加 街道/镇 town: options.town || '', // 地区编码 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; options.town = 0; updateData(); format.city(); // cb options.onChange(_api.getInfo()); // 这里的状态滞后的问题; console.log(options) }); $city.on('change', function () { options.city = $(this).find('option:selected').data('code') || 0; //选中节点的区划代码 options.area = 0; options.town = 0; updateData(); format.area(); // cb options.onChange(_api.getInfo()); }); $area.on('change', function () { options.area = $(this).find('option:selected').data('code') || 0; //选中节点的区划代码 options.town = 0; updateData(); //format.area(); options.onChange(_api.getInfo()); }); // town $town.on('change', function () { options.town = $(this).find('option:selected').val() || 0; // cur selected updateData(); format.town(); options.onChange(_api.getInfo()); }); //初始化 updateData(); format.province(); // => city => area => town if (options.code) { options.onChange(_api.getInfo()); } getApi(_api); } }); }); }; }));