Search code examples
javascriptruby-on-railsjquery-select2stimulusjs

How do I Listen to Select2 Events in a Stimulus Controller?


I am trying to listen to a Select2 event in a Stimulus controller via the data-action.

I have a stimulus controller, where I have included an event listener for Select2 events, but I cannot listen for the Select2 event from the HTML.

import { Controller } from 'stimulus';

export default class extends Controller {
  initialize() {
    const $element = window.$(this.element);

    $element.select2({
    });

    $element.on('select2:select select2:unselect', (_event) => {
      this.element.dispatchEvent(new Event('change'));
    });
  }
}

I have to listen to the "change" event with the Stimulus data-action attribute, instead of "select2" events. The following code works. Listening via data-action-"select2:select" does not work.

<%= f.select :name, ['name1', 'name2'], data: {'controller' => 'select2'} %>

I would like to listen to events with the data-action attribute, as Stimulus is intended to be used.

Can I listen for Select2 events with Stimulus?


Solution

  • I like the approach from https://psmy.medium.com/rails-6-stimulus-and-select2-de4a4d2b59e4

    Make one incision into the connect() method of the controller that is responsible for capturing the select2 event and send it back out as a standard change event so that 'data-action': "change->controller#update" will work as expected.

    import {Controller} from '@hotwired/stimulus';
    
    export default class extends Controller {
      static targets = ["select"];
      
      connect() {
        $(this.selectTarget).on('select2:select', function () {
          let event = new Event('change', { bubbles: true }) // fire a native event
          this.dispatchEvent(event);
        });
      }
    
      update(event) {
        console.log("UPDATE");
      }
    }
    <div data-controller="selector" >
      <select 'data-criteria-form-target': 'select',
              'data-action': "change->controller#update">
    </div>