Select2 Tab Off

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="foods1" style="color:green">Normal</label>
  <select id="foods1" >
    <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="foods2" style="color:green">Select2</label>
  <select id="foods2" class="select2-nosearch" >
    <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="foods3" style="color:green">Select2 + Search</label>
  <select id="foods3" class="select2-search" >
    <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/49089243/1366033'>
    Select current item when tabbing off Select2 input
  </a>
</div>

CSS

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

JavaScript

$('.select2-nosearch').select2({
  minimumResultsForSearch: 20
});

$('.select2-search').select2({});

$("*").on("mousedown focus focusin mouseup click blur keydown keypress keyup change",function(e) {
  console.log("{" + e.currentTarget.nodeName.toLowerCase() + ":" + e.type + "}"); 
});

$.fn.once = function (events, callback) {
    return this.each(function () {
        $(this).on(events, myCallback);
        function myCallback(e) {
            $(this).off(events, myCallback);
            callback.call(this, e);
        }
    });
};

// monitor every time we're about to close a menu
$("body").on('select2:closing', function (e) {
	// save in case we want it
	var $sel2 = $(e.target).data("select2");
  var $sel = $sel2.$element;
  var $selDropdown = $sel2.$results.find(".select2-results__option--highlighted")
  var newValue =  $selDropdown.data("data").element.value;
  
  console.log("closing", e);
  
  // must be closed by a mouse or keyboard - setup listener to see when that event is completely done
  // this must fire once and only once for every possible menu close 
  // otherwise the handler will be sitting around with unintended side affects
  $("html").once('keyup mouseup', function (e) {
  
		console.log("closing handler", e,e.target)
    // if close was due to a tab, use the highlighted value
    var KEYS = { UP: 38, DOWN: 40, TAB: 9 }
    if (e.keyCode === KEYS.TAB) {
      if (newValue != undefined) {
        $sel.val(newValue);
        $sel.trigger('change');
      }
    }

  });
  
});