In a phoenix LiveView form with 3 select tags, the first influences the other two, ie the dependent two should only display the options available for the first one, like so:
<%= f = form_for @changeset, "#", id: "eval-form", phx_target: @myself, phx_change: "validate", phx_submit: "save" %>
<%= select(f, :item1_id, Enum.map(@item1s, fn {_,v} -> {v.name, v.id} end), prompt: "Choose item1...") %>
<% item1_id = @changeset |> Ecto.Changeset.get_field(:item1_id) %>
<%= select(f, :item2_id, item1_id && Enum.map(@item1s[item1_id].item2s, &{&1.name, &1.id}) || []) %>
<%= select(f, :item3_id, item1_id && Enum.map(@item1s[item1_id].item3s, &{&1.name, &1.id}) || []) %>
</form>
When item1
gets chosen, item2
and item3
select tags do include the correct respective options, but display no chosen item (as they do not include a prompt, the first option should be selected). The changeset does not include changes for item2
and item3
(which matches what is displayed). However, after item2
is chosen, item3
displays the first option as chosen (as intended). After that, the changeset does include item1
and item2
changes, but item3
selected option is not there.
Questions:
item2
and item3
) to show their respective first option as chosen after a change to the first select ( item1
)?Have you tried using the value
option for select
tags? Like this:
<%= item2_values = item1_id && Enum.map(@item1s[item1_id].item2s, &{&1.name, &1.id}) || [] %>
<%= select(f, :item2_id, item2_values, value: @changeset |> Ecto.Changeset.get_field(:item2_id, List.first(item2_values))) %>
However, I think you should do this logic in your LiveView module. If you have a phx-change
event being fired from your form, you could actually assign item2_values
to the socket in a clean function.
I solved the problem with 'two phase changeset casting'.
When handling phx-change
event, firstly the item1
attribute is cast and validated. Next, item2
and item3
attributes are changed if needed (ie item values and selected value). Finally, item2
and item3
attributes are cast and validated.
It seems that this also works for any dynamic forms (eg in my case when item1
is selected, items for item2
are set, when item2
is selected additional fields appear that are needed for the item2
).
I'm open to suggestions if there is a better way of doing this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.