Stimulus
Stimulus is a JavaScript framework that ships with Rails. It provides a way to add client-side functionality to Phlex components with Stimulus controllers. For example, we can create a Stimulus component that copies a value from the DOM to the users clipboard.
// clipboard_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["source"];
async copyToClipboard() {
const valueToCopy = this.sourceTarget.dataset.value;
try {
await navigator.clipboard.writeText(valueToCopy);
} catch (err) {
console.error("Failed to copy text: ", err);
}
}
}
To bind this manually to a Phlex component, we use data tags to specify the controller and action. For example, we can add the following data attributes to a Phlex component:
🔓 Unlock content
Pre-order this course to unlock this video, source code, and content.
class LinkShare < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓ do
▓▓▓▓▓▓ data: { controller: "clipboard", action: "click->clipboard#copyToClipboard", value: "This text will be copied to your clipboard!" } do
"Copy"
end
end
end
end
Use helpers to cut-down on repetition
▓▓▓▓▓ ▓▓▓▓▓▓ ▓ ▓▓▓ ▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓ ▓▓▓
class LinkShare < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓ do
▓▓▓▓▓▓ **▓▓▓▓▓▓▓▓("clipboard", "click->clipboard#copyToClipboard",
value: "This text will be copied to your clipboard!"
){ "Copy" }
end
end
▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓
def ▓▓▓▓▓▓▓▓(▓▓▓▓▓▓▓▓▓▓, ▓▓▓▓▓▓, **▓▓▓▓▓▓▓)
{
data: {
▓▓▓▓▓▓▓▓▓▓:,
action:
}.▓▓▓▓▓(▓▓▓▓▓▓▓)
}
end
end
JavaScript and components without Stimulus
▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓ ▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓▓ ▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓
class LinkShare < ▓▓▓▓▓▓▓▓▓::▓▓▓▓
def ▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓ onclick: "copyToClipboard()", data_value: "This text will be copied to your clipboard!" } do
"Copy"
end
end
▓▓▓▓▓▓▓▓▓▓ <<~▓▓
function copyToClipboard() {
const valueToCopy = this.sourceTarget.dataset.value;
try {
await navigator.clipboard.writeText(valueToCopy);
} catch (err) {
console.error("Failed to copy text: ", err);
}
}
▓▓
end