Hi all,
how can I create a form where some of its fields are added dynamically, without losing the data when a user adds fields to the form?
I’m trying to create a cv builder. A cv can have many entries (i.e. the name of the company as well as the duration).
Here are the schemas that I have (not backed by a DB yet):
defmodule Cvtex.Cv do
use Ecto.Schema
import Ecto.Changeset
defmodule Entry do
import Ecto.Changeset
use Ecto.Schema
embedded_schema do
field :company_name, :string
field :work_period, :string
end
def new, do: %Entry{}
end
embedded_schema do
field :first_name, :string
field :last_name, :string
embeds_many :entries, Entry
end
def changeset(params) do
cast(%__MODULE__{entries: [Entry.new()]}, params, [:first_name, :last_name])
end
end
The form looks like this in the template:
<.form let={f} for={@changeset} phx-submit="submit-cv">
<%= label f, :first_name %>
<%= text_input f, :first_name %>
<%= label f, :last_name %>
<%= text_input f, :last_name %>
<%= inputs_for f, :entries, fn entry -> %>
<%= label entry, :company_name %>
<%= text_input entry, :company_name %>
<%= label entry, :work_period %>
<%= text_input entry, :work_period %>
<% end %>
<%= button "Add a work entry", to: "#", "phx-click": "add-entry" %>
<%= submit "Submit" %>
</.form>
And here’s the LiveView:
defmodule CvtexWeb.CvLive do
use CvtexWeb, :live_view
alias Cvtex.Cv
@impl true
def mount(_params, _session, socket) do
changeset = Cv.changeset(%{})
socket =
socket
|> assign(changeset: changeset)
{:ok, socket}
end
@impl true
def handle_event("submit-cv", %{"cv" => params}, socket) do
IO.inspect(params)
{:noreply, socket}
end
@impl true
def handle_event("add-entry", params, socket) do
current_entries =
Map.get(socket.assigns.changeset.changes, :entries, socket.assigns.changeset.data.entries)
changeset =
Ecto.Changeset.put_embed(
socket.assigns.changeset,
:entries,
[Cv.Entry.new() | current_entries]
)
socket =
socket
|> assign(changeset: changeset)
{:noreply, socket}
end
end
The problem is, everytime I click on “Add a work entry”, the current data that has been entered in the form simply dissapears. I would like to be able to add new entries/fields to the form without losing the current progress.