Danny Santos
Danny Santos

Reputation: 1160

jQuery Select2 - Use tab to select an option

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.

Upvotes: 5

Views: 9009

Answers (3)

Travis
Travis

Reputation: 353

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!

Upvotes: 0

DhavalThakor
DhavalThakor

Reputation: 500

Just add following line in your code.

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

Your issue will be resolved.

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337550

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>

Upvotes: 6

Related Questions