Which DOM node is emitting select2 events?


#1

I have a javascript library that listens to change events from an array (configurable) of CSS selectors to perform some operations (validations).

The easiest way to integrate with such library, is just adding another CSS selector to the list.
I couldn’t, however, figure out which DOM node is emitting events. I assumed it was the select tag, but it’s not.

Which DOM node is emitting select2 events?


#2

According to the Select2 documentation, the events are emitted from the underlying HTML <select> element. That is where you attach event handlers for the Select2 events.

What result are you seeing from your library? Are you able to attach an event handler directly to the <select> element yourself (rather than using your library)?


#3

I attached an event manually in the console and nothing happened. I turned back visible the select box and manually changed selection, and it triggered an event.

So no, select2 is not triggering events.

I found in the documentation a mention for this, but I’m on phone now and can’t find it:

All select2 events are not jquery events, instead they are used as internal communication mechanism.
There is even an EventRelay adapter which I assume does what I need, but it doesn’t relay change (which select2 apparently listens to, not sure what it does with it).

I built a hacky solution that triggers change, works great, but I can’t help but feel dirty


#4

I can assure you that Select2 does indeed fire regular DOM events (probably created via jQuery) from the HTML select element, as documented here: https://select2.org/programmatic-control/events. The internal event system you mentioned is not used for the events documented at the url above, but rather for Select2 plugins.

Without seeing your code I can’t say why it doesn’t work, but I have written code that listens for and responds to Select2 events, so I know it works.

If you can post your code somewhere (codepen.io, for example) so I can look at it and run it, I’ll be glad to help you further. But I can’t do much without seeing your accrual code.


#5

Hello @John30013

Here is a pen showing the problem:
https://codepen.io/Fire-Dragon-DoL/pen/KjPzPW

I, on purpose, remove the class that hides the select element. You can clearly see that select2 doesn’t fire change event, but when I change the select HTML element, it does fire.

Cheers!


#6

The problem is that you are attaching the change event handler using regular JavaScript (not jQuery). It works if you use jQuery to attach the event handler (I’ve forked your pen to demonstrate: https://codepen.io/John30013/pen/PrqNzV?editors=1010)

Note that the Select2 events documentation shows using jQuery to attach the event handler. I imagine that the Select2 widget has to intercept the attachment of the event listener to be aware that it needs to fire it, and attaching the event listener with plain JavaScript (whether before or after initializing the Select2 widget—I tried it both ways) doesn’t notify the Select2 widget that it needs to fire that event.

(The Select2 documentation probably should be more explicit on this point, but I suppose the authors reasoned that if you’re using the Select2 widget in the first place—which requires jQuery—you would also use jQuery to attach event handlers.)


#7

That makes a huge difference though.

It means select2 can’t be transparently integrated with other libraries because it uses a custom event dispatching system.

Thanks for the help, I’ll stick to my hack in that case (I relay the change event onto the select element)


#8

Well, Select2 is a jQuery plug-in, so any other library would have to respect jQuery in order to use Select2. I guess it’s semantics, but Select2 has to fire its own version of the events because:
a. Select2 adds extra data about the selected item to the change (and change.select2) event,
b. Programmatically selecting an item in a <select> does not trigger its change native event, and
c. All the other Select2 events are non-standard, so must be generated and fired programmatically.
Given that, I suppose you could say it uses a “custom event dispatching system”, but I don’t see any other alternative. Anyway, the events it dispatches are DOMEvents, and (FYI), jQuery does exactly the same thing when it generates its custom events.

FYI, your “hack” is doing exactly what Select2 does, you’re just attaching the event handler in a different way (one that Select2 isn’t aware of).

I have successfully integrated Select2 with AngularJS and Angular.io, both of which have their own event systems as well. So it’s entirely possible to use Select2 with other frameworks. I’m curious what library you’re using that doesn’t seem to work with Select2’s events.

Finally, I don’t think Select2 bills itself as transparently integrating with other libraries, so you might be expecting more than it promises. In any event, if you have a solution that works for you, then that’s what’s important. Good luck with the rest of your project!


#9

Hey @John30013
Thanks for the through explaination.
You are probably right, it’s definitely my expectation that was set wrong. My hack works which kind of settles it, but for completeness (or OCD :laughing: ), let me explain what I meant:

The framework I’m using is unpoly, which delivers a whole set of night utilities that build really well if you use HTML in the most canonical way possible.

So for example, in this specific case every time one field is updated in a form (on change event), an AJAX request is automatically sent to the server, using the whole form data, the response is rendered in HTML but unpoly replaces only some selectors (specified by the developers - could be the whole form) in the current page using JS. These selectors are usually the “error fields”, so I can basically “move” server-side validation like if it was happening on the frontend, by writing zero javascript (I have to add one attribute to the input fields).
The advantage with this approach is that it integrates very well with old applications that used to do everything with server-side rendering and downgrades really well (at worse, you get validation only when the form is actually submitted by the user).

So, in this case unpoly tries to listen to change on all form fields, but since the select input select2 is using doesn’t fire any canonical events, the validation is never fired.
There are various workarounds, but this one with relaying the event is very effective (the validation doesn’t need to check any field on the event, it just needs to know it was fired).


#10

Interesting. I’ve never heard of unpoly before, but based on your explanation I can see how it wouldn’t work straight out of the box with Select2, now that we know Select2 needs event handlers attached via jQuery. In that case your approach sounds reasonable.

Good luck with your project!