【web前端】可筛选[输入搜索]的select(重写)

【web前端】可筛选[输入搜索]的select(重写)
 ---  filterSelect.js

/**
 * 将Select转变为支持输入内容对Select的Option进行筛选的js
 * @author wanghq
 * @Date 2017年12月4日 18:38:29
 * var $select = $("select["+TriangleDefinition.HTML_DEF_ATTR_KEY_FILTER_SELECT+"]").filterSelect();
   $(selectDOMRouteProcess).filterSelectReloadOption();// 把selectDOMRouteProcess变为可filterSelect
 */

$(document).ready(function(){ 
// 这段代码,是遍历所有拥有 TriangleDefinition.HTML_DEF_ATTR_KEY_FILTER_SELECT 属性的元素,并把他们变为可编辑 
if($("select["+TriangleDefinition.HTML_DEF_ATTR_KEY_FILTER_SELECT+"]").length > 0){
$("select["+TriangleDefinition.HTML_DEF_ATTR_KEY_FILTER_SELECT+"]").filterSelect();
}
}); 

/**
 * 将Select转化为FilterSelect
 */
$.fn.filterSelect = (function(){
    return function(){
        var $body = $("body");
        this.each(function(i, v){
          if($(v).parent().is("div") && $(v).parent().attr("class") == "m-input-select"){
          return false;// 如果当前Select已经是FilterSelect,则退出.
          }
            var $sel = $(v);// 得到Select的DOM
            var $div = $('<div class="m-input-select" style="width:'+$sel.width()+'"></div>');//生成覆盖层的DIV,宽度等于原Select宽度
            var $input = $("<input type='text' class='m-input' />");
            // var $wrapper = $("<div class='m-list-wrapper'><ul class='m-list'></ul></div>");
            var $wrapper = $("<ul class='m-list'></ul>");
            $div = $sel.wrap($div).hide().addClass("m-select").parent();
            $div.append($input).append("<span class='m-input-ico'></span>").append($wrapper);

            // 遮罩层显示 + 隐藏
            var wrapper = {
                show: function(){
                    $wrapper.show();
                    this.$list = $wrapper.find(".m-list-item:visible");
                    this.setIndex(this.$list.filter(".m-list-item-active"));
                    this.setActive(this.index);
                },
                hide: function(){
                    $wrapper.hide();
                },
                next: function(){
                    return this.setActive(this.index + 1);
                },
                prev: function(){
                    return this.setActive(this.index - 1);
                },
                $list: $wrapper.find(".m-list-item"),
                index: 0,
                $cur: [],
                setActive: function(i){
                    // 找到第1个 li,并且赋值为 active
                    var $list = this.$list, size = $list.size();
                    if(size <= 0){
                        this.$cur = [];
                        return;
                    }
                    $list.filter(".m-list-item-active").removeClass("m-list-item-active");
                    if(i < 0){
                        i = 0;
                    }else if(i >= size){
                        i = size - 1;
                    }
                    this.index = i;
                    this.$cur = $list.eq(i).addClass("m-list-item-active");
                    this.fixScroll(this.$cur);
                    return this.$cur;
                },
                fixScroll: function($elem){
                    // console.log($wrapper);
                    var height = $wrapper.height(), top = $elem.position().top, eHeight = $elem.outerHeight();
                    var scroll = $wrapper.scrollTop();
                    // 因为 li 的 实际 top,应该要加上 滚上 的距离
                    top += scroll;
                    if(scroll > top){
                        $wrapper.scrollTop(top);
                    }else if(top + eHeight > scroll + height){
                        // $wrapper.scrollTop(top + height - eHeight);
                        $wrapper.scrollTop(top + eHeight - height);
                    }
                },
                setIndex: function($li){
                    if($li.size() > 0){
                        this.index = this.$list.index($li);
                        $li.addClass("m-list-item-active").siblings().removeClass("m-list-item-active");
                    }else{
                        this.index = 0;
                    }
                }
            };

            // input 的操作
            var operation = {
                // 文字更变了,更新 li, 最低效率的一种
                textChange: function(){
                    val = $.trim($input.val());
                    $wrapper.find(".m-list-item").each(function(i, v){
                        if(v.innerHTML.indexOf(val) >= 0){
                            $(v).show();
                        }else{
                            $(v).hide();
                        }
                    });
                    wrapper.show();
                },
                // 设值
                setValue: function($li){
                    if($li && $li.size() > 0){
                        var val = $.trim($li.html());
                        $input.val(val).attr("placeholder", val);
                        $input.attr("title", val);
                        wrapper.setIndex($li);
                        $sel.val($li.attr("data-value")).trigger("change");
                    }else{
                        $input.val(function(i, v){
                            return $input.attr("placeholder");
                        });
                    };
                    wrapper.hide();
                    this.offBody();
                },
                onBody: function(){
                    var self = this;
                    setTimeout(function(){
                        self.offBody();
                        $body.on("click", self.bodyClick);
                    }, 10);
                },
                offBody: function(){
                    $body.off("click", this.bodyClick);
                },
                bodyClick: function(e){
                    var target = e.target;
                    if(target != $input[0] && target != $wrapper[0]){
                        wrapper.hide();
                        operation.setValue();
                        operation.offBody();
                    }
                }
            };

            // 遍历 $sel 对象
            function resetOption(){
                var html = "", val = "", defVal = "";
                $sel.find("option").each(function(i, v){
                if(i == 0){
              defVal = v.text;
              }
                    if(v.selected){
                        val = v.text;
                    };
                    html += '<li class="m-list-item'+ (v.selected ? " m-list-item-active" : "") +'" data-value="'+ v.value +'" title="'+ v.text +'">'+ v.text +'</li>';
                });
                if(val.length == 0 ){
                 val = defVal;
                }
                $input.val(val);
                $input.attr("title", val);
                $input.attr("placeholder", val);
                $wrapper.html(html);
            };
            $sel.on("optionChange", resetOption).trigger("optionChange");
            $sel.on("setEditSelectValue", function(e, val){
                // console.log(val);
                var $all = $wrapper.find(".m-list-item"), $item;
                for(var i = 0, max = $all.size(); i < max; i++){
                    $item = $all.eq(i);
                    if($item.attr("data-value") == val){
                        operation.setValue($item);
                        return;
                    }
                }
            });

            // input 聚焦
            $input.on("focus", function(){
                this.value = "";
                operation.textChange();
                operation.onBody();
            }).on("input propertychange", function(e){
                operation.textChange();
            }).on("keydown", function(e){
                // 上 38, 下 40, enter 13
                switch(e.keyCode){
                    case 38:
                        wrapper.prev();
                        break;
                    case 40:
                        wrapper.next();
                        break;
                    case 13:
                        operation.setValue(wrapper.$cur);
                        break;
                }
            });

            $div.on("click", ".m-input-ico", function(){
                // 触发 focus 和 blur 事件
                // focus 是因为 input 有绑定
                // 而 blur,实际只是失去焦点而已,真正隐藏 wrapper 的是 $body 事件
                $wrapper.is(":visible") ? $input.blur() : ($input.val("").trigger("focus"));
            });

            // 选中
            $wrapper.on("click", ".m-list-item", function(){
                operation.setValue($(this));
                return false;
            });

            setTimeout(function(){
                // for ie
                wrapper.hide();
            }, 1)
        });
        return this;
    };
})();

/**
 * 更新当前FilterSelect的Option
 */
$.fn.filterSelectReloadOption = (function(){
    return function(){
        this.each(function(i, v){
          var $div = $(v).parent();
          if($div.is("div") && $div.attr("class") == "m-input-select"){
           var $sel = $(v);// 得到Select的DOM
                 var $input = $div.find(":text[class='m-input']");
                 var $wrapper = $div.find("ul[class='m-list']");
                 $wrapper.empty();
               var html = "", val = "", defVal = "";
                 $sel.find("option").each(function(i, v){
                   if(i == 0){
                   defVal = v.text;
                   }
                     if(v.selected){
                         val = v.text;
                     };
                     html += '<li class="m-list-item'+ (v.selected ? " m-list-item-active" : "") +'" data-value="'+ v.value +'" title="'+ v.text +'">'+ v.text +'</li>';
                 });
                 if(val.length == 0 ){
                   val = defVal;
                 }
                 $input.val(val);
                 $input.attr("title", val);
                 $input.attr("placeholder", val);
                 $wrapper.html(html);
          }
        });
        return this;
    };
})();



--  filterSelect.css
 
.m-input-select {
display: inline-block;
*display: inline;
position: relative;
-webkit-user-select: none;
}

.m-input-select ul, .m-input-select li {
padding: 0;
margin: 0;
}

.m-input-select .m-input {
padding-right: 22px;
}

.m-input-select .m-input-ico {
position: absolute;
right: 0;
top: 0;
width: 22px;
height: 100%;
background:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAATElEQVQoU2NkIBEwkqiegTwNcXFx/4m1CW4DMZoWLVrEiOIkfJpAikGuwPADNk0wxVg1gASRNSErxqkBpgldMV4NuEKNvHggNg5A6gBo4xYmyyXcLAAAAABJRU5ErkJggg==)
no-repeat 50% 50%;
}

.m-input-select .m-list-wrapper {
}

.m-input-select .m-list {
display: none;
position: absolute;
z-index: 1;
top: 100%;
left: 0;
right: 0;
max-width: 100%;
max-height: 250px;
overflow: auto;
border-bottom: 1px solid #ddd;
}

.m-input-select .m-list-item {
color: black;
cursor: default;
padding: 5px;
margin-top: -1px;
list-style: none;
background: #fff;
border: 1px solid #ddd;
border-bottom: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.m-input-select .m-list-item:hover {
background: #2D95FF;
}

.m-input-select .m-list-item-active {
background: #2D95FF;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值