When rendering a <form> inside comprehensions it appears too often and triggering events does result in even more <form> tags to be rendered:

You can see the error for yourself here: https://broken-live-view.herokuapp.com
The source code is available here: https://github.com/ream88/broken_live_view
Each <form> should only be rendered once.
I tried debugging this and right now I'm thinking it's actually a bug in morphdom. The inputs to the morphdom call are correct on the LiveView side, but the resulting DOM structure contains duplicates.
I think I'm running into the same issue… any word on progress on this bug?
@snewcomer I'd love your help on this one since @wrren's digging seems like a morphdom issue, but I will try to recreate and verify on the Elixir side to rule out an issue on our side. Comprehensions are treated specially so it's possible we aren't building the correct HTML before passing off to morphdom
I think I had a similar issue; I seem to have fixed it by adding a unique as: attribute for each form:
<%= for event_cs <- @events do %>
<%= f = form_for event_cs, "#", [phx_change: :validate, class: "row", as: "event#{event_cs.data.id}"] %>
…
Then, in my validate handler I broke apart the params I was getting to find the right key:
def handle_event("validate", params, socket) do
"event" <> event_id =
Map.keys(params)
|> Enum.find(fn i -> Regex.match?(~r/^event(?:\d*)$/, i) end)
…
{:noreply, socket}
end
Feels like a bit of a kluge, but it seems to work for now. ¯\_(ツ)_/¯ Do you think we need to add something like a key to each element rendered by a comprehension? (Kind of like how React, Vue, etc. do?)
I run into similar issue as well. When I inserted elements into an assign from which a for comprehension was rendering forms, the inputs in forms were not rendered correctly. @ashton314 suggestion to add as option made it work as intended.
@lukaszsamson This is a common issue we have come across and have learned (seems you have too) that if you are inside a loop, we need to make sure 1. No duplicate id attributes 2. but also that elements can be identified clearly by the diffing algorithm.
So in the broken_live_view repo above <input type="text" name="text" value="<%= text %>" id="text-<%= id %>" /> will solve the issue.
Scott is correct here. Duplicate IDs cannot be diffed properly and it's not something we can handle on our side because IDs are supposed to be unique. Hope that helps. Thanks!
just wanted to say that adding unique id attrs to HTML tags will solve the issue. thanks @chrismccord and @snewcomer for stopping me from tearing out my hair! :)
Most helpful comment
just wanted to say that adding unique
idattrs to HTML tags will solve the issue. thanks @chrismccord and @snewcomer for stopping me from tearing out my hair! :)