jquery weui地区选择器数据自定义报错'sub' of undefined,修改源码解决
报错原因是数据格式错误,或者设置默认选择的地区与数据不一致
<div class="weui-cell">
<div class="weui-cell__hd">居住地:</div>
<div class="weui-cell__bd">
<input class="weui-input" type="text" id="city" value="北京 北京市 东城区">
</div>
</div>
city-picker.js
+function($){
//部分地区数据,按照以下格式自定义数据,此处省略一万行
$.rawCitiesData = [{
"name": "北京",
"code": "110000",
"sub": [{
"name": "北京市",
"code": "110000",
"sub": [{
"name": "东城区",
"code": "110101"
}, {
"name": "西城区",
"code": "110102"
}, {
"name": "朝阳区",
"code": "110105"
}, {
"name": "丰台区",
"code": "110106"
}, {
"name": "石景山区",
"code": "110107"
}, {
"name": "海淀区",
"code": "110108"
}, {
"name": "门头沟区",
"code": "110109"
}, {
"name": "房山区",
"code": "110111"
}, {
"name": "通州区",
"code": "110112"
}, {
"name": "顺义区",
"code": "110113"
}, {
"name": "昌平区",
"code": "110114"
}, {
"name": "大兴区",
"code": "110115"
}, {
"name": "怀柔区",
"code": "110116"
}, {
"name": "平谷区",
"code": "110117"
}, {
"name": "密云县",
"code": "110228"
}, {
"name": "延庆县",
"code": "110229"
}]
}]
}, {
"name": "天津",
"code": "120000",
"sub": [{
"name": "天津市",
"code": "120000",
"sub": [{
"name": "和平区",
"code": "120101"
}, {
"name": "河东区",
"code": "120102"
}, {
"name": "河西区",
"code": "120103"
}, {
"name": "南开区",
"code": "120104"
}, {
"name": "河北区",
"code": "120105"
}, {
"name": "红桥区",
"code": "120106"
}, {
"name": "东丽区",
"code": "120110"
}, {
"name": "西青区",
"code": "120111"
}, {
"name": "津南区",
"code": "120112"
}, {
"name": "北辰区",
"code": "120113"
}, {
"name": "武清区",
"code": "120114"
}, {
"name": "宝坻区",
"code": "120115"
}, {
"name": "滨海新区",
"code": "120116"
}, {
"name": "宁河县",
"code": "120221"
}, {
"name": "静海县",
"code": "120223"
}, {
"name": "蓟县",
"code": "120225"
}]
}]
}];
}($);
+ function($) {
"use strict";
var defaults;
var raw = $.rawCitiesData;
var format = function(data) {
var result = [];
for(var i=0;i<data.length;i++) {
var d = data[i];
if(/^请选择|市辖区/.test(d.name)) continue;
result.push(d);
}
if(result.length) return result;
return [];
};
var sub = function(data) {
if(!data.sub) return [{ name: '', code: data.code }]; // 有可能某些县级市没有区
return format(data.sub);
};
var getCities = function(d) {
for(var i=0;i< raw.length;i++) {
if(raw[i].code === d || raw[i].name === d) return sub(raw[i]);
}
return [];
};
var getDistricts = function(p, c) {
for(var i=0;i< raw.length;i++) {
if(raw[i].code === p || raw[i].name === p) {
for(var j=0;j< raw[i].sub.length;j++) {
if(raw[i].sub[j].code === c || raw[i].sub[j].name === c) {
return sub(raw[i].sub[j]);
}
}
}
}
};
var parseInitValue = function (val) {
var p = raw[0], c, d;
var tokens = val.split(' ');
raw.map(function (t) {
if (t.name === tokens[0]) p = t;
});
p.sub.map(function (t) {
if (t.name === tokens[1]) c = t;
})
if (tokens[2]) {
c.sub.map(function (t) {
if (t.name === tokens[2]) d = t;
})
}
if (d) return [p.code, c.code, d.code];
return [p.code, c.code];
}
$.fn.cityPicker = function(params) {
params = $.extend({}, defaults, params);
return this.each(function() {
var self = this;
var provincesName = raw.map(function(d) {
return d.name;
});
var provincesCode = raw.map(function(d) {
return d.code;
});
var initCities = sub(raw[0]);
var initCitiesName = initCities.map(function (c) {
return c.name;
});
var initCitiesCode = initCities.map(function (c) {
return c.code;
});
var initDistricts = sub(raw[0].sub[0]);
var initDistrictsName = initDistricts.map(function (c) {
return c.name;
});
var initDistrictsCode = initDistricts.map(function (c) {
return c.code;
});
var currentProvince = provincesName[0];
var currentCity = initCitiesName[0];
var currentDistrict = initDistrictsName[0];
var cols = [
{
displayValues: provincesName,
values: provincesCode,
cssClass: "col-province"
},
{
displayValues: initCitiesName,
values: initCitiesCode,
cssClass: "col-city"
}
];
if(params.showDistrict) cols.push({
values: initDistrictsCode,
displayValues: initDistrictsName,
cssClass: "col-district"
});
var config = {
cssClass: "city-picker",
rotateEffect: false, //为了性能
formatValue: function (p, values, displayValues) {
return displayValues.join(' ');
},
onChange: function (picker, values, displayValues) {
var newProvince = picker.cols[0].displayValue;
var newCity;
if(newProvince !== currentProvince) {
var newCities = getCities(newProvince);
newCity = newCities[0].name;
var newDistricts = getDistricts(newProvince, newCity);
picker.cols[1].replaceValues(newCities.map(function (c) {
return c.code;
}), newCities.map(function (c) {
return c.name;
}));
if(params.showDistrict) picker.cols[2].replaceValues(newDistricts.map(function (d) {
return d.code;
}), newDistricts.map(function (d) {
return d.name;
}));
currentProvince = newProvince;
currentCity = newCity;
picker.updateValue();
return false; // 因为数据未更新完,所以这里不进行后序的值的处理
} else {
if(params.showDistrict) {
newCity = picker.cols[1].displayValue;
if(newCity !== currentCity) {
var districts = getDistricts(newProvince, newCity);
picker.cols[2].replaceValues(districts.map(function (d) {
return d.code;
}), districts.map(function (d) {
return d.name;
}));
currentCity = newCity;
picker.updateValue();
return false; // 因为数据未更新完,所以这里不进行后序的值的处理
}
}
}
//如果最后一列是空的,那么取倒数第二列
var len = (values[values.length-1] ? values.length - 1 : values.length - 2)
$(self).attr('data-code', values[len]);
$(self).attr('data-codes', values.join(','));
if (params.onChange) {
params.onChange.call(self, picker, values, displayValues);
}
},
cols: cols
};
if(!this) return;
var p = $.extend({}, params, config);
//计算value
var val = $(this).val();
//自定义需要默认值与name对应
if (!val) val = '北京 北京市 东城区';
currentProvince = val.split(" ")[0];
currentCity = val.split(" ")[1];
currentDistrict= val.split(" ")[2];
if(val) {
p.value = parseInitValue(val);
if(p.value[0]) {
var cities = getCities(p.value[0]);
p.cols[1].values = cities.map(function (c) {
return c.code;
});
p.cols[1].displayValues = cities.map(function (c) {
return c.name;
});
}
if(p.value[1]) {
if (params.showDistrict) {
var dis = getDistricts(p.value[0], p.value[1]);
p.cols[2].values = dis.map(function (d) {
return d.code;
});
p.cols[2].displayValues = dis.map(function (d) {
return d.name;
});
}
} else {
if (params.showDistrict) {
var dis = getDistricts(p.value[0], p.cols[1].values[0]);
p.cols[2].values = dis.map(function (d) {
return d.code;
});
p.cols[2].displayValues = dis.map(function (d) {
return d.name;
});
}
}
}
$(this).picker(p);
});
};
defaults = $.fn.cityPicker.prototype.defaults = {
showDistrict: true //是否显示地区选择
};
}($);