The form values are reset when the validate event is triggered

Hi,

I have a form where users can select hardware and provide installation instructions:

I preopulate the installation instructions from the database, if they are found there.
That works, but when the validate event is triggered along with the reset_form function, any new user data is wiped away.

What is the correct pattern to achieve pre-populating values and be able to save new data?

Here you can see in the log that the validate event receives the new values: “updates”, but when the save event is triggered, then it still uses the old “NEW INSTRUCTIONS” data.

[debug] HANDLE EVENT "validate" in MyAppWeb.WizardLive.Summary.Edit
  Component: MyAppWeb.WizardLive.Form
  Parameters: %{"_target" => ["installation_instructions-9"], "component_selected" => "1", "installation_instructions-9" => "updates", "qty_9" => "1", "summary" => %{"coming_from" => "display_targets_selected", "display_targets" => "displaytargets_selected"}}
params in validate: %{
  "_target" => ["installation_instructions-9"],
  "component_selected" => "1",
  "installation_instructions-9" => "updates",
  "qty_9" => "1",
  "summary" => %{
    "coming_from" => "display_targets_selected",
    "display_targets" => "displaytargets_selected"
  }
}
[debug] Replied in 3ms
[debug] HANDLE EVENT "save" in MyAppWeb.WizardLive.Summary.Edit
  Component: MyAppWeb.WizardLive.Form
  Parameters: %{"component_selected" => "1", "installation_instructions-9" => "NEW INSTRUCTION", "qty_9" => "1", "summary" => %{"coming_from" => "display_targets_selected", "display_targets" => "displaytargets_selected"}}
params: %{
  "component_selected" => "1",
  "installation_instructions-9" => "NEW INSTRUCTION",
  "qty_9" => "1",
  "summary" => %{
    "coming_from" => "display_targets_selected",
    "display_targets" => "displaytargets_selected"
  }
defmodule MyAppWeb.WizardLive.Form do

  def update(assigns, socket) do
    {
      :ok,
      socket
      |> assign(assigns)
      |> assign_projectors()
      |> clear_form()
    }
  end

  defp clear_form(%{assigns: %{summary: summary}} = socket) do
    assign_form(socket, Wizard.change_summary(summary))
  end
defmodule MyAppWeb.Components.ComponentSelector do

              <label class="block pt-3" for={"installation_instructions-#{component.id}"}>Location & other relevant information</label>
              <input
                type="text"
                name={"installation_instructions-#{component.id}"}
                id={"installation_instructions-#{component.id}"}
                phx-target={@myself}
                phx-debounce="blur"
                phx-hook="PersistFocus"
                value={SummariesDisplayTargets.installation_instructions(%{component: component, summary_id: assigns.form.data.id})}
              />

Call me crazy, but if I wanted to persist the values in the form, I wouldn’t be piping into a function called clear_form :wink:.

In your “validate” event handler, the event params and original struct give you a new changset, which you use to create a new form assign.

Hehe, you’re right! clear_form does not actually clear the form on the other places where it’s used, but that’s because I also updated the socket.assigns.summary with those values.

Thanks for pushing me in the right direction. :smiling_face: