Search code examples
stimulusjs

Does Stimulus Targets Have to be Nested Under Stimulus Controller in the DOM?


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>

Solution

  • 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.