Is there a way to get the original HTML element that contains the data-action attribute when a Stimulus action is fired? I got this setup:
<div data-controller="copy">
<button data-action="copy#copy">
Click here to copy! <i class="fas fa-copy"></i>
</button>
<span data-copy-target="copy">This content here will be copied</span>
</div>
import { Controller } from "@hotwired/stimulus";
import showToastAttachedTo from "toaster";
export default class extends Controller {
static targets = ["copy"];
copy(event) {
if (window.navigator?.clipboard) {
window.navigator.clipboard.writeText(this.copyTarget.innerText);
showToastAttachedTo(event.target, "Copied successfully!");
} else {
showToastAttachedTo(event.target, "Copy failed, copy manually!");
}
}
}
When the text on the button is clicked, the Toast gets attached to the button and everything looks good. However, if the user clicks on the <i>-Icon inside of the button, the Toast gets attached to the Icon, which is not intended. Inspecting the event argument in copy, I found no property that returns the original <button> element, i.e. the “source” of the event. Neither target nor originalTarget nor currentTarget contain the original <button>.
I could use some heuristic like event.target.closest("[data-action=\"copy#copy\"]"), however this breaks apart as soon as there are multiple Stimulus controllers nested inside of each other or as the data-action becomes more complex, i.e. in some places data-action="click->copy#copy" is used instead.