Reputation: 1160
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
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
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
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