All form field are reset to their original values when there is an error in just one of the fields

I have a simple form, used with a changeset, where users can enter name, address, phone, etc. Simplified it looks like this:

<%= f = form_for @changeset, "#", [phx_submit: "save", phx_target: @myself] %>

    <div>
      <label>Name</label>
      <%= text_input f, :name %>
      <%= error_tag f, :name %>
    </div>

    <div>
      <label>City</label>
      <%= text_input f, :city %>
      <%= error_tag f, :city %>
    </div>

  <%= submit "Save" %>
</form>

On save, there are some validations checked, this is all working fine.

Now I want to actually populate the field with values from the database, so users can come back to the form and change data which is already there. So I added values to each field, like this:

<%= f = form_for @changeset, "#", [phx_submit: "save", phx_target: @myself] %>

    <div>
      <label>Name</label>
      <%= text_input f, :name, value: @user.name %>
      <%= error_tag f, :name %>
    </div>

    <div>
      <label>City</label>
      <%= text_input f, :city, value: @user.city %>
      <%= error_tag f, :city %>
    </div>

  <%= submit "Save" %>
</form>

Populating works, but now the following problem occurs. If there is a validation error in one of the fields (e.g. missing), then on submit the error is shown but also all the fields are reset to their original values. Which means that, for example, if there was no data in the db yet, all the fields are emptied again. This is of course quite annoying.

How can I populate the fields with some existing values, but make sure that when the form is submitted, the fields keep their values as entered/changed by the user, also if there is an error in one of the fields?

Well, get the values from the changeset itself, which was created from an existing %User{} struct (on edit) or an empty one (on create).

mix phx.new changeset_example --live
mix phx.gen.live Accounts User users name:string age:integer

Check the generated files in the user_live folder (in particular form_component.ex and form_component.html.leex)

2 Likes

Awesome. Just creating the changeset from the existing user does the trick. Thanks!