All the examples/tutorials I have seen for building out controllers and targets for stimulus have the targets nested under a parent element that has been declared as using a data controller.
For example (from the handbook:
<div data-controller="slideshow">
<button data-action="slideshow#previous"> ← </button>
<button data-action="slideshow#next"> → </button>
<div data-slideshow-target="slide">🐵</div>
<div data-slideshow-target="slide">🙈</div>
<div data-slideshow-target="slide">🙉</div>
<div data-slideshow-target="slide">🙊</div>
</div>
Is there any recommendation or hard rule that the targets must be nested under the controller? Can the following be used:
<div data-controller="slideshow">
<button data-action="slideshow#previous"> ← </button>
<button data-action="slideshow#next"> → </button>
</div>
<div id="someOtherDiv">
<div data-slideshow-target="slide">🐵</div>
<div data-slideshow-target="slide">🙈</div>
<div data-slideshow-target="slide">🙉</div>
<div data-slideshow-target="slide">🙊</div>
</div>
Yes. In order for targets to relate to the controller, they need to be within that controller's scope. That means that you must have an element with data-controller="my-controller"
as the parent element for any HTML elements with data-my-controller-target="myControllerTarget"
. You can have a controller and a target on the parent element, though, and you can also have several controllers assigned to a single parent element. For the example you provided, I would recommend moving the controller declaration up to a common parent element.