New to stimulus and trying to find the correct pattern here. I have a collection of form items with a hidden submit button by default. When you click into the input the submit button reveals.
As you click into other inputs the previously active submit button disappears and the new one reveals. If you click outside all inputs, there is a global data-action="click@window->editor#hideButton" that hides the submit button.
If you run the snippet it has the exact UX I'm looking to implement. However, attaching the global window event to every instance of the controller seems like overkill. Additionally, this global click is fired every time there is a click on the page for other actions.
This pattern works in a modal context, but feels off in my collection example. In my example the hideButton function will be called 4 times on every click. Even when interacting with other elements on the page.
https://discuss.hotwired.dev/t/best-practices-for-handling-clicks-outside-element/1266
I've read creating a controller for each item in the collection is the correct approach.
Is leaning on this global event the right approach for Stimulus? Or, should I rethink the approach entirely to achieve the UX (realize I may be way off in my architecture).
const application = Stimulus.Application.start()
application.register("editor", class extends Stimulus.Controller {
static targets = ["button"]
showButton() {
this.buttonTarget.classList.remove("hide")
}
hideButton() {
if (this.element === event.target || this.element.contains(event.target)) return;
this.buttonTarget.classList.add("hide")
}
})
.hide {
display: none;
}
li {
margin: 10px;
background: gray;
width: 230px;
}
input:hover {
cursor: pointer;
}
ul {
list-style: none;
}
<script src="https://unpkg.com/stimulus@2.0.0/dist/stimulus.umd.js"></script>
<ul>
<li data-controller="editor" data-action="click@window->editor#hideButton">
<form>
<label>Item1</label><br>
<input type="text" data-action="click->editor#showButton">
<input class="hide" type="submit" value="Submit" data-editor-target="button">
</form>
</li>
<li data-controller="editor" data-action="click@window->editor#hideButton">
<form>
<label >Item2</label><br>
<input type="text" data-action="click->editor#showButton">
<input class="hide" type="submit" value="Submit" data-editor-target="button">
</form>
</li>
<li data-controller="editor" data-action="click@window->editor#hideButton">
<form>
<label>Item4</label><br>
<input type="text" data-action="click->editor#showButton">
<input class="hide" type="submit" value="Submit" data-editor-target="button">
</form>
</li>
<li data-controller="editor" data-action="click@window->editor#hideButton">
<form>
<label>Item4</label><br>
<input type="text" data-action="click->editor#showButton">
<input class="hide" type="submit" value="Submit" data-editor-target="button">
</form>
</li>
</ul>