Closed itSQualL closed 5 years ago
@snewcomer sounds like a possibly patching bug when we call morphdom, but I can't say why we'd diff any differently for the div container vs no container. Can you take a look? <3
@itSQualL I'd be curious what happens when you add data-index=<%= c_f.index %>>
to each div with a form-group
class (without the
Ok I found the problem here. It was a mistake with that line:
<button ="remove_code" data-index=<%= c_f.index %>>Remove code</button>
I was testing the code and I forgot to append phx-click
before ="remove_code"
, removing that or adding the event, it works.
I'm sorry for the noise here.
@itSQualL Do you have the full solution documented anywhere? Interested in the same feature for a project.
@jrissler Hi, I don't have a repository but I'm doing the next:
First, on mount or validate events I'm saving the initial/updated params
def mount(params, socket) do
...
{:ok, assign(socket, %{changeset: changeset, params: params})}
end
def handle_event("validate", %{"params" => params}, socket) do
...
{:noreply, assign(socket, %{changeset: changeset, params: params})}
end
So I ever have the state of params.
Then, I have an add
and remove
actions triggered when button is pushed:
def handle_event("add_code", _, socket) do
{:noreply, LiveHelpers.add_nested_field(socket, "codes")}
end
def handle_event("remove_code", index, socket) do
{:noreply, LiveHelpers.remove_nested_field(socket, "codes", index)}
end
defmodule LiveHelpers do
import Phoenix.LiveView
alias Phoenix.LiveView.Socket
def add_nested_field(socket, field) do
params = Map.update!(socket.assigns.params, field, fn
field when is_map(field) -> Map.values(field) ++ [%{}]
field when is_list(field) -> field ++ [%{}]
end)
do_changes(socket, params)
end
def remove_nested_field(socket, field, index) do
params = Map.update!(socket.assigns.params, field, fn
field when is_map(field) -> Map.drop(field, [index])
field when is_list(field) -> List.delete_at(field, String.to_integer(index))
end)
do_changes(socket, params)
end
defp do_changes(socket, params) do
changeset =
socket
|> get_resource
|> Locations.change_region(params) # It returns a changeset
assign(socket, %{changeset: changeset, params: params})
end
I hope it will help you. I've tried to find examples about this too but I find nothing.
@itSQualL awesome thanks, that does help.
@itSQualL I understand the logic of your code, but what I don't understand is how are you passing the index of the element to be deleted using liveview? I am doing the same thing as you, but even with data-index
attribute set on the delete button, I don't receive anything on my handle_event("remove_code", index, socket)
function as index is always ""
. Could you please share more detail, or am I missing something basic?
Nevermind, I figured it out. You can pass parameters using phx-value
attribute. This is documented here.
So, the correct version of your button should be:
<button phx-click="remove_code" phx-value=<%= c_f.index %>>Remove code</button>
@itSQualL Thanks for a good example! I’m trying to implement this example but have problems to understand what the function ”get_resource” does. I think it gets values from the form to ensure that date isn’t overwritten? But I can’t figur out how to do this from the handle_event.
@itSQualL Thanks for a good example! I’m trying to implement this example but have problems to understand what the function ”get_resource” does. I think it gets values from the form to ensure that date isn’t overwritten? But I can’t figur out how to do this from the handle_event.
Hi!, well, it was a private function that I omitted. It just return some info saved into the socket to use on the next function.
Since it is related, I will publish here a package to manage nested fields in forms:
Hello, maybe this was too long ago for you, but I wonder why store the params
separately from the changeset
into the socket.
{:ok, assign(socket, changeset: changeset, params: params)}
Why not just store the changeset
and use changeset.params
?
Environment
Actual behavior
I'm building a nested form with buttons for add or remove nested field.
form.html.leex:
live/new.ex:
Navigating to the view shows:
but when I submit the
add_code
event the result html is:As you can see, "traducción" label and "add code" button dissapear
Expected behavior
I've found that if you wrap the nested fields into a div, it works perfect:
From:
To:
And then, it works perfect: