自定義mui 搜索列表插件 picker-search

目錄

一.說明

二.上代碼

1.html

2.css

3.js


一.說明

mui的picker插件功能不滿足當前需求,在picker的基礎上新做個插件,帶有搜索功能。

實現可以 實時搜索,實時改變列表選項。

新建myMuiSearchPicker.js 和 myMuiSearchPicker.css

筆記:

1.關於選項條高度,在第一遍初始化時,高度是組件默認高度。

    在mui.picker.js中設置的

在自定義組件中,設置選項條。

在設置完數據後,要再一次初始化,並重新計算項目位置。這裏計算項目位置不要傳true

2.組件位置

     通過設置top,top是定值

     top = 屏幕高 - 組件高

3.組件的滾動顯示高度

二.上代碼

1.html

引用 mui.js/css 和 mui.picker.js/css   或者用min版的

var searchPicker = new mui.SearchPicker({
    title:"位置選擇",
    placeholder:"搜索位置",
    data:[{ value: "", 
            text: "未選擇" 
         },{
           value: "first",
           text: "第一項"
         }, {
          value: "second",
          text: "第二項"
         }, {
          value: "third",
          text: "第三項"
         }]
});

2.css

.searchPicker{
    bottom:-400px !important;
    background-color: #fff;
    border-top: 0;
    border-top-left-radius: 14px;
    border-top-right-radius: 14px;
    z-index:99999 !important;
}
.searchPicker.mui-active{
   /* bottom:0 !important;*/
   /* top: calc( 100% - 428px) !important;*/
}
.searchPicker .mui-poppicker-header{
    padding:0 6px !important;
}
.searchPicker .mui-poppicker-btn-ok{
    float:right;
    margin:9px 7px;
    border: 1px solid rgba(254,45,76,1) !important;
    background-color: rgba(254,45,76,1) !important;
}
.searchBtnCancel{
    float:right;
    font-size: 20px !important;
    margin: 13px 5px;
    padding: 0 !important;
    line-height: 0;
    border-radius: 20px;
}
.searchPicker .mui-poppicker-body{
    height:380px;
    border-top:0 !important;
    overflow-y:hidden;
}
.searchPicker .mui-picker{
    height:560px !important;
}
.searchPicker .mui-search{
    width:90%;
    margin-left: auto;
    margin-right: auto;
}
.searchPicker .mui-placeholder{
    text-align: left !important;
    padding-left:10px;
}
.searchPicker .pickerTitle{
    display:inline-block;
    position:absolute;
    width:100%;
    height:46px;
    line-height:46px;
    font-size: 16px;
    text-align: center;
    color:#0C0C0C;
    font-weight: 600;
}
.searchPicker .mui-picker-inner{
    -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, #fff 10%, #fff 93%, transparent 95%, transparent);
}
.searchPicker .mui-pciker-list,.searchPicker .mui-pciker-rule{
    top:10% !important;
    height:40px !important;
}
.searchPicker .mui-pciker-rule-ft {
    border-top: solid 1px rgba(254,45,76,1) !important;
    border-bottom: solid 1px rgba(254,45,76,1) !important;
}
.searchPicker .mui-pciker-list{
    height:40px !important;
    line-height:40px;
}

3.js

/**
 * 彈出選擇列表插件
 * 此組件依賴 listpcker ,請在頁面中先引入 mui.picker.css + mui.picker.js
 * varstion 1.0.0
 * by Liyuqi
 */

(function($, document) {

    $.dom = function(str) {
        if (typeof(str) !== 'string') {
            if ((str instanceof Array) || (str[0] && str.length)) {    //如果是數組
                return [].slice.call(str);
            } else {
                return [str];
            }
        }
        if (!$.__create_dom_div__) {
            $.__create_dom_div__ = document.createElement('div');
        }
        $.__create_dom_div__.innerHTML = str;
        return [].slice.call($.__create_dom_div__.childNodes);  //返回創建div的子節點
    };

    var panelBuffer = '<div class="mui-poppicker searchPicker">\
      <div class="mui-poppicker-header">\
          <div class="pickerTitle"></div>\
         <button class="mui-btn searchBtnCancel"><span class="mui-icon mui-icon-closeempty"></span></button>\
         <button class="mui-btn mui-btn-blue mui-poppicker-btn-ok">確定選擇</button>\
         <div class="mui-poppicker-clear"></div>\
      </div>\
      <div class="mui-poppicker-body">\
            <div class="mui-input-row mui-search" style="text-align: left">\
               <input type="search" class="mui-input-clear"  class=placeholder="">\
            </div>\
        </div>\
      </div>';

    var pickerBuffer = '<div class="mui-picker">\
      <div class="mui-picker-inner">\
         <div class="mui-pciker-rule mui-pciker-rule-ft"></div>\
         <ul class="mui-pciker-list">\
         </ul>\
         <div class="mui-pciker-rule mui-pciker-rule-bg"></div>\
      </div>\
   </div>';

    //定義彈出選擇器類
    var SearchPicker = $.SearchPicker = $.Class.extend({
        //構造函數
        init: function(options) {
            var self = this;
            self.options = options || {};
            self.options.title= options.title||'';
            self.options.placeholder= options.placeholder||'';
            self.options.data= options.data||[];
            /*self.options.buttons = self.options.buttons || ['x', '確定'];*/
            self.panel = $.dom(panelBuffer)[0];
            document.body.appendChild(self.panel);
            self.title=self.panel.querySelector('.pickerTitle');
            self.ok = self.panel.querySelector('.mui-poppicker-btn-ok');
            self.cancel = self.panel.querySelector('.searchBtnCancel');
            self.body = self.panel.querySelector('.mui-poppicker-body');
            self.input = self.panel.querySelector('input[type="search"]');
            $('.mui-input-row input').input();
            self.spanPlaceholder = self.body.querySelector('.mui-placeholder span:last-child');
            self.spanPlaceholder.textContent='';
            /*self.searchClean= self.panel.querySelector('mui-icon-clear');*/
            self.mask = $.createMask();
            self.title.innerText=self.options.title;
            self.input.placeholder=self.options.placeholder;
            self.top = (document.body.clientHeight - 428)+"px";
            /*self.cancel.innerText = self.options.buttons[0];*/
            /*  self.ok.innerText = self.options.buttons[1];*/
            self.cancel.addEventListener('tap', function(event) {
                self.hide();
            }, false);
            self.ok.addEventListener('tap', function(event) {
                if (self.callback) {
                    var rs = self.callback(self.getSelectedItems());
                    if (rs !== false) {
                        self.hide();
                    }
                }
                self.setData(self.options.data);
                self.body.querySelector(".mui-input-row").classList.remove("mui-active");
                self.input.blur();
            }, false);
            self.body.querySelector('.mui-placeholder').addEventListener('tap',function(e){
                self.body.querySelector(".mui-input-row").classList.add("mui-active");
                self.input.focus();
            },false);
            self.input.addEventListener('tap',function(e){
                self.body.querySelector(".mui-input-row").classList.add("mui-active");
                self.input.blur();
                self.input.focus();
            },false);
            self.input.addEventListener('focus',function(){
                self.panel.style.top = self.top;
            });
            self.input.addEventListener('input', function() {
                self.panel.style.top = self.top;
                self.searchClean= self.input.nextSibling;
                self.searchClean.addEventListener('tap',sc,false);
                var filter = this.value;
                var filterList= [];
                if (filter) {
                    for(var i=0; i<self.options.data.length;i++){
                        if(self.options.data[i].text.search(filter)!= -1){
                            filterList.push(self.options.data[i]);
                        }
                    }
                    self.setData(filterList);
                } else {
                    self.setData(self.options.data);
                }
                self.pickers[0].setSelectedIndex(0, 1000);

            },false);

            self.input.addEventListener("keydown",function(e){
                if(e.keyCode==13||e.key=="Enter"){
                    self.body.querySelector(".mui-input-row").classList.remove("mui-active");
                    self.input.blur();
                }
            },false);

            function sc(){
                if(!self.searchClean.value){
                    self.setData(self.options.data);
                }
                self.searchClean.removeEventListener('tap',sc,false);
            }
            self.mask[0].addEventListener('tap', function() {
                self.hide();
            }, false);
            self._createPicker();
            //防止滾動穿透
            self.panel.addEventListener($.EVENT_START, function(event) {
                event.preventDefault();
            }, false);
            self.panel.addEventListener($.EVENT_MOVE, function(event) {
                event.preventDefault();
            }, false);
            if(self.options.data){
                self.setData(self.options.data);
            }
        },
        _createPicker: function() {
            var self = this;
            var layer = self.options.layer || 1;
            var width = (100 / layer) + '%';
            self.pickers = [];
            for (var i = 1; i <= layer; i++) {
                var pickerElement = $.dom(pickerBuffer)[0];
                pickerElement.style.width = width;
                self.body.appendChild(pickerElement);
                var picker = $(pickerElement).picker();
                self.pickers.push(picker);
                pickerElement.addEventListener('change', function(event) {
                    var nextPickerElement = this.nextSibling;
                    if (nextPickerElement && nextPickerElement.picker) {
                        var eventData = event.detail || {};
                        var preItem = eventData.item || {};
                        nextPickerElement.picker.setItems(preItem.children);
                    }
                }, false);
                pickerElement.addEventListener('touchstart',function(e){
                    self.body.querySelector(".mui-input-row").classList.remove("mui-active");
                    self.input.blur();
                },false);
                pickerElement.querySelector(".mui-pciker-rule-ft").addEventListener('tap',function(event) {
                    if (self.callback) {
                        var rs = self.callback(self.getSelectedItems());
                        if (rs !== false) {
                            self.hide();
                        }
                    }
                    self.setData(self.options.data);
                    self.body.querySelector(".mui-input-row").classList.remove("mui-active");
                    self.input.blur();
                }, false)
            }
        },
        //填充數據
        setData: function(data) {
            var self = this;
            data = data || [];
            self.pickers[0].setItems(data);
            self.pickers[0].init();
            self.pickers[0].calcElementItemPostion();
        },
        //獲取選中的項(數組)
        getSelectedItems: function() {
            var self = this;
            var items = [];
            for (var i in self.pickers) {
                if(self.pickers.hasOwnProperty(i)) { // 修復for in會訪問繼承屬性造成items報錯情況
                    var picker = self.pickers[i];
                    items.push(picker.getSelectedItem() || {});
                }
            }
            return items;
        },
        //顯示
        show: function(callback) {
            var self = this;
            self.callback = callback;
            self.mask.show();
            document.body.classList.add($.className('poppicker-active-for-page'));
            self.panel.classList.add($.className('active'));
            //處理物理返回鍵
            self.__back = $.back;
            $.back = function() {
                self.hide();
            };
            setTimeout(function () {
                self.panel.style.top = (document.body.clientHeight - 428) + "px";
            },0);

        },
        //隱藏
        hide: function() {
            var self = this;
            self.panel.style.top = document.body.clientHeight+"px";
            if (self.disposed) return;
            self.panel.classList.remove($.className('active'));
            self.body.querySelector('.mui-search').classList.remove($.className('active'));
            self.input.value='';
            self.mask.close();
            document.body.classList.remove($.className('poppicker-active-for-page'));
            //處理物理返回鍵
            $.back=self.__back;
            if(self.options.data){
                self.setData(self.options.data);
            }
        },
        dispose: function() {
            var self = this;
            self.hide();
            setTimeout(function() {
                self.panel.parentNode.removeChild(self.panel);
                for (var name in self) {
                    self[name] = null;
                    delete self[name];
                }
                self.disposed = true;
            }, 300);
        }
    });

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