Listening to jQuery events on Stimulus actions like `ajax:success`

Motivation
Some of you might have worked on projects using jQuery and struggled with the lacking ability to listen for jQuery events on Stimulus actions.

I was working on a project where I needed to listen to the jquery_ujs request lifecycle events like ajax:success on my Stimulus actions and I didn’t have the option to replace it with rails-ujs, so I wrote a small wrapper in CoffeeScript to solve this issue.

Solution

How it works
There’s not a lot to it. Internally it catches, converts and re-dispatches jQuery events as regular DOM events.

It prepends jquery: to each delegated event name. The jQuery event ajax:beforeSend is dispatched as the native event jquery:ajax:beforeSend.

Usage

I’ve posted some templates for popular libraries like jQuery UJS, Bootstrap, and Select2 in the comment section of the gist. Feel free to add your own as well.

Delegate the jQuery event with the parameters specified in the documentation:

# jquery_event_delegators.coffee
delegate 'ajax:beforeSend', parameters: ['event', 'xhr', 'settings']

Listen for the event with a Stimulus action:

<!-- slideshow.html -->
<a ... data-action="jquery:ajax:beforeSend->slideshow#prepareSlides">

Handle it in your Stimulus controller

// slideshow_controller.js
prepareSlides(event) {
  event.detail // { event: {...}, xhr: {...}, settings: {...} }
}

You can attach listeners to regular event targets as well:

document.addEventListener('jquery:ajax:beforeSend', function(event){ ... })

Accessing data
The event handler can access the delegated parameters as members on the event.detail object.
For example ajax:beforeSend defines three parameters: event, xhr and settings which makes the detail object look like this:

That’s it. I hope some of you finds this helpful :slight_smile:

5 Likes

For those of you looking for a non-coffee solution, I created a package called jquery-events-to-dom-events that was designed to be dropped right into Stimulus controllers.

1 Like