【JavaWeb】jQuery WeUI框架 地址选择器 City-Picker 自定义demo

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" %>
<html>
<head>
    <!--控制页面自动适应屏幕大小-->
    <meta charset="UTF-8" name="viewport"
          content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

    <title>BORN TO LOVE</title>
    <link rel="shortcut icon" href="#">

    <!--JQuery-->
    <script type="text/javascript" charset="UTF-8" src="resources/scripts/jquery-3.3.1.min.js"></script>
   
    <!--JQuery WEUI-->
    <script type="text/javascript" charset="UTF-8" src="resources/scripts/jquery-weui.min.js"></script>
    <script type="text/javascript" charset="UTF-8" src="resources/scripts/fastclick.js"></script>
    <script type="text/javascript" charset="UTF-8" src="resources/scripts/city-picker.js"></script>

    <!--WeUI CSS-->
    <link rel="stylesheet" type="text/css" href="resources/css/weui.css">
    <link rel="stylesheet" type="text/css" href="resources/css/jquery-weui.css">
</head>

 最近开发的应用有一个新的需求,由于是在湖北省内使用,要求不显示“湖北省”,只选择市级-区级,而且地址名称需要自定义

因此这里需要解决两个问题:

#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);
        }
    });

<body></body> 

<h2 class="demos-second-title">只选择城市</h2>
<div class="weui-cells weui-cells_form">
    <div class="weui-cell">
        <div class="weui-cell__hd"><label for="home-city" class="weui-label">城市</label></div>
        <div class="weui-cell__bd">
            <input class="weui-input" id="home-city" type="text" value="武汉市 武昌区">
        </div>
    </div>
</div>

需要强调的是,这里的<input>必须初始化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 修改完毕。

前端<input>html

<h2 class="demos-second-title">请选择目的地</h2>
<div class="weui-cells weui-cells_form">
    <div class="weui-cell">
        <div class="weui-cell__hd"><label for="home-city" class="weui-label">城市</label></div>
        <div class="weui-cell__bd">
            <input class="weui-input" id="home-city" type="text">
        </div>
    </div>
</div>

city-picker初始化,datalist可以通过ajax去后台获取,这里为了演示方便直接写出来了,另外需要注意的是JSON数据要加“[ ]”。

<script>
    // 注意要加[]  -- datalist可以通过ajax去后台查询数据库获取
    let datalist = JSON.parse("[{\n" +
        "            \"name\": \"武汉市\",\n" +
        "            \"code\": \"420100\",\n" +
        "            \"sub\": [\n" +
        "                {\n" +
        "                    \"name\": \"市辖区\",\n" +
        "                    \"code\": \"420101\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"江岸区\",\n" +
        "                    \"code\": \"420102\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"江汉区\",\n" +
        "                    \"code\": \"420103\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"硚口区\",\n" +
        "                    \"code\": \"420104\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"汉阳区\",\n" +
        "                    \"code\": \"420105\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"武昌区\",\n" +
        "                    \"code\": \"420106\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"青山区\",\n" +
        "                    \"code\": \"420107\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"洪山区\",\n" +
        "                    \"code\": \"420111\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"东西湖区\",\n" +
        "                    \"code\": \"420112\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"汉南区\",\n" +
        "                    \"code\": \"420113\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"蔡甸区\",\n" +
        "                    \"code\": \"420114\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"江夏区\",\n" +
        "                    \"code\": \"420115\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"黄陂区\",\n" +
        "                    \"code\": \"420116\",\n" +
        "                    \"sub\": []\n" +
        "                },\n" +
        "                {\n" +
        "                    \"name\": \"新洲区\",\n" +
        "                    \"code\": \"420117\",\n" +
        "                    \"sub\": []\n" +
        "                }\n" +
        "            ]\n" +
        "        }]");

    $("#home-city").cityPicker({
        title: "选择目的地",
        // showProvince: false,
        showDistrict: false,
        initDataList: datalist,
        onChange: function (picker, values, displayValues) {
            console.log(values, displayValues);
        }
    });

</script>

--- 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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值