DEV Community

Rails Designer
Rails Designer

Posted on • Originally published at railsdesigner.com

Use cases for Turbo's Custom Events

This article was originally published on Rails Designer


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>
Enter fullscreen mode Exit fullscreen mode

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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()
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)