I’m trying to stream an object “question” twice on a single page. One to be displayed on a desktop view and another on a mobile view.
Whenever I copy the partial (below) on a single page, only the first partial in the line of code gets streamed live.
I would need to refresh the page in order for the second partial to be rendered.
<%= render @room.questions %>
Can Hotwire stream two turbo_frame_tags from the same object on the same page?
HTML does not allow two items on the same page to have the same ID. You will either need to use CSS to make the one thing look different in two different contexts, or you will have to give each one a unique ID.
Is there a way to change the dom_id with Hotwire?
I assumed I needed to change the the dom_id tag and render it in a different partial view. But when I did so, the dom_id remained the same as question_1, question_3 and question_3.
<div id="<%= dom_id question_mobile %>">
<%= render partial: "questions/question_mobile", collection: @room.questions, as: :question_mobile %>
The dom_id helper is great for the problem you’re trying to solve. If I’m understanding the architecture correctly, it sounds like you’re rendering a collection from an index action, than making changes to members of that collection in an update action? If so, it seems like what you’ll want is some view files that look something like…
<!-- app/views/questions/index.html.erb -->
<% @questions.each do |question| %>
<div id="<%= dom_id(question, :mobile)"><!-- Question on mobile --></div>
<div id="<%= dom_id(question, :desktop)"><!-- Question on desktop --></div>
<% end %>
<!-- app/views/questions/update.turbo_stream.erb -->
<%= turbo_stream.replace(dom_id(@question, :mobile)) do %>
<div id="<%= dom_id(@question, :mobile)"><!-- Question on mobile --></div>
<% end %>
<%= turbo_stream.replace(dom_id(@question, :desktop)) do %>
<div id="<%= dom_id(@question, :desktop)"><!-- Question on desktop --></div>
<% end %>
Am I understanding the problem you’re trying to solve?
Looks like I’m half way there .Your suggestions to change the dom_id worked. However, the object turbo_stream still doesn’t update for the new mobile dom_id loop.
I tried implementing your code with both :mobile and :desktop id but the original question stream stopped working with :desktop in the id (so I kept the original “dom_id question” for the desktop loop).
Is there a way to isolate and turbo_stream the new question mobile dom_id?
I’m not sure I understand what you’re trying to accomplish.
turbo_stream.replace(@question) is roughly equivalent to calling
turbo_stream.replace(dom_id(@question)). It sounds like you’re still broadcasting to
dom_id(@question), which is why reverting
dom_id(@question, :desktop) to
dom_id(@question) restored the behavior.
If you want to isolate the “mobile dom id”, you’ll have to explicitly broadcast to it, with
If you have two different elements, you’ll have to broadcast to them independently, since everything in turbo streams and turbo frames is identified by
id, which HTML requires to be unique.