1
votes

I'd like to be able to use the arrow keys to get to the select2 option I want and then press tab to select that option and then tab to the next element as usual.

I already got the down arrow to open the select2 with the following:

$(document).on('keydown', '.select2', function(e) {
  if (e.originalEvent && e.which == 40) {
    e.preventDefault();
    $(this).siblings('select').select2('open');
  } 
});

And I can also use the arrows to get where I need to go. Now I'm struggling to make the tab part work.

I'm assuming since the select2-search__field has focus at the time I'm pressing the key, that that is the element I bind the event to? And then presumably I need to get the value of the currently highlighted option and trigger the select2 change?

I'm not 100% sure this is the right approach but I can't quite figure it out.

3
Can you provide us a working example by adding a snippet please? :)Kostas

3 Answers

5
votes

To achieve this you can use selectOnClose: true:

$(document).on('keydown', '.select2', function(e) {
  if (e.originalEvent && e.which == 40) {
    e.preventDefault();
    $(this).siblings('select').select2('open');
  }
});

$('select').select2({
  selectOnClose: true
});
select {
  min-width: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" />
<select>
  <option>AAAAA</option>
  <option>BBBB</option>
  <option>CCCC</option>
  <option>DDDD</option>
  <option>EEEE</option>
  <option>FFFF</option>
  <option>GGGG</option>
</select>
0
votes

Just add following line in your code.

$(document).on("select2:close", '.select2-hidden-accessible', function () { $(this).focus(); });

Your issue will be resolved.

0
votes

I had this same issue. Because selectOnClose: true also means that pressing 'esc' or clicking outside of the select dropdown was selecting the input, I have opted for a far more complicated and less elegant solution than the accepted answer. My solution has solved this issue for me (and allows subsequent tabbing to switch focus on down the DOM).

I added a listener to select2:closing (which fires immediately before it closes and thus when the highlighted li is still highlighted). Select2 gives that li an id that contains the value of the option to which it's tied. I parse that out and squirrel it away in state (I'm using Vue):

$(this.subjectSelect2).on('select2:closing', () => {
    var idArray = $(".select2-results__option--highlighted")[0].id.split("-");
    var id = idArray[idArray.length - 1];
    this.select2LastHighlighted = id;
})

I then added a listener for keydown, so that if tab is pressed, it takes that value from state, and updates the select2 to that value:

$(this.subjectSelect2).on('select2:open', () => {
    $(".select2-search__field")
        .on('keydown', (e) => {
            if (e.key == 'Tab') {
                this.subjectSelect2.val(this.select2LastHighlighted);
                this.subjectSelect2.trigger('change');
            }
        })
})

I'd love to hear if someone has a more elegant way to do this!