Redirect After A Form Submission

I have a form inside a <turbo-frame id=‘modal’> tag. I render into this any forms that need displaying.
The forms have a stimulus controller attached that shows the modal on connect.

One form captures a barcode, and upon submission I want to find the item associated with the barcode and simply redirect to a show page for it.

However, I cannot figure out how to do this. I’ve tried just about every permutation of targets, gets/posts and statuses etc… the best I’ve managed is to have the redirect be rendered, but not replace the URL or entire page.

I gave up on this a while ago and simply served a bespoke turbo_stream action that I handle and redirect, but it’s always bugged me and I’d like to figure out the right way to do this.

Is this possible without taking the form out of a turbo frame (which I wouldn’t like to do if possible as I use the frame population to show the modal forms) ?

If i’m understanding correctly, you might be able to solve this by adding this to your form:

data: { turbo: false }

This seems to tell the form not to submit with turbo.

Quick example, I’m using it like so in a few situations:

data: { turbo: user_signed_in? }

So if a user is signed in, it does turbo stuff, replacing elements in page, while if a user is signed out, it submits normally so the user can be redirected to a sign up page.

The only downside of that is that I cannot use a turbo stream to re-render and display the form on errors then.

I was expecting this to be something I’ve missed in how to use Turbo and streams etc… and to get swiftly nudged in the right direction.

I’m beginning to think that my rendering of a bespoke redirect stream action wasn’t such a bad solution after all :smiley:

I think you need a 'data-turbo-frame' : '_top' on your form tag. That way, the redirect response will navigate you away from the frame. Since your id="modal" is probably enclosing your form tag, the turbo responses that updates it will work as intended.

See:
https://turbo.hotwired.dev/reference/frames#frame-that-drives-navigation-to-replace-whole-page

Yeah - I’ve tried that - that follows the redirect but it doesn’t update the page URL and (therefore) history.

I want to end up on the show page - with the show path in the URL.

Hum, strange. That works for me, can you show more of the relevant controller / view parts? A gist with the relevant files would be nice.

I setup a new test application and it worked, so I dug deeper into what was happening and after some time of stepping through the javascript of turbo I noticed that the response after the redirect wasn’t a full page response but a turbo stream.

It turns out that I had a show.turbo_stream.erb view, from long ago when I was first learning this, that was being rendered preferentially because the request was a turbo_stream, and because the response was a stream, turbo did what was it was asking :smiley:

I’m not sure if there is or should be an option to get the redirect to be requested as html and not turbo_stream somehow ?

Thanks for motivating me to look in to this in detail again :wink:

Nice! Convention over configuration can shoot yourself in a lot of ways sometimes since a lot of stuff is not explicit. I’m also learning Turbo/Stimulus after 7 years or so away from Rails and I am fighting similar mistakes :P. Good thing you worked out!

I’m also now curious if it’s possible to setup a different response upon redirection. The docs on Turbo doesn’t have much detail on the lifecycle of such things and how to dig into it.

Cheers
o/

I reckon I’ve visited every line of the turbo.js code through single stepping in the debugging to figure stuff out :smiley:

My javascript isn’t that good though so it’s taught me a lot.

I’m a big fan of the stimulus and turbo approach though. After doing a lot rendering page updates via ajax responses it seems fresh, clean and obvious - even though streams aren’t too different to explicit dom updates.

When turbo is closer to being released we should all put some effort into documenting all the ins and outs. There’s a lot to cover and the current documentation really only covers the core usage.

1 Like

Humm… Interesting idea about stepping into turbo with a debugger. I did a lot of different stuff on the past 2 years. React + Nest, Angular + RxJS + Firebase, Rails + Hotwire. Can’t decide which love most :). Nothing beats Rails on a quick CRUD, but when things gets more complex the field levels out a bit for me.

o/