Use cases for Turbo's Custom Events
Turbo emits various Custom events before, during and after certain actions. Knowing this helps you write cleaner and more maintainable code, without reinventing the wheel.
I want to give a few ideas and suggestions on how you could use them. Let me know if you have other suggestions I should add. ✌️
Loading state on frame load
When the content to be loaded in a frame takes some time, you can show some loading state, eg. a spinner.
You can add some loading state or Skeleton UI for the first load by simply adding it within the turbo-frame, but if you are reloading that frame, this won’t work.
But using the events turbo:before-frame-render and turbo:frame-render->frames it’s pretty doable!
<turbo-frame id="my-frame"
data-controller="loading"
data-action="
turbo:before-frame-render->frames#showSpinner
turbo:frame-render->frames#hideSpinner
">
</turbo-frame>
The JavaScript could, at its basics, look like this:
// app/javascript/controller/frames_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["spinner"];
showSpinner() {
this.element.insertAdjacentElement("afterbegin", this.#spinner);
}
hideSpinner() {
this.spinnerTarget?.remove();
}
// private
get #spinner() {
const spinner = document.createElement("div")
spinner.setAttribute("data-frames-target", "spinner");
spinner.textContent = "Loading…";
return spinner;
}
}
Similar methods for loading a page (turbo:before-render and turbo:render) also exists. You could apply the same technique.
Reset form on submit
There are multiple ways to reset a form with Turbo. You can replace it with (if a partial) using Turbo Streams, but you can also use turbo:submit-end. All it needs is a simple Stimulus controller. A general-purpose, form controller works great for this.
// app/javascript/controllers/form_controller.js
export default class extends Controller {
reset({ detail: { success } }) {
if (success) {
this.element.reset()
}
}
}
This would only reset the form if the request was successful.
Then your HTML form:
<form data-controller="form" data-action="turbo:submit-end->form#reset">
</form>
And there you have it. Some ideas to inspire you to use Turbo’s custom events. As mentioned, if you have a good use case, do feel free to share them so I can add them in this article. ❤️
Want to read me more?
-
How to add a skeleton UI to Rails with Turbo
Adding a skeleton UI to your Rails app helps with perceived loading speed. It's easy to do using Turbo Frames! -
Visual loading states for Turbo Frames with CSS only
Learn how to add instant loading feedback to your Turbo Frames without JavaScript. I'll walk you through using the aria-busy state with CSS pseudo-elements to show text or animated SVG spinners during slow requests. -
Conditionally Style Turbo Frame Content
Using a simple Tailwind CSS plugin, you can conditionally style HTML if it's a turbo-frame or not. Allowing you to reuse HTML.
Over to you…
What did you like about this article? Learned something knew? Found something is missing or even broken? 🫣 Let me (and others) know!
Comments are powered by Chirp Form
{{comment}}