Changeset with radio buttons

I have a LiveView that creates a changeset on mount and validate.

defp build_changeset(data) do
    types = %{email: :string, distance_id: :integer}
    changeset = {data, types} |> Ecto.Changeset.cast(%{}, Map.keys(types)) |> Ecto.Changeset.validate_required([:email, :distance_id])

And a simple form. It presents multiple options to the user, so I’m relying on a wrapping a radio

<.form as={:form} for={@changeset} :let={f} phx-change="validate" phx-submit="save">
    <.input field={f[:email]} type="email" />
    <%= for vd <- @distances do %>
        for={"form_distance_id_" <> to_string(}>
        <input type="radio" id={"form_distance_id_" <> to_string(} name="form[distance_id]" value={} class="sr-only" />
        <!-- various aesthetic elements -->
    <% end %>

When I first click one of these labels, my validate event fires and I see params for my changeset:

Parameters: %{"_target" => ["form", "email"], "form" => %{"distance_id" => "23", "email" => ""}}

However, if I start editing the email field, the distance_id is wiped away.

Parameters: %{"_target" => ["form", "email"], "form" => %{"email" => ""}}

Without complete form values, I can only rebuild a partial changeset, thus wiping out prior user selections. Anything stand out?

Hey @boiserunner you need to set a checked attribute on the input that has the value you’ve set. Something like:

<input type="radio" ... checked={get_field(@changeset, :distance_id) == />
1 Like

Confirmed, this works.

Not a complete face-palm moment, but maybe like… 65%? 70%?

Thank you!

1 Like