I have a simple form setup using form_for/3
:
<%= f = form_for @post_changeset, "#", phx_change: "validate", phx_submit: "save" %>
<%= label f, :headline %>
<%= text_input f, :headline %>
<%= error_tag f, :headline %>
<%= label f, :content %>
<%= text_input f, :content %>
<%= error_tag f, :content %>
<%= label f, :pinned %>
<%= checkbox f, :pinned %>
<%= error_tag f, :pinned %>
<%= submit "Save", phx_disable_with: "Saving..." %>
</form>
This form is appending posts to its parent (a ‘project’) using this submit handler:
def handle_event("save", %{"post" => post_params}, socket) do
case Projects.create_post(socket.assigns.project, post_params) do
{:ok, post} ->
{:noreply,
socket
|> put_flash(:info, "Post created successfully")
|> assign(:project, %{
socket.assigns.project
| posts: socket.assigns.project.posts ++ [post]
})
|> assign(:post, %Projects.Post{})
|> assign(:post_changeset, Projects.change_post(%Projects.Post{}, socket.assigns.project))}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, post_changeset: changeset)}
end
end
What it should do:
After the submit, the newly created post should be appended to the existing posts (without reloading/recreating the liveview). The form should be reset, meaning the inputs are empty and the form is ‘pristine’ again (not dirty/touched).
What it’s currently doing:
After the submit, the newly created post is appended to the existing posts (without a reload). The form inputs are cleared but after tabbing from the first input (after typing something into it) to the second (e.g. headline → content), the changeset error for that field is instantly displayed even though the input hasn’t been dirtied. I would expect that the form behaves like on a fresh page render.
What am I missing?