Rails 6 Stimulous JS Cheat Sheet

Official docs stimulusjs.org

Controller names

file: snake_case.js identifier: kebab-case

Always use dashes in data-controller values for multi-word controller identifiers. source

app/javascript/controllers/entries_search_controller.js (or entries-search-controller.js)

// app/javascript/controllers/entries_search_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  // ...
}
<div data-controller="entries-search"></div>
div data-controller="entries-search"

Action names

cammelCase

// app/javascript/controllers/entries_search_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  makeRequestNow() {
    alert("request was made (not really)");
  }
}
<div data-action="click->entries-search#makeRequestNow"></div>

<div data-action="click->entries-search#makeRequestNow" class="chip hoverable"></div>
div data-action="click->entries-search#makeRequest"

.chip.hoverable data-action="click->entries-search#makeRequest"

Target names

cammelCase

// app/javascript/controllers/entries_search_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "awesomeBands" ]

  fillAwesomeBands() {
    this.awesomeBands.innerHTML = "Atreyu, Deadlock, Trivium';
  }
}
<div data-target="entries-search.awesomeBands">
<div data-action="click->entries-search#fillAwesomeBands">Want to know awesome bands?</div>
div data-action="click->entries-search#makeRequest"

.chip.hoverable data-action="click->entries-search#makeRequest"

Lifecycle

import { Controller } from "stimulus"

export default class extends Controller {

  initialize () {
    // is called once per controller
  }

  connect () {
    // is called evvery time the controller is connected to the DOM.
  }

  disconnect () {
    // called when controller element is removed from the document:
  }
}

sources:

Set data on controller

  • this.data.has("melodicDeathMetalBand") returns true if the controller’s element has a data-entries-search-melodic-death-metal-band attribute
  • this.data.get("melodicDeathMetalBand") returns the string value of the element’s data-entries-search-melodic-death-metal-band attribute
  • this.data.set("melodicDeathMetalBand", "Deadlock") sets the element’s data-entries-search-melodic-death-metal-band attribute to the string value of “Deadlock”

stolen from: Stimulus cheatsheet by mrmartineau

How to fetch data values on various levels

// app/javascript/controllers/entries_search_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  giveMeSomeData(event) {
    // Access the Controller data
    console.log(this.data.get('categoriesLoadPath'));
    // => /band_search
    //
    // note: `console.log(this.data.get('categories-load-path'));` also works


    // Access data on currently clicekd element
    console.log(event.currentTarget.dataset.favoriteBand);
    // => Parkway Drive


    // Access data on a target
    console.log(this.topBandThisWeekTarget.dataset.bandName);
    // Gojira
  }
}
div data-controller="entries-search" data-entries-search-categories-load-path="/band_search"
  div data-target="entries-search.topBandThisWeek" data-band-name="Gojira"

  .chip.hoverable data-action="click->entries-search#giveMeSomeData" data-favorite-band="Parkway Drive" Click This !

How to use Rails.ajax to async replace HTML content with Stimulus JS

There is 2 ways how to do it. The RJS way or the render_to_string way. Both are equally fine, it’s just matter of taste.

I wrote separate notes explaining how to do each approach:

Sources