Stop select2 from keeping focus after close (or disable spacebar!)

It appears that my select2 remains the active element after closing by default. That’s fine and what you’d expect, but it also captures the space bar and enter key when focused which are not desired in my application.

To address this and hopefully un-focus the select2, I have an on:change event for the select2 where I try to focus() some other element than my select2 or blur() the select2. This seems to work, as when I step through with my debugger I see document.activeElement change to the new element. However at some unspecified time later, the active element becomes “select2-selection select2-selection–single” again. I’ve not managed to step through to catch when this happens yet, but it might just be a matter of time if the cause of this is set to trigger as a callback or whatever.

I also tried moving the on:change to on:close, no change in results.

Is there some setting I can use to disable focus on a select2 after a selection is made? Or, more directly to the point, is there a way to just disable the function of spacebar after a selection is made?

Thanks in advance.

There isn’t a built-in option to do what you’re asking. I think you’re on the right track with changing focus on the select2:close event… I’ve encountered the same behavior you have–that after moving focus away Select2 seems to steel it back. My solution (which I only did as a demo—not actual production code) was to put the “change focus” code in a setTimeout callback. I think I used a 500ms delay, but you could try different values to see what works for you.

Well, that certainly worked. It’s something I had considered at first but thought to be a bit fiddly. Anyway, I set a timeout to focus some other element from within the on:change event. I didn’t see issues with that set at 10ms, but I worry about going lower and possibly seeing issues on other browsers or what-have-you due to a race condition between my interval and whatever closes the dialog and resets the focused element. Also, this is still not a perfect solution as obviously keypresses within that 10ms can still cause the select2 to re-open. That’s of course unlikely, but not outside the realm of possibility.

Anyway, it should work for now - if I could get some knowledge of the underlying code I might have a bit more confidence in this going forward however. As it stands this feels like an unfinished compatibility issue in the code more than anything.

I agree with you that this is “fiddly”, but absent writing your own DropdownAdapter (and probably also SelectionAdapter), hacking a solution using the supported events seems like the best approach.

If you’re worried about that “window of opportunity” to press a key before changing the focus, you can fix that with—yes—a couple of other event handlers:

  1. In your change handler, immediately set a flag* indicating that you don’t want to allow the Select2 to re-open while that flag is set. (*The flag could, for instance, be a custom property that you set on the underlying HTML select element.)
  2. Add a select2:opening event handler that checks the value of that flag; it it’s set, cancel the event (thus preventing the Select2 from opening).
  3. In your setTimeout callback, clear the flag after you have moved the focus to the desired element.

If you do this, then you can increase the timeout (perhaps up to 100ms) so you have to worry less about any potential race conditions (for example, on a slower machine).

I ran into the same problem and during the testing I realized that after closing/selecting an item on select2 focus was being set to another element, but then focus rapidly goes back to select2!

my workaround was to set a timeout and then focus the element I needed.

myComponent.on('select2:select', function (e) {
	setTimeout(function() {
		$('#otherElement').focus().select();
	}, 500);
});

It is hacky, but simple, I hope it helps.