Closed drnic closed 1 year ago
You'll want to remove the on
prefix in the event name. Here's an example.
TurboReflex.registerEventDelegate('mouseover', ['p[data-turbo-reflex]'])
Let me know if this works for you.
Note that after the lib rebrand to TurboBoost Commands, this code should be changed to:
TurboBoost.Commands.registerEventDelegate(...)
@hopsoft I wanted to follow up on this conversation. I've attempted to register a keyup, keydown and keypress event but unfortunately it didn't trigger the command.
I unfortunately don't have a sample project for you at the moment and I'll see if I can take this local and do some debugging myself, but just wanted to put it on your radar.
Interesting. If it helps, this is where/how the library registers the default event delegates. https://github.com/hopsoft/turbo_boost-commands/blob/main/app/javascript/index.js#L92-L98
And here's where the library identifies a match when the event is triggered. https://github.com/hopsoft/turbo_boost-commands/blob/8217e3925fab7cb0f0ca2198f39ef82732dca85b/app/javascript/delegates.js#L17
Verified that we definitely have a bug related to registering additional events. The click handler is taking precedence. Will dive into this shortly.
I tested this current branch against keyup as well and that seems to still fail. I hope tomorrow to actually sit down and take a look at debugging.
EDIT
I was able to get this to work if I did the following
TurboBoost.Commands.registerEventDelegate("change", []);
TurboBoost.Commands.registerEventDelegate("click", []);
TurboBoost.Commands.registerEventDelegate("keydown", [
"input[data-turbo-command]",
]);
but unfortunately this prevented any actual value being typed in to the input
Excuse my stupidity but is there a specific reason to not use something similar to stimulus where you can bind the action with change->Command->method
Great question. Yes, there is a reason we opt for event delegation over per-element bound event listeners. Low level tools and libraries (like this one) can't make too many assumptions about the JavaScript ecosystem they're running within.
One example to illustrate the challenges is related to how StimulusReflex implicitly registers a StimulusJS controller for events that declare a data attribute that haven't already registered a StimulusJS controller with similar behavior. Detecting this is problematic because there's no way for the library to know how the JavaScript assets are organized or how they'll be loaded and parsed for a given application. This scenario is exacerbated with new techniques like import maps etc... Any client side Stimulus controller that's implicitly wired up can introduce unintentional and unwanted duplicate behavior (i.e. trigger RPC calls multiple times from a single client side event).
Event delegation eliminates this problem entirely, so it doesn't matter how the JavaScript assets are resolved, loaded, and parsed on the client. The primary caveat of delegation being that it limits us to bubbling events.
Having said that, event delegation also works with custom events and each registered delegate can include multiple selectors per event. Selectors for each delegate can be as simple or as sophisticated as desired.
In your example above, I would expect the following delegate to work.
const existingChangeDelegate = TurboBoost.Commands.eventDelegates.find(e => e.name === 'change')
TurboBoost.Commands.registerEventDelegate('change', [...existingChangeDelegate.selectors, '.my-element[data-turbo-command]'])
I could probably make this a bit more intuitive though.
Just created ticket #75 to help with event delegate overrides.
In https://github.com/hopsoft/turbo_reflex/blob/main/README.md#reflex-triggers it suggests we can override default events with
TurboReflex.registerEvent
but this method doesn't exist for me.I found
TurboReflex.registerEventDelegate
but I couldn't get it to registeronmouseover
or some other event types.Similarly, I tried inline custom events like
data-turbo-reflex="onmouseover->CounterReflex#increment"
but didn't see the reflex action trigger.