Stimulus Cheatsheet
Connect element to controller
-
<div data-controller="country-filter">...</div>
- or in symfony/twig:
-
{{ stimulus_controller('country-filter') }}
-
- or with values:
-
{{ stimulus_controller('country-filter', myValuesArray) }}
-
Access the controller element
No need for a separate target!
-
connect() { console.log(this.element); }
Targets
-
<a data-slider-target="nextButton">
-
// slider_controller.js export default class extends Controller { static targets = [ 'nextButton', ]; connect() { console.log(this.nextButtonTarget); } }
Action
-
<div data-action="click->my-controller#doSomething">...</div>
Listen to an event @window
-
<div data-action="custom:event-name@window->my-controller#doSomething">...</div>
Values
-
<div data-controller="frame" data-frame-lazy-value="true" <!-- data- $controllerName - $valueName - value --> ></div>
-
export default class extends Controller { static values = { lazy: Boolean, url: { type: String, default: '/foo' }, } connect() { console.log(this.lazyValue); } }
Get the element clicked upon
<button data-action="click->header-nav#toggle"> toggle(event) { // Get the clicked element: var button = event.currentTarget; }
Communication between controllers
Access another controller
-
<div id="other-controller-id" data-controller="other-controller"></div
-
// foo_controller.js # this.application is the parent object for all controllers const otherController = this.application.getControllerForElementAndIdentifier( // the element of the other controller: document.getElementById('other-controller-id'), // the other controller's name 'other-controller' );
Alternative
The method described here
- https://stimulus.hotwired.dev/reference/controllers#cross-controller-coordination-with-events and here
- https://symfonycasts.com/screencast/stimulus/multi-controller-dispatch
did not work for me. Probably because the event receiving element is not an ancestor of the emitter?
Update: maybe params for this.application.getControllerForElementAndIdentifier() were wrong. Try again with the new information above "Access other controller"
Anyways, this worked:
- In the emitting stimulus controller dispatch a custom event:
-
var customEvent = new CustomEvent("myevent", { detail: { foo: 'bar' }}); window.dispatchEvent(customEvent);
-
-
Then bind this event in another controller normally via "data-action" attribute on any element inside the data-controller element:
-
<div data-action="myevent@window->other#anyMethod"></div>
-
-
This calls anyMethod() inside "other_controller"
-
updateCount(event) { console.log(event.detail) }
-
(From https://fullstackheroes.com/tutorials/stimulus/create-custom-events/)