js实现下拉框搜索功能

下拉框搜索功能

这里分享一个下拉框的搜索功能,感觉挺好用的。

searchableSelect.js代码

(function($){
  // 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();
    })
  }
 
  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');
      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);
          _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();
      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){
      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;
  };
 
})(jQuery);

searchableSelect.css代码

/* select */

.searchable-select-hide {
  display: none;
}

.searchable-select {
  display: inline-block;
  min-width: 100%;
  font-size: 14px;
  line-height: 1.428571429;
  color: #555;
  vertical-align: middle;
  position: relative;
  outline: none;
  z-index: 9
}

.searchable-select-holder{
  padding: 0 10px;
  background-color: #fff;
  background-image: none;
  border: 1px solid #d9d9d9;
  min-height: 36px;
  line-height: 36px;
  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: #a0a0a0 transparent transparent transparent;
  top: 5px;
  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.selected,
.searchable-select-item.hover {
  background: #3f86d8;
  color: white;
}
/* select */

引入文件

在你的html页面引入上面二个文件searchableSelect.js和searchableSelect.css,jquery-1.11.2.min.js请自行去下载,路径改成你自己的项目路径
在这里插入图片描述

静态下拉框搜索html代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>下拉框搜索</title>
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="apple-mobile-web-app-status-bar-style" content="black"> 
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="format-detection" content="telephone=no">
	<script type="text/javascript" src="js/jquery-1.11.2.min.js"></script>
	<script type="text/javascript" src="js/searchableSelect.js"></script>
	<link href="css/searchableSelect.css" rel="stylesheet">
	
	<script type="text/javascript">
		$(function(){
            $('#a').searchableSelect();
        });
	</script>
</head>
<body>
<div>
<select id="a">
      <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="and">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>
</div>

</body>
</html>

页面效果图 显示全部

在这里插入图片描述
在文本框输入显示值
在这里插入图片描述

动态下拉框搜索示例

这里后台框架用的是JFinal框架,所以这样写,返回的就是supplier_id和supplier_name这2个值

public void getSupplierData() {
		List<Supplier> list=Supplier.dao.find("select supplier_id,supplier_name from t_supplier");
		this.renderJson(list);
	}

前端代码示例:
先在页面引入
<script type="text/javascript" src="js/jquery-1.11.2.min.js"></script> <script type="text/javascript" src="js/searchableSelect.js"></script> <link href="css/searchableSelect.css" rel="stylesheet">这三个文件

<select id="supplier_id"  name="supplier_id">
	<option value="${item.supplier_id}">${item.supplier_name}</option>
</select>

这里有${item.supplier_id}是编辑时,数据回显显示,用来做修改数据用的

js部分代码
请求地址改成你自己的

<script type="text/javascript">
		$(function(){
			$.ajax({
					url: '${context_path}/commdity/getSupplierData',
					dataType: 'json',
					//data:{'state': 0},
					type: 'GET',
					success: function (data) {
						$.each(data, function (index, item) {
							$('#supplier_id').append(new Option(item.supplier_name, item.supplier_id));// 下拉菜单里添加元素
						});
						$('#supplier_id').searchableSelect();//为下拉框添加搜索功能
					}
				});
        });
</script>

到这里代码就写完了。
动态添加效果和静态是一样,如图:
在这里插入图片描述
喜欢的小伙伴,点个赞,谢谢啦!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值