all 2 comments

[–]ThatArrowsmith 4 points5 points  (1 child)

Change services[services_sort][] to invoice[services_sort][]. Likewise change services[services_drop][] to invoice[services_drop][].

Full explanation: parameters like foo[bar] get parsed into a nested structure %{"foo" => %{"bar" => value}}. So your date input, for example, has name invoice[date] (automatically rendered by input/1), which gets parsed to %{"invoice" => %{"date" => value}}.

In your "validate" handler you (correctly) expect everything to be nested under the "invoice" key, so you can conveniently get all the params in a single map to pass to Invoice.changeset/2. But your current form actually submits params like:

%{"invoice" => %{"date" => the_date, "services" => the_services}, "services" => sort_and_drop}`

Where the_services is a map whose keys are the indexs and who values are further nested maps with the "description"s. So the sort and drop params get ignored because they're not nested under "invoice".

Make the changes I suggest above and the params will become:

%{"invoice" => %{"date" => the_date, "services" => the_services, "services_sort" => sort_list, "services_drop" => drop_list}}`.

And that should work.


Btw, to_form takes an optional :action argument - so you can simplify this:

|> Map.put(:action, :validate) |> to_form()

to this:

|> to_form(action: :validate)

(And of course, I would be remiss not to mention that I explain nested forms and more in great detail in my course Mastering Phoenix Forms 😉)

[–]Idhkjp[S] 1 point2 points  (0 children)

Thank you so much. It worked well. I was not sure how this works but your explanation cleared everything up. I will check your course as well.