jQuery Select2 - Use tab to select an option
Asked Answered
J

3

5

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.

Jordan answered 30/5, 2018 at 12:54 Comment(1)
Can you provide us a working example by adding a snippet please? :)Complexion
G
6

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>
Geller answered 30/5, 2018 at 12:59 Comment(4)
Ah this is great, thanks. Guess I was overcomplicating things! The only thing this doesn't handle is resuming the default behaviour of tabbing to the next element on the page. Is there an equally easy way to achieve this, or would that need to be done manually?Jordan
Works, but I didn't need selectOnClose.Hesperides
I works, but on close it selects the latest highlighted option, this is not the desired behavior, I need to select the selected option only on keypress enter/tab.Rebut
Another wrinkle to this approach is that Esc also selects on close, which is not very intuitive behavior.Damicke
H
0

Just add following line in your code.

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

Your issue will be resolved.

Holley answered 18/3, 2019 at 3:0 Comment(0)
D
0

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!

Damicke answered 10/12, 2021 at 21:29 Comment(1)
this seems to work, but when I clicked the cross button to "deselect" there was no $(".select2-results__option--highlighted")[0], so the JS threw an error, so I had to wrap it in a condition if($(".select2-results__option--highlighted").length)Bitterweed

© 2022 - 2024 — McMap. All rights reserved.