Skip to content

Some thoughts about turbo-frame-tags when the redirected render doesn't contain any turbo-frame-tags that match the original #94

@kobaltz

Description

@kobaltz

Firstly and perhaps most importantly, thank you so much for Turbo. I really enjoy it!

Let's take a very simple example of a new Rails application with hotwire-rails created. We create a scaffold for products and within the form partial of the products, we wrap the form elements in a turbo_frame_tag 'product'. The expected behavior now is if there are any validation errors, it renders the page with the validation errors. Turbo accomplishes this already.

However, if there are no validation errors and the record persists successfully, then I would expect it to render the display of the show page. However, because there is no turbo-frame-tag on the show page, it doesn't do anything and we still have the form displayed.

I think that this is very unexpected behavior even though things make sense with turbo. I know that this functionality has caused me a few headaches initially and also the community with trying to find proper workarounds.

I'm not the best Javascript person out there, but dabbled around in it a bit, so I would leave any PR to the experts. However, I did pull in the turbo library from turbo-rails into my application to tinker with things and came up with a minor-ish fix.

Within the FrameController class, I modified the loadResponse function. I added the const html which before was simply inside of the fragmentFromHTML, but the important bit is the else statement. It looks like the element is the rendered result from our Rails application and the turbo-frame-tag has been plucked out as a fragment of the original rendered response. So, if no element is found, then that means that the rendered page did not have any turbo-frame-tags which means that our UI will look like it did not perform any action.

My thought here is to replace the body of the current page, with the entire contents of the rendered response in the event that no turbo-frame-tag was found within the response.

  async loadResponse(response) {
    const html = await response.responseHTML
    const fragment = fragmentFromHTML(html);
    const element = await this.extractForeignFrameElement(fragment);
    if (element) {
      await nextAnimationFrame();
      this.loadFrameElement(element);
      this.scrollFrameIntoView(element);
      await nextAnimationFrame();
      this.focusFirstAutofocusableElement();
    } else {
      document.getElementsByTagName("html")[0].innerHTML = html
    }
  }

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