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

 參考https://blog.csdn.net/weixin_41913378/article/details/103175157

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章