I’m trying to build an LV-powered multistep form where the user is presented with a series of questions, with each question having a set of predefined answers (displayed as radio buttons). The user selects an answer, then hits the next button, and the next question is presented.
To guard against netsplits and system restarts, I’ve opted to present this as a single form with each question contained in its own div, and only one div shown at the time. So basically when the user hits the next button, the current_question
assign (an integer) is incremented, which will cause the next question to be shown, while all the others will be hidden.
Questions and answers are loaded from the DB, so they are dynamic, and the form can’t be hardcoded. Therefore, I created an LV component called Question
, with the following leex:
<div id="<%= @question.id %>" class="<%= unless @visible? do %>hidden<% end %>">
<h3><%= @question.question %></h3>
<%= for answer <- @question.answers do %>
<input type="radio" id="<%= answer.id %>" name="answers[<%=@question.id%>]" value="<%= answer.id %>" />
...
<% end %>
<button type="submit">Next</button>
</div>
The relevant part of the root leex:
<form phx-submit="next">
<%= for {question, index} <- Enum.with_index(@questions) do %>
<%= live_component
@socket,
Question,
question: question,
visible?: @current_question == index,
id: question.id
%>
<% end %>
</form>
On the LV side, the submit event handler increments the current_question
assign and does nothing else.
Unfortunately this doesn’t work quite as expected. When I hit the next
button, the checked property of the selected radio button is cleared. Looking at the socket message, I don’t see anything suspicious:
[
"4",
"5",
"lv:phx-FlRcsYGfUEwUFQ0G",
"phx_reply",
{
"response": {
"diff": {
"1": {"0": "2"},
"2": "",
"3": {"d": [[1], [2], [3]]},
"4": "",
"c": {"1": {"1": {"s": ["hidden"]}}, "2": {"1": ""}}
}
},
"status": "ok"
}
]
I was able to solve this by adding phx-update="ignore"
to the radio button. However, I must confess I don’t understand why this is needed, nor any possible negative consequences of adding. Can anyone shed some light? Is this explained somewhere in the docs?
Also, is this in general a good approach to implement an LV-powered multistep form?