Typing while a select2 element has focus does not jump to a matching option

with a normal select element, as soon as it has focused, without actually opening the dropdown, if you start typing, then it will automatically jump to the next option that literally matches the keys you typed in within a short timeframe.

Problem shown on example page, https://select2.org/getting-started/basic-usage, if you tab to the first regular select element, and just type “ha”, then you will see it automatically select the “Hawaii” option. If you tab to the select2 version, typing doesn’t select anything. You have to open actually open the dropdown to type-select. This breaks natural functionality that select elements had prior to being stylized with select2, namely that it requires an additional layer of interaction before user is able to select an element.

This seems to be a design decision on the part of Select2’s creator, so I don’t think you could classify it as a “bug”. It does seem to be a reasonable way for the widget to operate, however. I have two suggestions:

  1. The creator of Select2 is currently working on a new version, and he’s said his focus is on accessibility. Your desired functionality might fit that focus, so you could suggest it to him

  2. Alternatively, if you want to implement your own solution, you could either override the SelectionAdapter (I think…) or you could do something like I did in this example to capture the user’s keystrokes when they focus on the unopened control, programmatically open the Select2 widget and “stuff” the keystrokes into the text input field. (Note that my example was created to demonstrate something else, but I did provide the ability to simply start typing as long as the page has focus. You should be able to adapt that approach to apply only when the closed Select2 widget has focus.)

thanks for the suggestions, unfortunately the example doesn’t quite work. Example, if the select2 item has focus (but not opened), and you immediately type in “vel”, then the dropdown will automatically open, but only the first character “v” is visible.

I suppose I can write my own listener to listen to keystrokes tapped, and do my own searching within the list. The idea would be not to open the dropdown, since the keystrokes should auto jump to the first matched entry from beginning of string, although this brings with it it’s own can of worms of how it would work on ajax based searches, as well as stylized entries where it’s not just a single value string. If/when I figure out my own solution, I’ll update here in case someone else comes looking for the same thing.

Yes, my example only listens for the first keystroke, and then it opens the Select2 and puts focus in the text entry field, assuming that will catch the other characters the user types. As you discovered, typing very quickly can lose characters after the first one. That could be fixed by continuing to listen for and stuff the keypresses into the text entry field even after it is open.

I think you’ve hit the nail on the head for why the Select2 widget doesn’t behave like a standard HTML select—primarily because of how the author chose to implement the AJAX feature. To do what you want will probably require you to create your own SelectionAdapter, but I don’t see why it couldn’t be done, as long as you aren’t using an AJAX data source. Unfortunately, the documentation for writing your own adapter is practically nonexistent. You could look at the source code of the built-in SelectionAdapter. This tutorial might also be helpful.

Good luck!

I realize this was 5 years ago but I stumbled across this post trying to do the same thing and I eventually landed on this solution (all of my select2 dropdowns have the class dropdown-select2, adjust accordingly:

$('.dropdown-select2').next('.select2').find('select2-selection').on('keypress', function (e) {
  $(e.target).closest('div').find('.dropdown-select2').select2('open');
  setTimeout(function () {
    $('.select2-search__field').focus();
    $('.select2-search__field').val(e.key);
  }, 100);
});

Now hopefully anyone who stumbles across this is closer to an answer!