jQuery WeUI City-Picker Demo:http://www.jqweui.cn/extends#city-picker
官方的city-picker提供了两种样式:
(1)省级-市级-区级
(2)省级-市级(不显示区级)
前端页面要引入的JS、CSS文件如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
BORN TO LOVE
最近开发的应用有一个新的需求,由于是在湖北省内使用,要求不显示“湖北省”,只选择市级-区级,而且地址名称需要自定义。
因此这里需要解决两个问题:
#1-> 如何只显示两级“市级-区级”?
#2-> 如何实现city-picker数据源动态加载,即数据自定义的问题?
在解决上述问题之前,我们先看看[city-pcker.js]里的源数据是如何组织的吧 ^^。
[city-pcker.js] 里的源数据是按JSON格式组织的 rawCitiesData ,例如“湖北省-武汉市-武昌区”的组织结构如下所示。
$.rawCitiesData = [
{
"name":"湖北省",
"code":"420000",
"sub":[
{
"name":"武汉市",
"code":"420100",
"sub":[
{
"name":"武昌区",
"code":"420106"
},
]
},
...
]
}
]
现在来解决第一个问题,如何只显示“市级-区级”,不显示“省级”。
思路1:参照官网不显示区级的做法
直接在 city-picker.js 修改 defaults = $.fn.cityPicker.prototype.defaults 增加 showProvince: true
defaults = $.fn.cityPicker.prototype.defaults = {
showDistrict: true, //是否显示地区选择
showProvince: true //是否显示省份选择
};
前端页面初始化添加 showProvice: false
$("#home-city").cityPicker({
title: "选择目的地",
showProvince: false, //不显示省级
onChange: function (picker, values, displayValues) {
console.log(values, displayValues);
}
});
但是,并没有达到想要的效果,没有任何影响。
原因是这里相当于只是写了一个属性名,必须自定义完善对应的方法,相当于要参照showDistrict的方法写一套处理showProvince的方法,虽然确实可以实现,但必须要读懂 city-picker.js 源码再进行相应的修改,对小白来说太不友好了。
比如下图展示了源码中涉及到showDistrict的所有地方,如果要改showProvince只会更麻烦,因为省份默认是带sub子节点的,这个结构注定了可以向下追溯,没法直接从中间节点向上追溯的,感兴趣的大神可以自行考虑如何改写这个逻辑代码。
思路2:严格按照 rawCitiesData 的JSON格式重新组织数据源
原始数据:“湖北省” - “武汉市” - “武昌区”
改写数据:“武汉市” - “武昌区” - null
{
"name": "武汉市",
"code": "420100",
"sub": [
{
"name": "武昌区",
"code": "420106",
"sub": []
}
]
}
页面再按照不显示区级的方法初始化city-picker
$("#home-city").cityPicker({
title: "选择目的地",
showDistrict: false,
onChange: function (picker, values, displayValues) {
console.log(values, displayValues);
}
});
只选择城市
需要强调的是,这里的必须初始化value值,不然会报错
报错原因分析:
原始的 city-picker.js 里有一段代码
//计算value
var val = $(this).val();
if (!val) val = '北京 北京市 东城区';
currentProvince = val.split(" ")[0];
currentCity = val.split(" ")[1];
currentDistrict = val.split(" ")[2];
这段代码的意思是取input框的value值,如果value为空则赋值为“北京 北京市 东城区”,并初始化picker的三层选择框的省份为“北京”、城市为“北京市”、地区为“东城区”,当点击这个input框的时候,初始的选择值就是“北京 北京市 东城区”。但是我们之前已经把 rawCitiesData 进行了重写,只保留了武汉市的数据,因此如果input不初始化value值,控件找不到这个值,自然会报错。
解决方式主要有两种:
一种是直接给input赋值初始value,另一种就是在city-picker.js里修改上面那段代码。
需要注意的是value值必须是 rawCitiesData 中初始化的值,不然也会报错。
//计算value
var val = $(this).val();
if (!val) val = '武汉 武昌区';
currentProvince = val.split(" ")[0];
currentCity = val.split(" ")[1];
currentDistrict = val.split(" ")[2];
演示效果:
现在来解决第二个问题, 如何动态加载数据源,可以自定义数据,满足个性化需求。
#-> 思路:
要自定义显示的数据,直接修改 city-picker.js 里的 rawCitiesData 就行了。
一种方式,自己按照 rawCitiesData 的JSON格式组织自己要的数据,然后粘贴复制替换掉原来的rawCitiesData 就行。这种方式比较适合数据量比较小,且固定后期变动比较小的情况,优点是修改直观且简单粗暴。
另一种方式就是实现动态加载数据源,通过外部传参的方式初始化数据源,数据源可通过ajax的方式去后台数据库查询,然后组织成对应的JSON格式返回前端。这种方式就比较适合数据量比较大且后期数据变动较大的情况,优点是维护方便。
#-> 实现:
首先,我们来看看 city-picker.js 源码是如何对数据源进行操作的。
其实很简单,就是设置了一个变量 raw ,然后初始化赋值成数据源 rawCitiesData 。有点类似一个类Class里直接给属性赋值初始化的过程,如果要动态修改这个属性的值,我们通常会增加 set 方法,所以这里也是一样的道理,可以给 raw 也增加一个 set 方法,实现动态修改 raw 的值。
// 初始化赋值成空
var raw = [];
// 新增set方式为raw赋值
var setRawDataList= function (raw_data_list) {
raw = raw_data_list;
}
和构造函数设置参数一样,这里 set 方法里传入的参数 raw_data_list 也需要修改默认参数设置,新增一个参数 initDataList ,用于接收外部数据源。
defaults = $.fn.cityPicker.prototype.defaults = {
showDistrict: true, //是否显示地区选择
initDataList: [] //加载数据源-参数设置
};
最后在 city-picker 初始化的时候为 raw 进行赋值操作,在 $.fn.cityPicker = function (params) {}里新增如下代码,params.initDataList 就是刚刚在defaults里设置的新增参数。
$.fn.cityPicker = function (params) {
params = $.extend({}, defaults, params);
return this.each(function () {
var self = this;
// 根据外部传入的参数为raw赋值
if(params.initDataList != null && params.initDataList.length > 0 ){
setRawDataList(params.initDataList);
}
... // 其他代码不变
}
主要修改的就只有三个地方,如下图所示
至此,city-picker.js 修改完毕。
前端html
请选择目的地
city-picker初始化,datalist可以通过ajax去后台获取,这里为了演示方便直接写出来了,另外需要注意的是JSON数据要加“[ ]”。
--- 20200724 --- 更新 ----------------------------------
#-> 自定义打开滚动框时的默认选中值
整体修改思路和上面自定义数据源的方式类似,把默认值改成外部自定义输入即可,添加相应的set方法完成赋值。
分析city-picker.js源代码,打开滚动框设定默认值的代码是这一行,因此需要修改这里的val为外部输入的变量值。
var val = $(this).val();
if (!val) val = '湖北 武汉 武昌区';
在defaults设置里新增一个默认外部输入变量 initCityShowValue
defaults = $.fn.cityPicker.prototype.defaults = {
initCityShowValue: "" //设置滚动框显示的默认值
};
给新变量 showval 新增set方法 setShowValue()
// 初始化赋值成""
var showval = "";
// 新增set方式为showval赋值
var setShowValue = function (show_value) {
showval = show_value;
}
通过set方法将外部传入的参数 params.initCityShowValue 赋值给 showval
$.fn.cityPicker = function (params) {
params = $.extend({}, defaults, params);
return this.each(function () {
var self = this;
// 根据外部传入的参数为showval赋值
if(params.initCityShowValue !== "" && params.initCityShowValue.length > 0 ){
setShowValue(params.initCityShowValue);
}
}
最后修改原来的默认值为我们新增的这个变量值 showval 即可
if (!val) val = showval;
前端初始化的时候,通过指定 initCityShowValue 的值即可
$("#destination").cityPicker({
title: "请选择出差地点",
// showDistrict: false,
initCityShowValue: "武汉 江岸 个险",
onChange: function (picker, values, displayValues) {
console.log(values, displayValues);
console.log("values:" + values);
console.log("displayValues:" + displayValues[0] + " " + displayValues[1] + " " + displayValues[2]);
}
});
参考:https://blog.csdn.net/weixin_41913378/article/details/103175157