-
Notifications
You must be signed in to change notification settings - Fork 425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamically mounting an action to Stimulus #478
Comments
Would declaring an event listener within your controller suit your needs? // dropdown controller
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
addEventListener("click", this.hide)
}
disconnect() {
removeEventListener("click", this.hide)
}
hide = (event) => {
// ...
}
} If you'd need to conditionally listen based on some other // dropdown controller
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
disconnect() {
removeEventListener("click", this.hide)
}
expand() {
// ... show the dropdown
addEventListener("click", this.hide)
}
hide = (event) => {
// ... hide the dropdown
removeEventListener("click", this.hide)
}
} |
@seanpdoyle thanks for coming back to me! Indeed, it is possible to do so, this is my current implementation: import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["button", "dropdown"]
toggle (event, shouldHide) {
let hidden = !!shouldHide ? shouldHide : this.dropdownTarget.classList.contains("hidden")
this.dropdownTarget.classList.toggle("hidden", !hidden)
this.dropdownTarget.setAttribute("aria-expanded", !hidden.toString())
hidden ? addEventListener("click", this.hide, true) : removeEventListener("click", this.hide, true)
}
hide = event => {
if (!this.buttonTarget.contains(event.target)) this.toggle(true)
}
} However, I think there are several drawbacks:
|
How about this implementation @elvinaspredkelis ? https://stimulus-use.github.io/stimulus-use/#/use-click-outside
|
Sorry to waist everyones bandwidth here - but I can't help thinking if the issue is related to my "observation" ? (quick resumé: if an element is 'hidden' it's action will not "work" if the element at some later point in time gets 'unhiddened' - or, that's my observation, at least, and as I duly posit: I'm sure it's on me) am I way off here? |
Would the 3.1.1 feature See docs - https://stimulus.hotwired.dev/reference/actions#options |
Another way to dynamically add an action is to actually (re)-write the this.element.dataset.action = `click->${this.identifier}#myDynamicAction` or if you want the respect the previous value: this.element.dataset.action = `${this.element.dataset.action} click->${this.identifier}#myDynamicAction` We could also abstract it away in a function call itself, here's a rough sketch from a few months ago: https://gist.github.com/marcoroth/64c308d9e7be047a2061469ebe58daea |
@marcoroth do you know if a specific version of stimulus is required to dynamically add an action by re-writing the |
Hey @MrHubble, no this shouldn't be version dependent as it's just setting an attribute via the native DOM API. Can you share what you've got? |
@marcoroth of course after coming back to this I can no longer replicate this issue 🤦♂️ |
Hey!
First of all, I am a big fan of Stimulus 🎉
Recently, I found myself missing a way to dynamically adding actions. Is there a way to do so? Or, perhaps, there only be a way to do it eventually?
Use case
Handling a dropdown menu via JS, for example. Currently, I am collapsing such menus via something like
click@window->dropdown#hide
which is not ideal: it adds a lot of unnecessary events, fills up the debug mode and it only gets worse if there are more such dropdowns.Obviously, it is possible add
window.addEventListener(...)
, however, it becomes "detached" from the controller. So it would be nice to keep things consistent.Expected functionality
Perhaps having an exposed
Action
class and/or mounting method could be an option.Referring to the above mentioned use case, it would be possible to mount a new action when the dropdown is opened:
new Action(element, index, descriptor)
and then destroy this action upon disconnect.P.s.
Not sure if this is a question or a feature request. I have tried searching for an answer, however, with no luck. Also, I am not that sure if this is a bad practice and/or is inconsistent with the Stimulus codebase or the way it is mounted.
The text was updated successfully, but these errors were encountered: