/**
* 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);
}
});
});
};
}));