• 基于jquery的可查询多级select控件(可记录历史选择)


    一、功能和使用

    公司有功能需求,还要一条代码引入的控件,网上找完全符合的控件比较难,寻找所花的时间还不如自己写一个,所以找个空闲时间自己写了一个
     
    控件功能:1、可手动输入查询,也可点击下拉框查询,
    2、输入时实时定位到下拉框,enter补全
    3、可多级查询(目前是写到二级)
    4、localStorage存储历史记录
     
    控件使用:引入相应的js和css文件,需要控件的html中加一个div
    <div id="multiple_select" class="multiple-select-container"></div> 
    

    js里引入控件

    $("#multiple_select").multiSelect({
             type:'2',//可选择几级数据
             data:data.list,      
          noneSelectedText: '请选择',
             field:['provence','city','name']  //option字段,【一级字段,二级字段,显示字段】
      }); 

    二、代码

    HTML
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>树形控件</title>
        <link rel="stylesheet" type="text/css" href="./multiSelect.css" />    
      </head>
      <body style="padding:100px;">  
          <div id="multiple_select" class="multiple-select-container"></div>     
      <script src="plugins/jquery-1.10.2.js"></script>
      <script src="./multiSelect.js"></script>
      <script>
        $(function(){
          //测试用的数据
          var data = {
          list:[{
                  provence:"湖北",
                  city:[{name:"武汉",code:1}, {name:"仙桃",code:2},{name:"天门",code:3}]
              },          
                {
                  provence:"河北",
                  city:[{name:"石家庄",code:1}, {name:"邯郸",code:2},{name:"唐山",code:3}]
              },{
                  provence:"湖南",
                  city:[{name:"郴州",code:1}, {name:"岳阳",code:2},{name:"长沙",code:3}]
              }]          
          }
          //控件引用
          $("#multiple_select").multiSelect({
             type:'2',//可选择几级数据
             data:data.list,
             field:['provence','city','name'] , //option字段,第一个是1级展示数据的字段,第二个是二级数据字段,第三个是显示字段
       record: true,  //是否需要历史记录功能,只展示最近使用的前三条数据
            noneSelectedText : '', //未选择时展示数据
          });
        });
      </script> 
      </body>
    </html>

    CSS

    * {
        padding: 0;
        margin: 0;
    }
    
    ul li {
        list-style: none;
    }
    
    
    /*fontclass*/
    
    @font-face {
        font-family: "iconfont";
        src: url('iconfont.eot?t=1537237853618');
        /* IE9*/
        src: url('iconfont.eot?t=1537237853618#iefix') format('embedded-opentype'), /* IE6-IE8 */
        url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAVYAAsAAAAACCQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY8hUioY21hcAAAAYAAAABoAAABquZlt9xnbHlmAAAB6AAAAV8AAAG8iReSsmhlYWQAAANIAAAALAAAADYSq0zoaGhlYQAAA3QAAAAcAAAAJAfeA4ZobXR4AAADkAAAAA4AAAAUFAAAAGxvY2EAAAOgAAAADAAAAAwA2AFKbWF4cAAAA6wAAAAfAAAAIAESADtuYW1lAAADzAAAAUUAAAJtPlT+fXBvc3QAAAUUAAAAQgAAAFf+vnWeeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGBye8T/bxtzwv4EhhrmBoQEozAiSAwDr4gyoeJztkcENgCAMRV8FjTEmhj0cwKPDeHI/GalrYFscw08e+f1pORRgBJKxGxnkRnBdlkrkiSXyzGH1bGcA3bRobe1zj7uQRMccr4nNWq9M/FrjPr8q+9464UvHN65Px39Fa4fhBcRnF9R4nE2QP0/CQBiH732vtrRXwcT+wRBabWKLS4lt02646IgTwbBRZhkYlX4BExNC4uTiqFE+BHwL+DBePFoTveF+l8tzz+/yEiRi0RHuCCMBIVAHxQG7B1kIx5Yhe11QZM9PriDwkzRyIUsjy2gASssNpZvlci1Ja4dZbX1eMMfUikIzHVbM9bbFCtxK64oQO4+ZuJvPBcuK4t9ZlJZ/eMUJMQjJVLCi1A9EYeDLCsgORNknDGCku01o8JfaAbITxhcqNF19BXf8i9muDvc1CpKk8oXA9D/neO9U0fdkywbbsq00gzQET6FDvuLvpVO8LZ0wK5044B8w3EtFWSmFWSmlpXNGL8kROSMhIedeiEkPIweNOlKvjoaDUQ+TEEHuQjUwMUR4u3nMoyh/fKriOpv0O53+ZFoFPByynWa22FYznuOKisf7iHHcuc1/sWnev/g+BbZlLVPbsZbxAzYBVaMAeJxjYGRgYADikyacs+P5bb4ycLMwgMD1Yy2xyDQLA7MhkOJgYALxAArgCJB4nGNgZGBgbvjfwBDDwgACQJKRARWwAgBHCwJueJxjYWBgYEHDAAEEABUAAAAAAAAAQgBsAJYA3nicY2BkYGBgZdBnYGYAASYg5gJCBob/YD4DAA2tAU4AeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAlZGJkZmRhZGVkY2BJzknvzhVNzmzKDknlSOxqCi/XLe0gAvCSMkvz2MrTk0sSs5gYAAATLsOxwAA') format('woff'), url('iconfont.ttf?t=1537237853618') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
        url('iconfont.svg?t=1537237853618#iconfont') format('svg');
        /* iOS 4.1- */
    }
    
    .iconfont {
        font-family: "iconfont" !important;
        font-size: 16px;
        font-style: normal;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
    }
    
    .icon-close-circle:before {
        content: "e611";
    }
    
    .icon-arrow-up:before {
        content: "e6b6";
    }
    
    .icon-arrow-down:before {
        content: "e6b5";
    }
    
    .icon-search:before {
        content: "e60f";
    }
    
    
    /*fontclass end*/
    
    .multiple-select-container {
         166px;
        height: 34px;
        line-height: 34px;
        position: relative;
        display: inline-block;
        vertical-align: middle;
    }
    
    .multiple-select-container .select-inputbox {
         100%;
        height: 40px;
        line-height: 40px;
        padding: 0 9px;
        position: relative;
        box-sizing: border-box;
    }
    
    .multiple-select-container .select-input,
    .multiple-select-container .select-button {
         100%;
        height: 100%;
        outline: none;
        box-sizing: border-box;
        background: #FFF;
    }
    
    .multiple-select-container .select-input {
        padding: 5px 22px;
        border-radius: 2px;
        border: 1px solid #CFCFCF;
        height: 28px;
    }
    
    .multiple-select-container .select-button {
        padding: 5px 25px 5px 12px;
        border: 1px solid #CFCFCF;
        border-radius: 4px;
        text-align: left;
        display: flex;
        justify-content: space-between;
    }
    
    .multiple-select-container .select-button span {
        display: inline-block;
        height: 100%;
        line-height: 22px;
    }
    
    .multiple-select-container .selected-data {
         80%;
        color: #333;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    
    .multiple-select-container .input-isfold {
        float: right;
        cursor: pointer;
        margin-right: -16px;
        font-size: 12px;
    }
    
    .multiple-select-container .input-search,
    .multiple-select-container .input-close {
        position: absolute;
        cursor: pointer;
        top: 50%;
        transform: translateY(-50%);
        display: inline-block;
        height: 16px;
        line-height: 16px;
        font-size: 18px;
    }
    
    .multiple-select-container .input-close {
        left: calc(95% - 22px);
         12px;
        color: #7B7B7B;
        display: none;
    }
    
    .multiple-select-container .input-search {
        color: #ADADAD;
        left: 12px;
         16px;
    }
    
    .multiple-select-container .select-options-box {
         100%;
        display: none;
        position: absolute;
        border: 1px solid #c2cad8;
        z-index: 999999;
        background: #fff;
        height: 300px;
        overflow-y: auto;
    }
    
    .multiple-select-container .options-container {
         100%;
        height: auto;
    }
    
    .multiple-select-container .options-record,
    .multiple-select-container .optionslist {
        font-size: 14px;
         100%;
        box-sizing: border-box;
        padding: 0 9px;
        text-align: left;
    }
    
    .multiple-select-container .options-record {
        color: #999;
        height: 34px;
        line-height: 34px;
    }
    
    .multiple-select-container .optionslist {
        cursor: pointer;
        height: 26px;
        line-height: 26px;
    }
    
    .multiple-select-container .optionslist:hover {
        background: #DEEDFF;
    }
    
    .multiple-select-container .options-one {
        font-size: 16px;
    }
    
    .multiple-select-container .options-two {
         100%;
        font-size: 14px;
    }
    
    .multiple-select-container .options-two li {
        padding-left: 15px;
    }
    
    .multiple-select-container .options-isfold {
        float: right;
        display: inline-block;
         16px;
    }
    
    .multiple-select-container .active-border {
        border: 1px solid #009BE1;
    }
    
    .multiple-select-container .background-color {
        background: #ECECEC!important;
    }
    
    .multiple-select-container .border-bottom {
        border-bottom: 2px solid #D4D4D4;
    }
    
    ::-webkit-scrollbar {
         5px;
        height: 5px;
    }
    
    ::-webkit-scrollbar-thumb {
        background: #DCDCDC;
        border-radius: 8px;
    }
    

      JS 

     ;
     (function($, window, document) {
    
         var pluginName = 'multiSelect',
             defaults = {
                 type: '1', //select层级onetwo
                 data: [], //数据
                 field: [], //数据字段名 
                 record: false, //是否记录最近使用的三条数据
                 chooselast: true, //是否在初始化后自动选择最近使用的选项,record必须为true
                 noneSelectedText: '', //未选择时显示文字
                 isfoldFirst: false, //是否默认展开二级目录
                 disabled: '', //是否禁用
                 hasinput: true, //是否显示搜索框
                 id: '', //id字段名
                 allselect: '', //全选或者不选择
                 queryFun: function() {}, //搜索方法
    
             };
    
         function MultiSelect(element, options) {
             this.element = element;
             this.settings = $.extend({}, defaults, options);
             this.init();
         }
    
         MultiSelect.prototype = {
    
             //初始化弹出框
             init: function() {
                 var that = this,
                     element = this.element;
    
                 that.create(element);
                 that.triggerlist(element);
             },
    
             //创建select框
             create: function(element) {
                 var that = this,
                     $this = $(element),
                     noneSelectedText = that.settings.noneSelectedText,
                     selectElement = '<button name="selectinput" class="select-button">' +
                     '<span id="selected_data" class="selected-data">' + noneSelectedText + '</span><span class="input-isfold iconfont icon-arrow-down"></span></button>' +
                     '<div class="select-options-box" id="select_options_box"></div>';
                 $this.append(selectElement);
                 var $options_box = $this.find('#select_options_box');
                 $this.on({
                     'hideoptions': function(e) {
                         $options_box.fadeOut();
                         $this.find('.input-isfold').toggleClass('icon-arrow-down icon-arrow-up');
                     },
                     'showoptions': function(e) {
                         $options_box.fadeIn();
                         $this.find('.input-isfold').toggleClass('icon-arrow-down icon-arrow-up');
                     }
    
                 });
                 that.initOption(element);
             },
             //初始化列表
             initOption: function(element) {
                 var that = this,
                     $this = $(element),
                     $options_box = $this.find('#select_options_box');
                 var $options = that.parseOptions();
                 $options_box.html($options);
             },
             //解析并处理options数据
             parseOptions: function() {
                 var that = this,
                     type = that.settings.type,
                     field = that.settings.field,
                     one = field[0],
                     two = field[1],
                     data = that.settings.data,
                     allselect = that.settings.allselect,
                     hasinput = that.settings.hasinput,
                     disabled = that.settings.disabled,
                     twolist = '',
                     optionsTwo = [],
                     record = that.settings.record,
                     noneSelectedText = that.settings.noneSelectedText,
                     options = '';
                 var recordColumn = JSON.parse(window.localStorage.getItem("recordInfo")) ? JSON.parse(window.localStorage.getItem("recordInfo")) : [];
                 console.log("recordColumn" + recordColumn);
                 options += '<div class="options-container">';
                 if (record && recordColumn.length > 0) {
                     options += '<div class="options-record"><span class="options-data">最近使用</span>' +
                         '</div>';
                     for (var i = 0; i < recordColumn.length; i++) {
                         if (recordColumn[i] != undefined && JSON.stringify(data).indexOf(JSON.stringify(recordColumn[i].id)) >= 0) {
                             options += '<div class="optionslist" disabled="' + disabled + '" id="' + recordColumn[i].id + '" data-index=' + recordColumn[i].dataIndex + '">' +
                                 '<span class="options-data">' + recordColumn[i][one] + '</span></div>';
                         } else {
                             recordColumn.splice(i, 1);
                             window.localStorage.setItem("recordInfo", JSON.stringify(recordColumn));
                         }
                     }
                 }
                 if (noneSelectedText) {
                     options += '<div class="options-record optionslist" id="none_selected_all"><span class="options-data">' + noneSelectedText + '</span></div>';
                 }
                 if (hasinput) {
                     options += '<div class="select-inputbox"><input type="text" name="selectinput" id="select_input" class="select-input" placeholder="" />' +
                         '<i class="input-search iconfont icon-search"></i>' +
                         '<i class="input-close iconfont icon-close-circle"></i></div>';
                 }
                 switch (type) {
                     case '1':
                         for (var i in data) {
                             options += '<div class="optionslist" disabled="' + disabled + '" id="' + data[i].id + '" data-index="' + i + '"><span class="options-data">' + data[i][one] + '</span></div>';
                         }
                         break;
                     case '2':
                         for (var i in data) {
                             twolist = '', optionsTwo = [];
                             var optionsTwo = data[i][two];
    
                             for (var j in optionsTwo) {
                                 twolist += '<li class="options-container optionslist" disabled="' + disabled + '" id="' + data[i].id + '" data-index="' + i + '" data-twoindex="' + j + '">' +
                                     '-- ' + '<span class="options-data">' + optionsTwo[j][field[2]] + '</span></li>';
                             }
                             options += '<div class="options-one optionslist" disabled="' + disabled + '" id="' + data[i].id + '" data-index="' + i + '">' +
                                 '<span class="options-data">' + data[i][one] + '</span><span class="iconfont icon-arrow-up options-isfold"></span>' +
                                 '</div>' +
                                 '<ul class="options-two">' + twolist + '</ul>';
                         }
                         break;
                 }
                 options += '</div>';
                 return options;
             },
    
             //系列事件
             triggerlist: function(element, event) {
                 var that = this,
                     $this = $(element),
                     data = that.settings.data,
                     field = that.settings.field,
                     one = field[0],
                     two = field[1],
                     isfoldFirst = that.settings.isfoldFirst,
                     noneSelectedText = that.settings.noneSelectedText,
                     $options_box = $this.find('#select_options_box'),
                     $isfold = $this.find('.options-isfold'),
                     record = that.settings.record,
                     chooselast = that.settings.chooselast,
                     disabled = that.settings.disabled,
                     $input = $this.find('#select_input'),
                     $selected = $this.find('#selected_data'),
                     $button = $this.find('.select-button');
                 var recordColumn = JSON.parse(window.localStorage.getItem("recordInfo")) ? JSON.parse(window.localStorage.getItem("recordInfo")) : [];
                 $input.on({
                     'input propertychange': function() {
                         that.selectFun(false, false, element);
                     },
                     'click': function() {
                         $options_box.show();
                         return false;
                     }
                 });
                 $this.find('.input-search').on('click', function(event) {
                     $this.trigger('showoptions', e);
                     that.selectFun(false, false, element);
                     return false;
                 });
                 $this.find('.input-close').on('click', function(event) {
                     $options_box.show();
                     $input.val('');
                     $(this).hide();
                     return false;
                 });
                 $button.on('click', function(event) {
                     $(this).addClass('active-border');
                     $options_box.toggle();
                     that.selectFun(false, true, element);
                     $this.find('.input-isfold').toggleClass('icon-arrow-down icon-arrow-up');
                     event.stopPropagation();
                 })
                 $isfold.on('click', function(event) {
                         //  that.selectFun(false, true, element);
                         $(this).parent().next().toggle();
                         $(this).toggleClass('icon-arrow-down icon-arrow-up');
                         $options_box.show();
                         //  $this.trigger('showoptions');
                         event.stopPropagation();
                     })
                     //选择事件
                 $this.find('.optionslist').on({
                     'click': function(event) {
                         if (disabled) return;
                         $button.removeClass('active-border');
                         $(this).addClass('background-color');
                         $this.find('.optionslist').removeAttr("selected");
                         $(this).attr("selected", "selected");
                         $selected.html($(this).find('.options-data').html());
                         if ($.isFunction(that.settings.queryFun)) {
                             that.settings.queryFun();
                         }
                         if ($(this).attr("id") === "none_selected_all") {
                             $button.data("data", null)
                             $selected.html(noneSelectedText);
                         } else {
                             var recordIndex = parseInt($(this).attr("data-index")),
                                 twoIndex = parseInt($(this).attr("data-twoindex")),
                                 a = {},
                                 b = { dataIndex: recordIndex };
                             if ($(this).attr("data-twoindex")) {
                                 a = data[recordIndex][two][twoIndex];
                             } else {
                                 a = data[recordIndex];
                             }
                             recordCol = $.extend(a, b);
                             $button.attr("data-index", recordIndex);
                             $button.data("data", a)
                             if (record) {
                                 //  console.log("recordCol:" + recordCol + " recordColumn:" + JSON.stringify(recordColumn));
                                 var len = recordColumn.length,
                                     existIndex = -1;
                                 //  if (JSON.stringify(recordColumn).indexOf(JSON.stringify(recordCol)) > -1) {
                                 for (var i = 0; i < len; i++) {
                                     if (recordColumn[i].dataIndex == recordIndex) {
                                         existIndex = i;
                                     }
                                 };
                                 if (existIndex > -1) {
                                     recordColumn.splice(existIndex, 1);
                                 }
                                 //  };
                                 recordColumn.unshift(recordCol);
                                 len = recordColumn.length;
                                 if (len > 3) {
                                     recordColumn.splice(3, len - 3);
                                 }
                                 window.localStorage.setItem("recordInfo", JSON.stringify(recordColumn));
                             }
                         }
                         // $button.attr("data", a)
    
                         $this.trigger('hideoptions');
                         event.stopPropagation();
                     },
                     'mouseover': function() {
                         $(this).css({ 'background': '#DEEDFF' });
                     },
                     'mouseout': function() {
                         $(this).css({ 'background': '#fff' });
                     }
                 });
    
                 $(document).keyup(function(event) {
                     if (event.keyCode === 13&&$input.is(':focus')) {
                         that.selectFun(true, false, element);
                         if ($.isFunction(that.settings.queryFun)) {
                             that.settings.queryFun();
                         }
                     }
                     event.stopPropagation();
                 });
                 /* $(document).on('click', function(event) {
                     $options_box.hide();
                 }); */
                 $(document).on('click', function(event) {
                     var _tar = $button.children();
                     if (!_tar.is(event.target) && _tar.has(event.target).length === 0) { // Mark 1
                         $options_box.fadeOut();
                         $button.removeClass('active-border');
                     }
                 });
                 if (chooselast && record && recordColumn.length > 0) {
                     $this.find('.optionslist').first().trigger("click");
                 }
                 if (!isfoldFirst) {
                     $isfold.trigger("click");
                 }
             },
    
             // input与select同步
             selectFun: function(enter, button, element) { //enter为true代表是键盘enter键,button为true代表是select,为false代表是input搜索框
                 var that = this,
                     $this = $(element),
                     data = that.settings.data,
                     $options_box = $this.find('#select_options_box'),
                     $input = $this.find('#select_input'),
                     options = $this.find('.optionslist'),
                     $selected = $this.find('#selected_data'),
                     optionTop = 0,
                     selectHTML = '';
                 var optiondata = button ? $selected.html() : $input.val();
                 if ($input.val()) {
                     $this.find('.input-close').show();
                 } else {
                     $this.find('.input-close').hide();
                 }
                 $.each(options, function(i, item) {
                     selectHTML = $(item).find('.options-data').html();
                     // console.log(selected); 
                     if (selectHTML.indexOf(optiondata) >= 0) {
                         // $(item).trigger('hover');
                         options.removeClass('background-color');
                         $(item).addClass('background-color');
                         /*if ($(item).hasClass('options-one')) {
                           optionTop = $(item).position().top;                                
                         }else{
                           optionTop = $(item).parent().position().top;
                         }*/
                         optionTop = $(item).position().top;
                         // console.log(optionTop);
                         $options_box.scrollTop(optionTop);
                         if (enter) {
                             $(item).trigger('click');
                         }
                     }
                 });
    
                 if (optiondata === '') {
                     options.removeClass('background-color');
                     $options_box.scrollTop(0);
                 }
             }
    
         };
    
         $.fn[pluginName] = function(options) {
             this.each(function() {
                 if (!$.data(this, "plugin_" + pluginName)) {
                     $.data(this, "plugin_" + pluginName, new MultiSelect(this, options));
                 }
             });
             return this;
         };
    
         //外部获取选中数据
         $.fn.extend({
             optionSelected: function() {
                 if ($(this).find("button").data("data")) {
                     return $(this).find("button").data("data");
                 } else {
                     return "";
                 }
             },
             setOption: function(id) {
                 if (id && id != "" && id.length > 0) {
                     $(this).find("#" + id).trigger('click');
                 }
             },
             setDisabled: function() {
                 $(this).find("button").css("background-color", "#ccc");
                 $(this).css("pointer-events", "none");
                 $(this).parent().css("cursor", "no-drop");
             },
         });
    
     })(jQuery, window, document)
    

      

     

      

  • 相关阅读:
    素敵な日本人 2-1
    十年目のバレンタインデー のほか
    水晶の数珠  3
    水晶の数珠  2
    STM32 USB HID BarCodeReader不兼容问题的解决
    水晶の数珠 1
    クリスマスミステリ 2
    クリスマスミステリ 1
    サファイア奇跡 3
    感悟成功
  • 原文地址:https://www.cnblogs.com/phoebeyue/p/9644526.html
Copyright © 2020-2023  润新知