Skip to content

Instantly share code, notes, and snippets.

@kaspermeyer
Created December 13, 2018 14:06
Show Gist options
  • Select an option

  • Save kaspermeyer/7fe28bb7c55c2810e7b5f3d5e67c1a44 to your computer and use it in GitHub Desktop.

Select an option

Save kaspermeyer/7fe28bb7c55c2810e7b5f3d5e67c1a44 to your computer and use it in GitHub Desktop.
Dispatch jQuery events as regular DOM events
# ~ Dispatch jQuery events as regular DOM events ~
#
# Delegated events are given a new name in the format `jquery:<original event name>`.
# If you delegate `ajax:send` you will be able to listen for `jquery:ajax:send`
# on native event listeners such as Stimulus actions and `EventTarget.addEventListener`.
#
# Notes:
# * The first parameter must be called "event".
# * The parameters can be accessed as members on the `event.detail` object.
#
# Example:
# delegate 'ajax:send', parameters: ['event', 'xhr']
# document.addEventListener 'jquery:ajax:send', (event) -> console.log(event.detail)
#
delegate = (eventName, {parameters}) ->
handler = (args...) ->
data = {}
data[name] = args[index] for name, index in parameters
delegatedEvent = new CustomEvent("jquery:#{eventName}",
bubbles: true,
cancelable: true,
detail: data)
data.event.target.dispatchEvent(delegatedEvent)
$(document).on(eventName, handler)
@kaspermeyer

Copy link
Copy Markdown
Author
# jQuery UJS
#
# Source: https://github.com/rails/jquery-ujs/wiki/ajax
#
delegate 'ajax:before',           parameters: ['event']
delegate 'ajax:beforeSend',       parameters: ['event', 'xhr', 'settings']
delegate 'ajax:send',             parameters: ['event', 'xhr']
delegate 'ajax:success',          parameters: ['event', 'data', 'status', 'xhr']
delegate 'ajax:error',            parameters: ['event', 'xhr', 'status', 'error']
delegate 'ajax:complete',         parameters: ['event', 'xhr', 'status']
delegate 'ajax:aborted:required', parameters: ['event', 'elements']
delegate 'ajax:aborted:file',     parameters: ['event', 'elements']

@kaspermeyer

kaspermeyer commented Dec 13, 2018 •

Copy link
Copy Markdown
Author
# Select 2 (v4.0)
#
# Source: https://select2.org/programmatic-control/events
#
delegate 'select2:closing',     parameters: ['event']
delegate 'select2:close',       parameters: ['event']
delegate 'select2:opening',     parameters: ['event']
delegate 'select2:open',        parameters: ['event']
delegate 'select2:selecting',   parameters: ['event']
delegate 'select2:select',      parameters: ['event']
delegate 'select2:unselecting', parameters: ['event']
delegate 'select2:unselect',    parameters: ['event']

@kaspermeyer

Copy link
Copy Markdown
Author
# Bootstrap (v4.1)
#
# Source: https://getbootstrap.com/docs/4.1/getting-started/javascript/#events
#
# ~ alert
delegate 'close.bs.alert',        parameters: ['event']
delegate 'closed.bs.alert',       parameters: ['event']
# ~ carousel
delegate 'slide.bs.carousel',     parameters: ['event']
delegate 'slid.bs.carousel',      parameters: ['event']
# ~ collapse
delegate 'show.bs.collapse',      parameters: ['event']
delegate 'shown.bs.collapse',     parameters: ['event']
delegate 'hide.bs.collapse',      parameters: ['event']
delegate 'hidden.bs.collapse',    parameters: ['event']
# ~ dropdown
delegate 'show.bs.dropdown',      parameters: ['event']
delegate 'shown.bs.dropdown',     parameters: ['event']
delegate 'hide.bs.dropdown',      parameters: ['event']
delegate 'hidden.bs.dropdown',    parameters: ['event']
# ~ tab
delegate 'show.bs.tab',           parameters: ['event']
delegate 'shown.bs.tab',          parameters: ['event']
delegate 'hide.bs.tab',           parameters: ['event']
delegate 'hidden.bs.tab',         parameters: ['event']
# ~ modal
delegate 'show.bs.modal',         parameters: ['event']
delegate 'shown.bs.modal',        parameters: ['event']
delegate 'hide.bs.modal',         parameters: ['event']
delegate 'hidden.bs.modal',       parameters: ['event']
# ~ popover
delegate 'show.bs.popover',       parameters: ['event']
delegate 'shown.bs.popover',      parameters: ['event']
delegate 'hide.bs.popover',       parameters: ['event']
delegate 'hidden.bs.popover',     parameters: ['event']
delegate 'inserted.bs.popover',   parameters: ['event']
# ~ scrollspy
delegate 'activate.bs.scrollspy', parameters: ['event']
# ~ tooltip
delegate 'show.bs.tooltip',       parameters: ['event']
delegate 'shown.bs.tooltip',      parameters: ['event']
delegate 'hide.bs.tooltip',       parameters: ['event']
delegate 'hidden.bs.tooltip',     parameters: ['event']
delegate 'inserted.bs.tooltip',   parameters: ['event']

@asecondwill

Copy link
Copy Markdown

Works for Zurb Foundation too.

delegate 'moved.zf.slider', parameters: ['event']

And then
<div class="slider visits-slider" data-action="jquery:moved.zf.slider->provision#update">

@asecondwill

asecondwill commented Apr 2, 2019 •

Copy link
Copy Markdown

This actually gives an errorJust noticed this doesn't work for ie11

Object doesn't support this action
Line 16 of the JS(converted from coffee)

delegatedEvent = new CustomEvent("jquery:" + eventName, {

original coffee:
delegatedEvent = new CustomEvent("jquery:#{eventName}",

@asecondwill

Copy link
Copy Markdown

CustomEvent isn't supported in ie11, but there is a polyfil which worked great for me:

https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent


(function () {

  if ( typeof window.CustomEvent === "function" ) return false;

  function CustomEvent ( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: null };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
   }

  CustomEvent.prototype = window.Event.prototype;

  window.CustomEvent = CustomEvent;
})();

@n4cr

n4cr commented Aug 13, 2020

Copy link
Copy Markdown

This is a noob question but how should I use this coffee script? I have my project fully setup with backend django and stimulusjs with webpack. I don't get where I can include this delegator.

Thanks in advance

@kaspermeyer

kaspermeyer commented Aug 13, 2020 •

Copy link
Copy Markdown
Author

@n4cr Anywhere in your setup should be good. Make sure you have a CoffeeScript loader enabled in your webpack configuration.

@n4cr

n4cr commented Aug 13, 2020

Copy link
Copy Markdown

Thanks Kasper for the answer.

@n4cr

n4cr commented Aug 13, 2020

Copy link
Copy Markdown

In case someone needs this in JS:

const delegate = function (eventName, parameters) {
  const handler = (...args) => {
    const data = {}
    parameters.forEach((name, i) => data[name] = args[i]);
    const delegatedEvent = new CustomEvent("jquery:" + eventName, {
        bubbles: true,
        cancelable: true,
        detail: data
      }
    )
    data.event.target.dispatchEvent(delegatedEvent)
    console.log(delegatedEvent);
  }
  $(document).on(eventName, handler)
};

@leastbad

leastbad commented Sep 7, 2020

Copy link
Copy Markdown

I wish I'd seen this thread a long time ago!

I ended up creating jquery-events-to-dom-events to handle this problem in a way that would drop right into Stimulus controllers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment