Hi,
I am trying to implement a form that provides the dropdown option of selecting an existing reference or creating a new one:
def render(assigns) do #[...] <.form for={@form} id="person-form" phx-change="validate" phx-submit="save"> <.input field={@form[:name]} type="text" label="Name" /> <div class="space-y-1"> <.input field={@form[:role_id]} type="select" label="Role" options={@role_options} phx-change="role-changed" /> <%= if @enable_new_role do %> <.input type="hidden" field={@form[:role_id]} value=""/> <.inputs_for :let={f_nested} field={@form[:role]} > <.input type="text" field={f_nested[:name]} placeholder={if @enable_new_role, do: "Enter new role name", else: "Select 'Add new role' above"} /> </.inputs_for> <% end %> #[...] def mount(params, _session, socket) do #[...] role_options = [ [key: "-- Select role --", value: "", disabled: true], [key: "+ Add new role...", value: ""] ] ++ Enum.map(Persons.list_roles(), &[key: &1.name, value: &1.id]) #[...]
Based on the documentation I thought that a nil id for the reference should cause the creation of a new reference but I always run into:
cannot change belongs_to association `role` because there is already a change setting its foreign key `role_id` to `nil`
An no matter what I tried (as manually removing or overwriting parameters, or different cast options) on save phoenix is always confused and either fails or overwrites the old reference.
Can someone propose a good way how to implement this? (Ideally at the form level since I would like to turn this into a re-usable live component.)
Thanks!