I followed this tutorial: Nested model forms with Phoenix LiveView - Tutorials and screencasts for Elixir, Phoenix and LiveView
I have a schema called Folha
, defined as:
schema "folhas" do
field :competencia, :string
belongs_to :empresa, Empresa
has_many :itens, ItensFolha
timestamps()
end
@doc false
def changeset(folha, attrs) do
folha
|> cast(attrs, [:competencia, :empresa_id])
|> validate_required([:competencia, :empresa_id])
|> parse_string(:competencia)
|> foreign_key_constraint(:empresa_id)
|> cast_assoc(:itens, required: true, with: &ItensFolha.changeset/2)
end
And the ItensFolha
is defined as:
schema "itens_folha" do
field :adicional_noturno, :decimal
field :bonificacao, :decimal
field :descontos, :decimal
field :dias_faltas, :integer
field :finalizado?, :boolean, default: false
field :hora_extra, :decimal
# fields to enable nested form
field :temp_id, :string, virtual: true
field :delete, :boolean, virtual: true
belongs_to :folha, Folha
belongs_to :funcionario, Funcionario
timestamps()
end
@doc false
def changeset(itens_folha, attrs) do
itens_folha
|> cast(attrs, @fields)
|> validate_required(@required_fields)
|> foreign_key_constraint(:funcionario)
|> maybe_mark_for_deletion()
end
defp maybe_mark_for_deletion(%{data: %{id: nil}} = changeset), do: changeset
defp maybe_mark_for_deletion(changeset) do
if get_change(changeset, :delete) do
%{changeset | action: :delete}
else
changeset
end
end
On the live view side, I have the scaffold files: index.ex
, show.ex
, form_component.ex
and it’s templates!
My Folha
form is:
<h2><%= @title %></h2>
<%= f = form_for @changeset, "#",
id: "folha-form",
phx_target: @myself,
phx_change: "validate",
phx_submit: "save" %>
<%= label f, :competencia %>
<%= text_input f, :competencia %>
<%= error_tag f, :competencia %>
<%= label f, :empresa_id %>
<%= text_input f, :empresa_id %>
<%= error_tag f, :empresa_id %>
<p>Item Folha</p>
<%= inputs_for f, :itens, fn i -> %>
<%= label i, :dias_faltas %>
<%= number_input i, :dias_faltas %>
<%= error_tag i, :dias_faltas %>
<%= label i, :hora_extra %>
<%= number_input i, :hora_extra, step: "any" %>
<%= error_tag i, :hora_extra %>
<%= label i, :adicional_noturno %>
<%= number_input i, :adicional_noturno, step: "any" %>
<%= error_tag i, :adicional_noturno %>
<%= label i, :descontos %>
<%= number_input i, :descontos, step: "any" %>
<%= error_tag i, :descontos %>
<%= label i, :finalizado? %>
<%= checkbox i, :finalizado? %>
<%= error_tag i, :finalizado? %>
<%= label i, :bonificacao %>
<%= number_input i, :bonificacao, step: "any" %>
<%= error_tag i, :bonificacao %>
<%= label i, :funcionario_id %>
<%= text_input i, :funcionario_id %>
<%= error_tag i, :funcionario_id %>
<%= if is_nil(i.data.temp_id) do %>
<%= checkbox i, :delete %>
<% else %>
<%= hidden_input i, :temp_id %>
<a href="#" phx-click="remove-item" phx-value-remove="<%= i.data.temp_id %>">×</a>
<% end %>
<% end %>
<a href="#" phx-click="add-item">Add a item folha</a>
<%= submit "Save", phx_disable_with: "Saving..." %>
</form>
However, where I put the handle_event/3
“add-item” and “remove_item” clauses?
I tried to put on form_component.ex
but when I clicked the button, it throws a “validate” event…
So I tried to put on index.ex
, however, the socket
on this live view does not have the field changeset
, so I can’t to retrieve existing items. What I’m doing wrong?
I created a gist with some code: https://gist.github.com/a0e7230f312fb50fe681b984bac9b7a6
I also have all templates and live views for the ItensFolha
schema, could I “embed” one form_component
into another?