1. 程式人生 > >Jquery weui picker 支援label和value

Jquery weui picker 支援label和value

萬年沒更新了. 最近用jquery weui. 在使用picker時需要一些問題.

就是讓picker 顯示label, 但是取值的時候取value用於儲存. 官網例子如下

Jquery-weui 官網 : 點這裡  寫這篇文章時,用的版本是1.2.1版本

$("#picker-name").picker({
  title: "請選擇您的稱呼",
  cols: [
    {
      textAlign: 'center',
      values: ['趙', '錢', '孫', '李', '周', '吳', '鄭', '王']
      
//如果你希望顯示文案和實際值不同,可以在這裡加一個displayValues: [.....] }, { textAlign: 'center', values: ['杰倫', '磊', '明', '小鵬', '燕姿', '菲菲', 'Baby'] }, { textAlign: 'center', values: ['先生', '小姐'] } ] });

但是文字框中顯示的依然是value !!!!!

於是只能想其他辦法. 在onChange中將value儲存到 data-values中. 效果就達到了.

 

但是!!!!!

介面操作是沒問題了,接著其他問題就來了.

當從資料庫查出來時, 介面依然是顯示 value, 因為資料庫存的就是value.

我試圖在取出資料後改變文字框的值. 看起來正常了. 

$.ajax ({
    ...
    success: function(){
         $("#input").val(值的Text)
    }
})

還是但是!!!

 

有2個問題

1、你在執行 $("#input").val(值) 時未必已經能加載出picker的資料來源了.  所以你不一定能通過value拿到text去顯示

2、就算你先拿出了picker的資料來源, 再去載入資料庫的值設定. 看上去是沒問題了. 但是當你點選的時候..並不會預設指向你的值, 還會把你的值改成第一項。。。

      (關於第二點,  查了下,好像是說picker是在開啟過後才初始化內部的內容, 試了下以下程式碼可行  )

    

$("#input").picker("open");
$("#input").picker("setValue", [由值算出的文字]);
$("#input").picker("close");

  以上程式碼確實可行了, 但是當你onChange裡處理其他邏輯時就頭疼了...因為這幾句程式碼麼會觸發onChange事件. 

  舉例子:  picker 選擇性別  . 男的身高預設170,  囡的身高預設160,  

  所以你需要在onChange裡去更新身高的文字框, 這時使用者改了身高為175儲存.  

  當你從資料庫取出來用以上程式碼設定性別時, 會觸發onChange事件又把身高改成170了.

 

最終辦法:

結合以上問題得出思路:

1、二次封裝picker

2、在每次值發生改變時, 將label設定到文字框,  value設定到 data-values

3、提供setValue(v) 方法. 此方法即使資料來源沒加載出來依然會記錄下value, 等到資料來源加載出來了會取value出來更新作為預設的值

4、提供setDataSource(data) 方法, 此方法呼叫時將已儲存設定的值拿出來重算一次label顯示.

5、提供getValue() 獲取值

 

注意: picker初始化後再設定文字框的值不會更新picker的值, 因此點選彈出時不會定位到預設值, 這裡的解決辦法是 destroy後重新初始化.

 

不說了,累了幾天了頭腦很亂也不知道寫得看不看得懂.  直接上外掛程式碼.

 

/* 二次封裝weui的picker, 主要是目前的picker不支援text和value的方式使用,所以封裝一下,同時讓他支援非同步載入資料 */
/*
* title             picker的標題. 跟picker一樣
* value             當前值
* data              資料來源, 物件集合,  物件必須包含 label 和 value 屬性.
* allowEmpty        是否追加空白資料, 預設為true並追加空白資料
* onChange          選項變更事件, 不同於原picker的是多了第2個引數, 第二個引數為當前所有選項列表. 且僅當選項改變才觸發 (原picker只要點選就會觸發)
*                   
* 例子:             var picker = $("#selector").pickerPlus({}).data("pickerPlus");
* 
* 可使用方法:         
* picker.setValue(value)    設定值, 傳入的picker必須為資料物件的 value, 支援預設定. 即在資料來源未載入完成前設定. (原picker一旦設定資料來源, 無法再修改值, 除非open, setValue, close)
* picker.setDataSource(data)設定資料來源
* picker.getValue()         獲取值.  注意.原$("#selector").val()拿到的是label,需要用此方法獲取值. 或者$("#selector").attr("data-values")獲取值
*/

(function ($) {
    var defaultSettings = {
        title: '',
        data: [],
        value: '',
        allowEmpty: true,
        onChange: function () { }
    };

    $.fn.pickerPlus = function (settings) {
        return this.each(function () {
            var elem = $(this);
            elem.data('pickerPlus', new P(elem, settings));
        });
    }

    function P(elem, settings) {
        this.elem = elem;
        this.picker = null;
        this.settings = $.extend({}, defaultSettings, settings || {});
        this.init();
        return this;
    }

    P.prototype = {
        init: function () {
            let that = this,
                elem = that.elem,
                setting = that.settings;

            if (setting.allowEmpty && !setting.data.find(x => x.value == "")) {
                setting.data.splice(0, 0, { label: '', value: '' })
            }

            let obj = setting.data.find(x => x.value == setting.value);
            if (obj) {
                elem.val(obj.label);
            }
            elem.attr("data-values", setting.value);

            that.picker && that.picker.destroy();

            elem.picker({
                title: setting.title,
                cols: [
                    {
                        textAlign: 'center',
                        values: setting.data.map(x => x.label)
                    }
                ],
                onChange: function (e) {
                    let oldValue = that.settings.value;
                    let newValue = that.settings.data.find(x => x.label == e.value[0]).value;

                    that.settings.value = newValue;
                    if (oldValue != newValue)
                        setting.onChange && setting.onChange(e, setting.data);
                }
            });

            that.picker = that.elem.data('picker');
        },
        setDataSource: function (data) {
            let that = this,
                elem = that.elem,
                setting = that.settings;

            that.settings.data = data;
            that.init();
            return this;
        },
        setValue: function (key) {
            let that = this,
                elem = that.elem,
                setting = that.settings;
            
            that.settings.value = key;

            that.init();
            return this;
        },
        getValue: function () {
            return this.settings.value || '';
        }
    }

})(jQuery);
View Code

 

使用方式

1、引入

2、介面初始化時var picker = $("#input"),pickerPlus( {  選項 } ).data("pickerPlus");  

3、賦值時picker.setValue("value")

4、設定資料來源時 picker.setDataSouce(data)  格式為陣列物件 [{ label: '內容', value: '值' }]

4、獲取值時picker.getValue()

 

這樣一來,無需再關心是不是要等資料來源先載入還是先設定文字框值的問題了.

 

外掛寫的很匆忙很亂,暫時沒時間優化. 另外如果有其他更好的方案也可以告訴我。謝謝