jQuery plugin event and Stimulus actions?

I’m trying to listen to a Chosen.js event (a jQuery plugin) but I’m not sure how to do this when I’m not using a build. I read these notes about listening to jQuery events on Stimulus actions:

Listening to jQuery events on Stimulus actions like ajax:success

But I’m confused as to how to incorporate jquery-events-to-dom-events - npm which the article points to.

Basically I have this element:

data-action="change->my-controller#myFunction"

And the Chosen event is

$("#form_field").chosen().change( … );

(Chosen styles a select field.)

1 Like

I tried to get it working similar to the package you shared but couldn’t catch Chosen events.
A workaround could be:

import {Controller} from 'stimulus';
import 'chosen-js'

export default class extends Controller {
    connect() {
        $(this.element).chosen().change(e=>{
            console.log(e);
        })
    }
}

Not ideal though because you cannot catch the event on the controller and call a method on a different controller.

2 Likes

Hey just saw this–thanks for the workaround. (In the end I switched to select2, which worked out of box with StimulusJS)

FWIW Personally in this category I’d like to give a shout out to Slim Select (no JQuery dependency either).

Here is an example of a Stim wrapper I’m using for Slim Select. ( Credit to Slim-select stimulus controller · GitHub )

// app/javascript/controllers/shipments/entity_dropdown_controller.js

import { Controller } from "stimulus"
import SlimSelect from "slim-select"
import "slim-select/dist/slimselect.min.css"
import '../../css/slimselect.css'

export default class extends Controller {
  static values = { fromStream: Boolean }

  connect() {
    const limit = this.data.get("limit")
    const placeholder = this.data.get("placeholder")
    const searchText = this.data.get("no-results")
    const closeOnSelect = this.single
    const allowDeselect = !this.element.required

    this.select = new SlimSelect({
      select: this.element,
      closeOnSelect,
      allowDeselect,
      limit,
      placeholder,
      searchText,
      onChange: (info) => {
        const el = this.select.select.element.nextElementSibling
        const className = 'ss-is-selected'
        if (info.value === '') {
          el.classList.remove(className)
        } else {
          el.classList.add(className)
        }
      }
    })

    if (this.fromStreamValue) {
      Rails.fire(document, 'close-modal')
    }
  }

  get single() {
    return !this.element.multiple
  }
  get multi() {
    return this.element.multiple
  }

  disconnect() {
    if (this.select) {
      this.select.destroy()
    }
  }
}
  <%= l.select :part_id, parts, {prompt: "Select Part"},
               { data:
                 {
                   "controller": "shipments--entity-dropdown",
                   "shipments--entity-dropdown-from-stream-value": false
                 }
               }
``
1 Like