1.Demo
2.修改源码
/* global $:true */ + function($) { "use strict"; var defaults; var selects = []; var Select = function(input, config) { var self = this; this.config = config; //init empty data this.data = { values: '', titles: '', origins: [], length: 0 }; this.$input = $(input); if(config.readOnly != false ){ this.$input.prop("readOnly", true); } this.initConfig(); config = this.config; this.$input.click($.proxy(this.open, this)); selects.push(this) } Select.prototype.initConfig = function() { this.config = $.extend({}, defaults, this.config); var config = this.config; if(!config.items || !config.items.length) return; config.items = config.items.map(function(d, i) { if(typeof d == typeof "a") { return { title: d, value: d }; } return d; }); this.tpl = $.t7.compile("<div app_gn='select' style='min-height:300px !important;' class='weui-picker-modal weui-select-modal'>" + config.toolbarTemplate + (config.search?config.searchTemplate:"") + (config.multi ? config.checkboxTemplate : config.radioTemplate) + "</div>"); if(config.input !== undefined) this.$input.val(config.input); this.parseInitValue(); this._init = true; } Select.prototype.updateInputValue = function(values, titles) { var v, t; if(this.config.multi) { v = values.join(this.config.split); t = titles.join(this.config.split); } else { v = values[0]; t = titles[0]; } //caculate origin data var origins = []; this.config.items.forEach(function(d) { values.each(function(i, dd) { if(d.value == dd) origins.push(d); }); }); this.$input.val(t).data("values", v); this.$input.attr("value", t).attr("data-values", v); var data = { values: v, titles: t, valuesArray: values, titlesArray: titles, origins: origins, length: origins.length }; this.data = data; this.$input.trigger("change", data); this.config.onChange && this.config.onChange.call(this, data); } Select.prototype.parseInitValue = function() { var value = this.$input.val(); var items = this.config.items; //如果input为空,只有在第一次初始化的时候才保留默认选择。因为后来就是用户自己取消了全部选择,不能再为他选中默认值。 if( !this._init && (value === undefined || value == null || value === "")) return; var titles = this.config.multi ? value.split(this.config.split) : [value]; for(var i=0;i<items.length;i++) { items[i].checked = false; for(var j=0;j<titles.length;j++) { if(items[i].title === titles[j]) { items[i].checked = true; } } } } Select.prototype._bind = function(dialog) { var self = this, config = this.config; dialog.on("change", function(e) { var checked = dialog.find("input:checked"); var values = checked.map(function() { return $(this).val(); }); var titles = checked.map(function() { return $(this).data("title"); }); self.updateInputValue(values, titles); if(config.autoClose && !config.multi) self.close(); }) .trigger('change') .on("click", ".close-select", function() { self.close(); }); } //更新数据 Select.prototype.update = function(config) { this.config = $.extend({}, this.config, config); this.initConfig(); if(this._open) { this._bind($.updatePicker(this.getHTML())); } } Select.prototype.open = function(values, titles) { if(this._open) return; // open picker 会默认关掉其他的,但是 onClose 不会被调用,所以这里先关掉其他select for (var i = 0; i < selects.length; i++ ) { var s = selects[i]; if (s === this) continue; if (s._open) { if(!s.close()) return false; // 其他的select由于某些条件限制关闭失败。 } } this.parseInitValue(); var config = this.config; var dialog = this.dialog = $.openPicker(this.getHTML()); this._bind(dialog); this._open = true; if(config.onOpen) config.onOpen(this); } Select.prototype.close = function(callback, force) { if (!this._open) return false; var self = this, beforeClose = this.config.beforeClose; if(typeof callback === typeof true) { force === callback; } if(!force) { if(beforeClose && typeof beforeClose === 'function' && beforeClose.call(this, this.data.values, this.data.titles) === false) { return false } if(this.config.multi) { if(this.config.min !== undefined && this.data.length < this.config.min) { $.toast("请至少选择"+this.config.min+"个", "text"); return false } if(this.config.max !== undefined && this.data.length > this.config.max) { $.toast("最多只能选择"+this.config.max+"个", "text"); return false } } } $.closePicker(function() { self.onClose(); callback && callback(); }); return true } Select.prototype.onClose = function() { this._open = false; if(this.config.onClose) this.config.onClose(this); } Select.prototype.getHTML = function(callback) { var config = this.config; return this.tpl({ items: config.items, title: config.title, closeText: config.closeText }) } $.fn.select = function(params, args) { return this.each(function() { var $this = $(this); if(!$this.data("weui-select")) $this.data("weui-select", new Select(this, params)); var select = $this.data("weui-select"); if(typeof params === typeof "a") select[params].call(select, args); return select; }); } defaults = $.fn.select.prototype.defaults = { items: [], input: undefined, //输入框的初始值 title: "请选择", multi: false, closeText: "确定", autoClose: true, //是否选择完成后自动关闭,只有单选模式下才有效 onChange: undefined, //function beforeClose: undefined, // function 关闭之前,如果返回false则阻止关闭 onClose: undefined, //function onOpen: undefined, //function split: ",", //多选模式下的分隔符 min: undefined, //多选模式下可用,最少选择数 max: undefined, //单选模式下可用,最多选择数 search: false, // 搜索,默认 不开启 readOnly:true, // 只读 // 标题 toolbarTemplate: '<div class="toolbar"> <div class="toolbar-inner"> <a href="javascript:;" class="picker-button close-select">{{closeText}}</a> <h1 class="title">{{title}}</h1> </div> </div>', searchTemplate: '<div class="weui-search-bar"> <form class="weui-search-bar__form"> <div class="weui-search-bar__box"> <i class="weui-icon-search"></i> <input type="search" class="weui-search-bar__input" id="select_search_input" placeholder="搜索" required=""> <a href="javascript:" class="weui-icon-clear" id="select_search_clear"></a> </div> <label class="weui-search-bar__label"> <i class="weui-icon-search"></i> <span>搜索</span> </label> </form> <a href="javascript:" class="weui-search-bar__cancel-btn" id="select_search_cancel">取消</a> </div>', radioTemplate: '<div app_gn="cells" class="weui-cells weui-cells_radio"> {{#items}} <label app_gn="cell" class="weui-cell weui-check_label" for="weui-select-id-{{this.title}}"> <div class="weui-cell__bd weui-cell_primary"> <p>{{this.title}}</p> </div> <div class="weui-cell__ft"> <input type="radio" class="weui-check" name="weui-select" id="weui-select-id-{{this.title}}" value="{{this.value}}" {{#if this.checked}}checked="checked"{{/if}} data-title="{{this.title}}"> <span class="weui-icon-checked"></span> </div> </label> {{/items}} </div>', checkboxTemplate: '<div app_gn="cells" class="weui-cells weui-cells_checkbox"> {{#items}} <label app_gn="cell" class="weui-cell weui-check_label" for="weui-select-id-{{this.title}}"> <div class="weui-cell__bd weui-cell_primary"> <p>{{this.title}}</p> </div> <div class="weui-cell__ft"> <input type="checkbox" class="weui-check" name="weui-select" id="weui-select-id-{{this.title}}" value="{{this.value}}" {{#if this.checked}}checked="checked"{{/if}} data-title="{{this.title}}" > <span class="weui-icon-checked"></span> </div> </label> {{/items}} </div>', } }($); // 给 搜索框添加输监听事件 $(document).on('input',"#select_search_input", function(){ select_search_weui(this) ; }).on('click','#select_search_clear,#select_search_cancel',function(){ select_search_weui(this) ; }) ; function select_search_weui(obj){ var body = $(obj).closest("div[app_gn='select']") ; var search_val = $(obj).val().trim() ; var cells = $(body).find("label[app_gn='cell']") ; for(var i=0,len=cells.length;i<len;i++){ var text = $(cells[i]).text().trim() ; if(text.indexOf(search_val) > -1 ){ $(cells[i]).css("display","") ; }else{ $(cells[i]).css("display","none") ; } } }