Select2 vs Select

by Kyle Mitofsky

HTML

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css">
<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" style="color:green">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" style="color:green">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" style="color:green">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>




<div style='position:fixed;bottom:0;left:0; background:lightgray;width:100%;'>
  About this question on SO: 
  <a href='https://stackoverflow.com/q/48015431/1366033'>
    Type to highlight results in Select2
  </a>
</div>

CSS

.form-control {
  padding:10px;
  display:inline-block;
}
select {
  width: 100px;
  border: 1px solid #aaa;
  border-radius: 4px;
  height: 28px;
}

JavaScript

$('#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;
      }
     ...