Hotwire Discussion

Post form not changing URL

Hi. So, i have this basic action

 def create
    @campaign = @business.campaigns.new campaign_params
    if @campaign.save
      redirect_to business_campaign_compose_path(@business, @campaign)
    else
      render :new, status: :unprocessable_entity
    end
  end

and when i post a form into this URL, the redirect is successful, but the url dosen’t change, and ideas why? i get the rendered page successfully, but the URL wont change

  • Is your form operating in a turbo_frame?

    turbo_frame_tag “new_campaign” do
    ← your form →
    end

No, its not inside a turbo frame

I think you might be redirecting to a new campaign rather than to the already created camapign at: campaign_path(@campaign)?

no, actually its the same. The thing is that it’s a multi-step wizard, where each step has it’s own url and content. and i need to animate the progressbar at the top on each step. The thing is the way im doing currently isnt really good. Let me tell you how i do it, let’s say the user finished step 1 and posts the form, so now they should be at step 2. This is what i return in step2.turbo_stream.erb

<%= turbo_stream.replace "content" do %>
  <span data-controller="connected-dispatcher"
        data-connected-dispatcher-event-name-value="compose-message"
        data-step-class="w-4/12">

  </span>

  <span data-controller="change-url"
        data-change-url-url-value="<%= business_campaign_compose_path(@business, @campaign) %>">

  </span>

  <%= render 'content', business: @business, campaign: @campaign %>
<% end %>

the first two spans will just dispatch an event when they are connnected to the DOM. The second span will dispatch a change-url event that this controller will manage

import {Controller } from "stimulus";
import { Turbo } from "@hotwired/turbo-rails";

export default class extends Controller {
    static values = {
        url: String
    }

    connect() {
        this.update();
    }

    update() {
        history.pushState(
            { turbo_frame_history: true },
            "",
            this.urlValue
        );
    }
}

but this kinda creates an empty navigation, and i dont really want to manually override the url by myself.

IF you are returning a turbo-stream upon a successful form submission, and the DOM is actually being replaced (as per your example above) i’m not sure that the URL will actually change. I think this is the expected behaviour? The URL doesn’t seem to change in this example here: https://youtu.be/eKY-QES1XQQ?t=304 — maybe someone else can confirm this?

If you don’t want to manually change the URL with a stimulus controller, another option could be to use turbo_frames rather than returning a turbostream which replaces the “content” dom element. with the turbo_frame approach, you may have to persist an inchoate model somehow.

# something like this
# step1_controller.rb
   def create
      if form_is_valid?
         redirect_to new_step2_path # and render step2 of the form - but then the URL changes automatically
     end
   end

step1/new.html.erb
turbo_frame "new_form" do
  <-- step 1 of the form -->
end

step2/new.html.erb
turbo_frame "new_form" do
  <-- step 2 of the form -->
end