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
}
}
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-railscreated. We create a scaffold for products and within the form partial of the products, we wrap the form elements in aturbo_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
FrameControllerclass, I modified theloadResponsefunction. I added theconst htmlwhich before was simply inside of thefragmentFromHTML, but the important bit is theelsestatement. It looks like theelementis 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 noelementis 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.