当设置minimumResultsForSearch时,键入以在Select2中突出显示结果

时间:2017-12-28 22:59:49

标签: javascript jquery jquery-select2

在select2中,如果搜索字段为hidden for small results setsdisabled all together,则下拉字段在输入时不会在不同的可用选项之间导航。

通常,只需过滤掉与搜索条件不匹配的选项即可处理此需求,但在禁用搜索时,此功能将不再有效。

这似乎是每个默认<select>元素中可用的非常基本的功能组件。是否有此功能的实现?

这是我正在谈论的一个例子:

键入以突出显示演示

Type to Highlight Demo

StackSnippets中的MCVE演示&amp; jsFiddle

$('#select2').select2({
  minimumResultsForSearch: 20,
});
$('#select2search').select2();
.form-control {
  padding:15px;
}
label {
  display:inline-block;
  width:150px;
}
select {
  width: 150px;
  border: 1px solid #aaa;
  border-radius: 4px;
  height: 28px;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<div class="form-control">
  <label for="normal">Normal</label>
  <select id="normal" >
    <option value="1">Apple</option>
    <option value="2">Banana</option>
    <option value="3">Carrot</option>
    <option value="4">Donut</option>
  </select>
</div>

<div class="form-control">
  <label for="select2">Select2</label>
  <select id="select2" >
    <option value="1">Apple</option>
    <option value="2">Banana</option>
    <option value="3">Carrot</option>
    <option value="4">Donut</option>
  </select>
</div>

<div class="form-control">
  <label for="select2search">Select2 + Search</label>
  <select id="select2search" >
    <option value="1">Apple</option>
    <option value="2">Banana</option>
    <option value="3">Carrot</option>
    <option value="4">Donut</option>
  </select>
</div>

1 个答案:

答案 0 :(得分:1)

您可以通过侦听按键事件,搜索项目的下拉列表以及通过触发该项目上的mouseenter事件来模拟选择来手动实现此功能。

  1. 由于很难将按键处理程序附加到Select2生成的动态<span>。我们可以收听包含--open--focus
  2. 的包含内容的按键事件
  3. 然后我们需要转换keypress event char code into a alphanumeric character
  4. Select2将自动handle most special characters喜欢↑↓ Enter ,但如果我们看到这样的字母/[a-z]/i.test(char)
  5. HTML Dropdowns以一种不稳定的方式搜索某种工作。一旦按下任何字符,它就会找到该元素,但您也可以快速连续地将多个键串在一起以进一步缩小焦点范围。因此,我们将设置一个delayed timeout,每次调用时都会刷新时钟,但会在750 ms后清除临时搜索字符串。
  6. 然后我们将从当前元素穿越,找到$results下拉列表及其中的所有.select2-results__option项。
  7. 从顶部开始,我们将测试每一个,以查看选项文本的开头是否与当前搜索字符串不区分大小写匹配
  8. 如果是这样,我们将触发mouseenter事件,即used elsewhere to highlight result items
  9. 总而言之,它看起来像这样:

    // https://stackoverflow.com/a/1909508/1366033
    var delay = (function () {
      var timer = 0;
      return function (callback, ms) {
        clearTimeout(timer);
        timer = setTimeout(callback, ms);
      };
    })();  
    
    // if we have focus and the container is open, it means we're not in the search field
    $("body").on('keydown', '.select2-container--focus.select2-container--open',
                 function(e) {
      // get char https://stackoverflow.com/a/34711175/1366033
      var char = e.key
    
      // only accept a range of characters
      if (/^[a-z]{1}$/i.test(char)) {
              // select2 handles others https://github.com/select2/select2/blob/4.0.5/dist/js/select2.js#L5368
    
        var $this = $(this); // need inside delay
    
        // act immediately but temporarily store a run of characters
        delay(function () {
          // clear search text on delay
          $this.data("searchText", "");
        }, 750);
    
        // build search string with any previous characters and store new value
        var previous =  $this.data("searchText");
        var searchText = (previous === undefined ? "" : previous) + char;
        $this.data("searchText", searchText);
        console.log(searchText);
    
            // find available options
        var $sel2 = $this.data("element");
        var $select2 = $sel2.data("select2");
        var $results = $select2.results.$results;
            var $opts = $results.find(".select2-results__option");
    
        // find first option with matching start and select it
        $opts.each(function(i,el) {
          var $opt = $(el)
          var optText = $opt.text()
          var startsWithRegex = new RegExp('^' + searchText, 'i');
          var match = startsWithRegex.test(optText)
    
                // if we got one - fire event and we can leave
          if (match) {
            // mouseenter is a reliable way to highlight item in results list
            // https://github.com/select2/select2/blob/4.0.5/dist/js/select2.js#L1234
            $opt.trigger('mouseenter');
            return;
          }
    
          // if we found nothing, previous selection will stay highlighted
        })
      }
    });
    

    StackSnippets中的工作演示&amp; jsFiddle

    $('#select2').select2({
      minimumResultsForSearch: 20,
    });
    $('#select2search').select2();
    
    // https://stackoverflow.com/a/1909508/1366033
    var delay = (function () {
      var timer = 0;
      return function (callback, ms) {
        clearTimeout(timer);
        timer = setTimeout(callback, ms);
      };
    })();  
    
    // if we have focus and the container is open, it means we're not in the search field
    $("body").on('keydown', '.select2-container--focus.select2-container--open',
                 function(e) {
      // get char https://stackoverflow.com/a/34711175/1366033
      var char = e.key
    
      // only accept a range of characters
      if (/^[a-z]{1}$/i.test(char)) {
    		  // select2 handles others https://github.com/select2/select2/blob/4.0.5/dist/js/select2.js#L5368
          
        var $this = $(this); // need inside delay
    
        // act immediately but temporarily store a run of characters
        delay(function () {
          // clear search text on delay
          $this.data("searchText", "");
        }, 750);
    
        // build search string with any previous characters and store new value
        var previous =  $this.data("searchText");
        var searchText = (previous === undefined ? "" : previous) + char;
        $this.data("searchText", searchText);
        console.log(searchText);
    
    		// find available options
        var $sel2 = $this.data("element");
        var $select2 = $sel2.data("select2");
        var $results = $select2.results.$results;
    		var $opts = $results.find(".select2-results__option");
        
        // find first option with matching start and select it
        $opts.each(function(i,el) {
          var $opt = $(el)
          var optText = $opt.text()
          var startsWithRegex = new RegExp('^' + searchText, 'i');
          var match = startsWithRegex.test(optText)
    
    			// if we got one - fire event and we can leave
          if (match) {
            // mouseenter is a reliable way to highlight item in results list
            // https://github.com/select2/select2/blob/4.0.5/dist/js/select2.js#L1234
            $opt.trigger('mouseenter');
            return;
          }
          
          // if we found nothing, previous selection will stay highlighted
        })
      }
    });
    .form-control {
      padding:15px;
    }
    label {
      display:inline-block;
      width:150px;
    }
    select {
      width: 150px;
      border: 1px solid #aaa;
      border-radius: 4px;
      height: 28px;
    }
    <link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
    
    <div class="form-control">
      <label for="normal">Normal</label>
      <select id="normal" >
        <option value="1">Apple</option>
        <option value="2">Banana</option>
        <option value="3">Carrot</option>
        <option value="4">Donut</option>
      </select>
    </div>
    
    <div class="form-control">
      <label for="select2">Select2</label>
      <select id="select2" >
        <option value="1">Apple</option>
        <option value="2">Banana</option>
        <option value="3">Carrot</option>
        <option value="4">Donut</option>
      </select>
    </div>
    
    <div class="form-control">
      <label for="select2search">Select2 + Search</label>
      <select id="select2search" >
        <option value="1">Apple</option>
        <option value="2">Banana</option>
        <option value="3">Carrot</option>
        <option value="4">Donut</option>
      </select>
    </div>

    工作演示

    Working Demo