新文章 网摘 文章 随笔 日记

可搜索下拉列表


(function ($) {

    //jQuery1.8.1以上版本使用
    // a case insensitive jQuery :contains selector
    /*$.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) {
      return function( elem ) {
        return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
      };
    });*/

    $.expr[":"].searchableSelectContains = function (obj, index, meta) {
        return $(obj).text().toUpperCase().indexOf(meta[3].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();
        });

        return this;
    }

    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.searchableElement.css('max-width', this.element.css('width'));
this.searchableElement.css('width', '100%'); this.element.after(this.searchableElement); this.buildItems(); this.setPriviousAndNextVisibility(); //自己添加的方法,当下拉列表值改变时 this.element.change(function (e) { e.preventDefault(); e.stopPropagation(); // 阻止事件冒泡 var value = $(e.currentTarget).val(); _this.selectItemByValue(value); }); }, filter: function () { var text = this.input.val(); this.items.find('.searchable-select-item').addClass('searchable-select-hide'); if (text != '') { this.items.find('.searchable-select-item:searchableSelectContains(' + text + ')').removeClass('searchable-select-hide'); } else { this.items.find('.searchable-select-item').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, false);//第一次初始化时不触发change事件 _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(); }); }, rebuildItems:function() { this.items.empty(); this.buildItems(); }, show: function () { this.dropdown.removeClass('searchable-select-hide'); this.input.focus(); this.status = 'show'; this.setPriviousAndNextVisibility(); this.dropdown.css('z-index', 100); //打开下拉列表时调高z-index层级 }, 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'; this.dropdown.css('z-index', 1); //关闭下拉列表时恢复z-index层级 }, hasCurrentSelectedItem: function () { return this.currentSelectedItem && this.currentSelectedItem.length > 0; }, selectItem: function (item, whetherTriggerChangeEvent) { if (this.hasCurrentSelectedItem()) this.currentSelectedItem.removeClass('selected'); debugger; 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); //自己添加的方法,只有显式指定不触发change事件,才会不触发,否则默认都是触发的 if (whetherTriggerChangeEvent == null || whetherTriggerChangeEvent == 'undefined') { this.element.change(); } else { if (whetherTriggerChangeEvent) { this.element.change(); } } if (this.options.afterSelectItem) { this.options.afterSelectItem.apply(this); } }, //自己添加的方法,根据值选定项目 selectItemByValue: function (value) { var item = this.items.find('[data-value="' + value + '"]'); this.selectItem(item, false); }, hasCurrentHoverItem: function () { return this.currentHoverItem && this.currentHoverItem.length > 0; }, hoverItem: function (item) { if (this.hasCurrentHoverItem()) this.currentHoverItem.removeClass('hover'); //这里item为null时有bug,所以加上校验 if (item != null && item != 'undefined' && item.length > 0) { 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); debugger; this.selectExtention = sS; }); return this; }; })(jQuery);

 





css文件:

.searchable-select-hide {
  display: none;
}
 
.searchable-select {
  display: inline-block;
  min-width: 130px;
  font-size: 14px;
  line-height: 1.428571429;
  color: #555;
  vertical-align: middle;
  position: relative;
  outline: none;  
}
 
.searchable-select-holder{
  padding: 2px;
  background-color: #fff;
  background-image: none;
  border: 1px solid #ccc;
  border-radius: 2px;
  min-height: 18px;
  box-sizing: border-box;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
  box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
  -webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
  transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}
 
.searchable-select-caret {
  position: absolute;
  width: 0;
  height: 0;
  box-sizing: border-box;
  border-color: black transparent transparent transparent;
  top: 0;
  bottom: 0;
  border-style: solid;
  border-width: 5px;
  margin: auto;
  right: 10px;
}
 
.searchable-select-dropdown {
  position: absolute;
  background-color: #fff;
  border: 1px solid #ccc;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
  padding: 4px;
  border-top: none;
  top: 28px;
  left: 0;
  right: 0;
}
 
.searchable-select-input {
  margin-top: 5px;
  border: 1px solid #ccc;
  outline: none;
  padding: 4px;
  width: 100%;
  box-sizing: border-box;
  width: 100%;
}
 
.searchable-scroll {
  margin-top: 4px;
  position: relative;
}
 
.searchable-scroll.has-privious {
  padding-top: 16px;
}
 
.searchable-scroll.has-next {
  padding-bottom: 16px;
}
 
.searchable-has-privious {
  top: 0;
}
 
.searchable-has-next {
  bottom: 0;
}
 
.searchable-has-privious, .searchable-has-next {
  height: 16px;
  left: 0;
  right: 0;
  position: absolute;
  text-align: center;
  z-index: 10;
  background-color: white;
  line-height: 8px;
  cursor: pointer;
}
 
.searchable-select-items {
  max-height: 400px;
  overflow-y: scroll;
  position: relative;
}
 
.searchable-select-items::-webkit-scrollbar {
  display: none;
}
 
.searchable-select-item {
  padding: 5px 5px;
  cursor: pointer;
  min-height: 30px;
  box-sizing: border-box;
    transition: all 1s ease 0s;
}
 
.searchable-select-item.hover {
 
  background: #555;
  color: white;
}
 
.searchable-select-item.selected {
  background: #28a4c9;
  color: white;
}

使用:

<select id='VendorCode'></select >

先在select 中填入可选项,然后:

  $('#VendorCode').searchableSelect();

 

如果联动生成下拉列表,则:

                getProcessDropDownListByPartId: function (partId) {
                    var url = '@Url.Action("GetProcessDropDownListByPartId")' + '?partId=' + partId;
                    $.get(url, function (result, status) {
                        if (status == 'success') {
                            result = new Result(result);
                            try {
                                if (result.status == 1) {
                                    //成功
                                    $('#PROCESS_ID').empty();
                                    $('#PROCESS_ID').val('');

                                    $('#PROCESS_ID').append('<option value="">-----</option>');
                                    for (var i = 0; i < result.data.length; i++) {
                                        $('#PROCESS_ID').append('<option value="' + result.data[i].Key + '">' + result.data[i].Value + '</option>');
                                    }

                                    //重构可搜索的下拉选项
                                    $("#PROCESS_ID")[0].selectExtention.rebuildItems();
                                } else {
                                    layer.msg(result.message);
                                }

                            } catch (err) {

                            }
                        } else {
                            try {
                                layer.msg("error:" + result.responseText);
                            } catch (err) {

                            }
                            warning();
                        }
                    });
                }
            };

 

posted @ 2020-10-14 08:42  岭南春  阅读(112)  评论(0)    收藏  举报