项目中用到了searchable插件,但遇见一个问题,这个插件貌似在初始化完成后,就不能动态去修改、删除选择项了....
所以为解决可以动态改变选择项,在插件功能基础上,添加了一个reload方法:
(function($){
//插件代码.....以上省略
$.fn.searchableSelect = function(options){
this.each(function(){
var sS = new $sS($(this), options);
});
return this;
};
//在插件最下边添加
$.fn.reload = function (options) {
$(this).next('.searchable-select').remove();
this.each(function(){
var sS = new $sS($(this), options);
});
}
})(jQuery);
后看底层,在初始化插件时,会在select 标签位置插入一个class为searchable-select的标签,重新加载的操作就是删除这个DIV,重新根据select生成。
最后,如果想动态修改项,就可以先修改select项,然后调用reload()。
实例:
<select> <option value="jQuery插件库">jQuery插件库</option> <option value="BlackBerry">BlackBerry</option> <option value="device">device</option> <option value="with">with</option> <option value="entertainment">entertainment</option> <option value="13">and</option> <option value="social">social</option> <option value="networking">networking</option> <option value="apps">apps</option> <option value="or">or</option> <option value="apps">apps</option> <option value="that">that</option> <option value="will">will</option> <option value="boost">boost</option> <option value="your">your</option> <option value="productivity">productivity</option> <option value="Download">Download</option> <option value="or">or</option> <option value="buy">buy</option> <option value="apps">apps</option> <option value="from">from</option> <option value="Afbb">Afbb</option> <option value="Akademie">Akademie</option> <option value="Berlin">Berlin</option> <option value="reviews">reviews</option> <option value="by">by</option> <option value="real">real</option> </select> <script> function reloadSelect() { $('select').html('<option value="1">A</option><option value="2">B</option><option value="3">C</option>'); $('select').reload();//重新根据select初始化 } $(function(){ $('select').searchableSelect(); });
</script>
这是从网站上找到的一个例子,在这个例子基础上添加了reload方法,在插件内添加reload函数后,就可以通过JQuery对象直接调用.
当调用reoad()方法时,插件重新根据select重建。
最后附上修改后插件,全部代码,仅在文件末尾修改:
// Author: David Qin // E-mail: david@hereapp.cn // Date: 2014-11-05 (function($){ // a case insensitive jQuery :contains selector $.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) { return function( elem ) { return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); $.searchableSelect = function(element, options) { this.element = element; this.options = options || {}; this.init(); var _this = this; this.searchableElement.click(function(event){ // event.stopPropagation(); _this.show(); }).on('keydown', function(event){ if (event.which === 13 || event.which === 40 || event.which == 38){ event.preventDefault(); _this.show(); } }); $(document).on('click', null, function(event){ if(_this.searchableElement.has($(event.target)).length === 0) _this.hide(); }); this.input.on('keydown', function(event){ event.stopPropagation(); if(event.which === 13){ //enter event.preventDefault(); _this.selectCurrentHoverItem(); _this.hide(); } else if (event.which == 27) { //ese _this.hide(); } else if (event.which == 40) { //down _this.hoverNextItem(); } else if (event.which == 38) { //up _this.hoverPreviousItem(); } }).on('keyup', function(event){ if(event.which != 13 && event.which != 27 && event.which != 38 && event.which != 40) _this.filter(); }) } var $sS = $.searchableSelect; $sS.fn = $sS.prototype = { version: '0.0.1' }; $sS.fn.extend = $sS.extend = $.extend; $sS.fn.extend({ init: function(){ var _this = this; this.element.hide(); this.searchableElement = $('<div tabindex="0" class="searchable-select"></div>'); this.holder = $('<div class="searchable-select-holder"></div>'); this.dropdown = $('<div class="searchable-select-dropdown searchable-select-hide"></div>'); this.input = $('<input type="text" class="searchable-select-input" />'); this.items = $('<div class="searchable-select-items"></div>'); this.caret = $('<span class="searchable-select-caret"></span>'); this.scrollPart = $('<div class="searchable-scroll"></div>'); this.hasPrivious = $('<div class="searchable-has-privious">...</div>'); this.hasNext = $('<div class="searchable-has-next">...</div>'); this.hasNext.on('mouseenter', function(){ _this.hasNextTimer = null; var f = function(){ var scrollTop = _this.items.scrollTop(); _this.items.scrollTop(scrollTop + 20); _this.hasNextTimer = setTimeout(f, 50); } f(); }).on('mouseleave', function(event) { clearTimeout(_this.hasNextTimer); }); this.hasPrivious.on('mouseenter', function(){ _this.hasPriviousTimer = null; var f = function(){ var scrollTop = _this.items.scrollTop(); _this.items.scrollTop(scrollTop - 20); _this.hasPriviousTimer = setTimeout(f, 50); } f(); }).on('mouseleave', function(event) { clearTimeout(_this.hasPriviousTimer); }); this.dropdown.append(this.input); this.dropdown.append(this.scrollPart); this.scrollPart.append(this.hasPrivious); this.scrollPart.append(this.items); this.scrollPart.append(this.hasNext); this.searchableElement.append(this.caret); this.searchableElement.append(this.holder); this.searchableElement.append(this.dropdown); this.element.after(this.searchableElement); this.buildItems(); this.setPriviousAndNextVisibility(); }, filter: function(){ var text = this.input.val(); this.items.find('.searchable-select-item').addClass('searchable-select-hide'); this.items.find('.searchable-select-item:searchableSelectContains('+text+')').removeClass('searchable-select-hide'); if(this.currentSelectedItem.hasClass('searchable-select-hide') && this.items.find('.searchable-select-item:not(.searchable-select-hide)').length > 0){ this.hoverFirstNotHideItem(); } this.setPriviousAndNextVisibility(); }, hoverFirstNotHideItem: function(){ this.hoverItem(this.items.find('.searchable-select-item:not(.searchable-select-hide)').first()); }, selectCurrentHoverItem: function(){ if(!this.currentHoverItem.hasClass('searchable-select-hide')) this.selectItem(this.currentHoverItem); }, hoverPreviousItem: function(){ if(!this.hasCurrentHoverItem()) this.hoverFirstNotHideItem(); else{ var prevItem = this.currentHoverItem.prevAll('.searchable-select-item:not(.searchable-select-hide):first') if(prevItem.length > 0) this.hoverItem(prevItem); } }, hoverNextItem: function(){ if(!this.hasCurrentHoverItem()) this.hoverFirstNotHideItem(); else{ var nextItem = this.currentHoverItem.nextAll('.searchable-select-item:not(.searchable-select-hide):first') if(nextItem.length > 0) this.hoverItem(nextItem); } }, buildItems: function(){ var _this = this; this.element.find('option').each(function(){ var item = $('<div class="searchable-select-item" data-value="'+$(this).attr('value')+'">'+$(this).text()+'</div>'); if(this.selected){ _this.selectItem(item); _this.hoverItem(item); } item.on('mouseenter', function(){ $(this).addClass('hover'); }).on('mouseleave', function(){ $(this).removeClass('hover'); }).click(function(event){ event.stopPropagation(); _this.selectItem($(this)); _this.hide(); }); _this.items.append(item); }); this.items.on('scroll', function(){ _this.setPriviousAndNextVisibility(); }) }, show: function(){ this.dropdown.removeClass('searchable-select-hide'); this.input.focus(); this.status = 'show'; this.setPriviousAndNextVisibility(); }, hide: function(){ if(!(this.status === 'show')) return; if(this.items.find(':not(.searchable-select-hide)').length === 0) this.input.val(''); this.dropdown.addClass('searchable-select-hide'); this.searchableElement.trigger('focus'); this.status = 'hide'; }, hasCurrentSelectedItem: function(){ return this.currentSelectedItem && this.currentSelectedItem.length > 0; }, selectItem: function(item){ if(this.hasCurrentSelectedItem()) this.currentSelectedItem.removeClass('selected'); this.currentSelectedItem = item; item.addClass('selected'); this.hoverItem(item); this.holder.text(item.text()); var value = item.data('value'); this.holder.data('value', value); this.element.val(value); if(this.options.afterSelectItem){ this.options.afterSelectItem.apply(this); } }, hasCurrentHoverItem: function(){ return this.currentHoverItem && this.currentHoverItem.length > 0; }, hoverItem: function(item){ if(this.hasCurrentHoverItem()) this.currentHoverItem.removeClass('hover'); if(item.outerHeight() + item.position().top > this.items.height()) this.items.scrollTop(this.items.scrollTop() + item.outerHeight() + item.position().top - this.items.height()); else if(item.position().top < 0) this.items.scrollTop(this.items.scrollTop() + item.position().top); this.currentHoverItem = item; item.addClass('hover'); }, setPriviousAndNextVisibility: function(){ if(this.items.scrollTop() === 0){ this.hasPrivious.addClass('searchable-select-hide'); this.scrollPart.removeClass('has-privious'); } else { this.hasPrivious.removeClass('searchable-select-hide'); this.scrollPart.addClass('has-privious'); } if(this.items.scrollTop() + this.items.innerHeight() >= this.items[0].scrollHeight){ this.hasNext.addClass('searchable-select-hide'); this.scrollPart.removeClass('has-next'); } else { this.hasNext.removeClass('searchable-select-hide'); this.scrollPart.addClass('has-next'); } } }); $.fn.searchableSelect = function(options){ this.each(function(){ var sS = new $sS($(this), options); }); return this; };
$.fn.reload = function (options) {
$(this).next('.searchable-select').remove();
this.each(function(){
var sS = new $sS($(this), options);
});
}
})(jQuery);