Today I noticed that when using
embedded_schema do
...
embeds_one :variables, Variables
end
def changeset(%Variables{} = variables, attrs) do
variables
|> cast(attrs, [:id, :name])
end
My input_for is visible in my /new route
The way I need to.
But when I use
embedded_schema do
...
embeds_many :variables, Variables, on_replace: :delete
end
def changeset(%Variables{} = variables, attrs) do
variables
|> cast(attrs, [:id, :name])
|> cast_embed(:variables, with: &Variables.changeset/2, required: true)
end
The form of input_for some.
Why does this happen?
Needed it to work like embeds_many
My form html is like this:
<%= f = form_for @changeset, "#" , id: example-form" , phx_target: @myself, phx_submit: "save" %>
....
<%= inputs_for f, :variables, fn i -> %>
<label>Name form 2</label>
<%= text_input i, :name_form_2, class: "form-control" %>
<%= error_tag i, :name_form_2 %>
<% end %>
</form>
I added the button in my form.html
<a href="#" phx-click="add-feature">Add feature</a>
my index.html looks like this
def handle_event("add-feature", _, socket) do
existing_variants = Map.get(socket.assigns.changeset.changes, :variables, socket.assigns.matrix_priority.variables)
variables =
existing_variants
|> Enum.concat([
Structure.change_variables(%Variables{temp_id: get_temp_id()}) # NOTE temp_id
])
changeset =
socket.assigns.changeset
|> Ecto.Changeset.put_embed(:variables, variables)
IO.inspect(changeset)
{:noreply, assign(socket, changeset: changeset)}
end
when i click the button,
nothing happens.
Neither error has shown.
I see that when clicking the button, it returns this with inspect
#Ecto.Changeset<
action: nil,
changes: %{
variables: [
#Ecto.Changeset<action: :insert, changes: %{}, errors: [],
data: #Structure.Variables<>, valid?: true>
]
},
errors: [variables: {"can't be blank", [validation: :required]}],
data: #Myproject.Structure.<>,
valid?: false
>
I tried to follow this article, but without success.
I recently build an example using LV with nested inputs: Inputs_for/4 collection indices - #4 by LostKobrakai
2 Likes
That way you put it, I can also run normally with phx-click.
But it came down to the same issue.
When clicking the button, the web page does not update.
I modified the code to look like this:
def handle_event("add-feature", _, socket) do
socket =
update(socket, :changeset, fn changeset ->
existing = Ecto.Changeset.get_field(changeset, :variables, [])
Ecto.Changeset.put_embed(changeset, :variables, existing ++ [%{}])
end)
IO.inspect(socket)
{:noreply, socket}
end
I managed to find the problem.
In case anyone goes through the same thing as me.
Just add the phx_target: @myself in your form