Using pure JS set Select2 value and trigger events

251 Views Asked by At

I'm using grease monkey user script to restyle UI and automate initial input on some weird site, which uses jQuery and Select2.

I dealing with row containing two selects:

  • organization (options are loaded, empty option is selected, select control is enabled)
  • hall (no options, disabled).

I need to make selection in the first one to force second one to load corresponding option and become enabled.

Lets name orgSelect is a HTMLSelectElement with attached events and orgSpan is a "select + span > span.selection > span" element with attached events, created by Select2.

I can set orgSelect.value (obviously).

I can dispatch "change" event for orgSelect and see selected value rendered. But nothing going on with second select.

I can click orgSpan expecting dropdown action (I even seen such a example online and it works), but this doesn't work for me. No drop down on orgSpan.click().

So, I can set value for select2, but how to trigger it properly?

1

There are 1 best solutions below

1
Eduard Kolodka On

Wellp... somehow I found proper event chain. But I didn't tested it in pure JS. Because, first I decided to try to use jQuery from "unsafe" window and since it working I did the next:

  • rewrote code to jQuery;
  • had wrote wrapper for adding event handlers with exporting them to "unsafe" window;
  • found out that the behavior doesn't changed after switching from dispatchEvent() to jQuery.trigger() (I can set and render value, but no further actions starting after this - looks that devs don't use "change" event for that actions)
  • figured out that devs uses YII and googled the problem in this context
  • figured out that secondary select component even didn't initialized as Select2() after the main select value changed
  • after dozens of tries and looking different events across the html body I found the event for starting the actions (it was attached to one of the parents of select2 component):
    orgSelect.val(orgId);
    orgSelect.trigger('change'); // rendering new value
    orgSelect.trigger('select2:select'); // starting actions for secondary <select>