How to update current url with query params

Hello,

I have the following idea for a search functionality on index page: search form is implemented in modal dialog, which POSTs and receives a Turbo Stream that updates index page showing found data. However, this is not updating index page URL to reflect search parameters.

I tried to pin with turbo:before-fetch-request event with stimulus action that replaces URL with History
history.replaceState({}, "", event.detail.url.href), which seems at first to work just fine (current index page URL is reflecting the search result), however advancing and going back breakes the behaviour.

Is it possible to update URL in a manner that works with Turbo?

1 Like

What happen if you switch from a POST to a GET? If you are trying to update the URL search-params, then maybe GET is what you need. Unless you are using the POST simply so that you can get turbo-stream to work?

Sorry, I am already using GET in my search form.

I am evaluating using data-turbo-action="advance", however I think I don’t get how it works. From the docs, my search form with data-turbo-action="advance" should sent GET request and update browser address bar. However, I don’t see it performing the address bar update part. Does it work only for a href="url" links?

Even with data-turbo-action="advance", I think your form method might still need to be get. I’m not 100% sure - I don’t think I’ve tried to use advance with a POST. What is your form method?

It is GET. I was wrong about using POST in my 1st post.

Hmmm, I’m not sure, sorry.

I assume you’re missing few bits:

<%= form_with(..., url: some_path, data: { turbo_frame: :my_frame, turbo_action: :advance },  method: :get ) do | form | %>
 [..]
<% end %>

# Then
<%= turbo_frame_tag :my_frame do %>
Loading...
<% end %>

Again I will assume you’re getting data from a controller and assign it to an instance variable then the updated code would be:

<%= turbo_frame_tag :my_frame do %>
  <%= render "my_partial", instance: @variable %>
<% end %>

I tried to write to the URL/turbo state but could not get it to work… I’m not using a form but conceptually the same.

Hi, might the turbo_power gem be a soulution?
There is a push_state function.

i played with it in my gem render_turbo_stream and it looks solid.
The attempt here is to make it easier to handle the turbo-stream commands.

Hi @SylarRuby,

In fact my code is very similar to what you wrote, at first look I see only one significant difference: my response with search results is rendered as collection of <tr>s with dom_id() instead of turbo-frame (which will not work inside table tag). Turbo stream template renders them with update stream action, targeting my table body with id="body". This works well.
What I am missing is how search response can update browser’s history(). According to Turbo docs

To promote a Frame navigation to a Visit, render the element with the [data-turbo-action] attribute.

Does it mean I have to use `data-turbo-action=“advance” with search form code or in the rendered response? This part is not clear to me.

Hi,

@christian1 I think that Turbo-rails is capable of what I want to achieve, it is stated in the docs mentioned earlier. So no need for another gem just for that. Unless I am wrong :slight_smile:

So no need for another gem just for that.

Correctly.

Only: turbo_power depends on the rendering method, i.e. you have to render with turbo stream to perform these actions. As I understand your question, this is the case.

From what I can tell, maybe restructuring the HTML document might help out.

Could you wrap the whole table in a turbo frame?

(Sending a drawing/wireframe/screenshots of what you want might help us help you better)

(Blasting in here with my pet peeve about the custom-element design decision:) The whole reason to use a table is to present a structured collection of data. Wrapping that collection in a single turbo-frame ruins the reason to use Turbo – surgical replacement of only the changed part(s) of that collection.

Walter