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. ❤️