Skip to content

New Event: Turbo-Frame Rendered #118

@KonoMaxi

Description

@KonoMaxi

When working with turbo, I badly miss an event which fires after Turbo completed doing it's "new magic" with frames, named somthing like turbo:frame-rendered.
I think it'd be an improvement, if you'd add it to the turbos specification. I've seen Issue 88, but it goes into a slightly different direction.
I also provided an example repo for my proposition, which shows the problem I faced.

I tried to build a a multi-step form (hereafter called stepper), where each step depends on its predecessor.
The stepper involves 3 steps which each have a stimulus controller attached, to do some step-specific styling and interactivity.
A fourth Stimulus Controller (hereafter called "orchestrator") spans the whole thing - it orchestrates the steps and saves state outside the turbo-frames.
I modeled each step as a form in a turbo-frame.

When submitting step 1, I want the following things to happen:

  1. Clear Step 3 - in case something went wrong with step 1 it would show inconsistent data.
  2. when step 2's form is rendered, iterate over the checkboxes it contains and recheck everything that was previously checked (skipped this step in my example repo)
  3. immediately submit step 2 after the checkbox-business

I made a small schematic drawing to show what I have in mind.
stepper-illustration

I thought it to be clean design, that each step's JS is isolated - I didn't want the stimulus controller of step 2 to know about the existence of step 3 - its the orchestrators business. So I put data-action="turbo:submit-end->orchestrator#doStuff" on the forms, but this event is dispatched BEFORE the turbo-frame is updated. Thus the orchestrator submitted an old version of step 2 (very inconvenient). To get notified about step2 being replaced, I let a stimulus controller dispatch a "connected"-event in its connected() lifecycle hook - but orchestrator could not see data-action="connected->orchestrator#doStuff". Modifying connected() to setTimeout(() => this.element.dispatchElement("connected")) did the trick - but this feels wrong and hacky (also the delay is visible when ticking checkboxes).

If turbo would emit a turbo:frame-rendered-event, the steppers required JS would reduce significantly. Please feel free to view the example repo to see for yourself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions