How to show form validation errors?

I tried:

new.html.erb

<%= turbo_frame_tag "form" do %>
    <%= render 'form', course: @course %>
<% end %>

controller:

respond_to do |format|
      if @course.save
        format.turbo_stream { redirect_to edit_course_path(@course), notice: "Course was successfully created." }
      else
        format.turbo_stream
      end
    end

create.turbo_stream.erb

<%= turbo_stream.replace "form" do %>
  <%= render "form.html", course: @course %>
<% end %>

This way, I can show form validation errors, but then if the form is successful, it doesn’t redirect properly. I.e I can actually see these two requests happening behind the scenes.

If I don’t wrap the form in the turbo_frame_tag, then redirect works, but how can I then show form errors?

Edit: thanks to https://twitter.com/Intrepidd/status/1341482325280960519, the key is to add frame: “_top” to the turbo_frame_tag. E.g <%= turbo_frame_tag "form", target: "_top" do %>. Then redirects start to work.

2 Likes

Have you tried not wrapping the redirect_to in format.turbo_stream?

Here it says Turbo Drive expects an HTTP 303 redirect response: https://turbo.hotwire.dev/handbook/drive#redirecting-after-a-form-submission

We intend to allow HTTP 422 responses for form submissions inside frames, but it didn’t make the cut for the initial beta release.

For now, you can try sending a Turbo Streams response that re-renders your form with errors.

5 Likes

Is there going to be support for adding data-turbo=“false” to forms? I have some legacy forms where I just need to handle simple form submission (full page refresh to show validation errors is fine), but Turbo Drive does not appear to allow this.

Yes, there’s a pull request open for this but it didn’t make the cut for the initial beta release.

2 Likes