BLacika

BLacika

Liveview Form - Update other fields on phx-change

Hi!
I would like to ask for help. I have a form and I would like to change the values of some fields if I change one of them.
For example, I have this code snippet:

@impl true
  def handle_event("validate", %{"_target" => ["invoice", "date"], "invoice" => invoice_params}, socket) do
    %{"date" => date} = invoice_params
    invoice = %{
      socket.assigns.invoice
      | due_date: Date.add(Date.from_iso8601!(date), socket.assigns.invoice.payment_term),
        date: Date.from_iso8601!(date)
    }

    changeset =
      invoice
      |> Invoices.change_invoice(invoice_params)
      |> Ecto.Changeset.put_assoc(:invoice_lines, invoice.invoice_lines)
      |> Map.put(:action, :validate)

    {:noreply,
     socket
     |> assign(:invoice, invoice)
     |> assign(:changeset, changeset)}
  end

I want to update the due_date field. But this does not change the field in the form.
I’ve manually updated the socket.assigns.invoice, it doesn’t work either.

I have a partner field which works though. When I select a partner, it goes through a few updates. The problem there is that the validation on the other field (date) does not work. Here is the code for that:

@impl true
 def handle_event(
     "validate",
     %{"_target" => ["invoice", "partner_id"], "invoice" => %{"partner_id" => partner_id}} = invoice_params,
     socket) when partner_id != "" do
   partner = Partners.get_partner!(partner_id) |> Repo.preload([:bank_accounts])
   invoice = %{
     socket.assigns.invoice
     | partner_id: partner.id,
       payment_method: partner.payment_method,
       payment_term: partner.payment_term,
       currency_id: partner.currency_id,
       due_date: Date.add(socket.assigns.invoice.date, partner.payment_term),
       exchange_rate: exchange_rate(partner.currency_id)
   }
   changeset = invoice_changeset(invoice, invoice_params) |> Map.put(:action, :validate)

   {:noreply,
    socket
    |> assign(:partner, partner)
    |> assign(:invoice, invoice)
    |> assign(:partner, partner)
    |> assign(:changeset, changeset)
    |> assign(:bank_accounts, bank_accounts(partner.bank_accounts))}
 end

Is there anything in the documentation about this, or perhaps an example? I have not found anything similar here on the forum. Thank you! :slight_smile:

Marked As Solved

codeanpeace

codeanpeace

Ahh, I think you may be overwriting the due date in your callback function.

The form’s current due_date is being sent back in the parameters nested under "invoice".

This means that the invoice_params from the callback function head includes the "due_date" coming from the form. Assuming Invoices.change_invoice/2 function is pretty standard, the form’s "due_date" in the invoice_params will replace the due_date in the invoice struct that you calculated and defined in the function itself.

Also Liked

BLacika

BLacika

Thank you very much for your help and guidance. You helped a lot :slight_smile: It finally helped me to find out where I went wrong. Basically, I should have read the documentation better :smiley: The thing is, I thought that socket.assigns.invoice reflected the state of the form and I started to update it. I rewrote the code and now I update the params fields from the form and compile the changeset that way. So now it works as I had intended.

Like here:

@impl true
  def handle_event("validate", %{"_target" => ["invoice", "date"], "invoice" => invoice_params}, socket) do
    %{"date" => date, "payment_term" => payment_term} = invoice_params
    invoice_params =
      invoice_params
      |> Map.put("due_date", Date.add(Date.from_iso8601!(date), String.to_integer(payment_term)))
      |> Map.put("date", Date.from_iso8601!(date))

    changeset =
      socket.assigns.invoice
      |> Invoices.change_invoice(invoice_params)
      |> Ecto.Changeset.put_assoc(:invoice_lines, socket.assigns.invoice.invoice_lines)
      |> Map.put(:action, :validate)

    socket =
      socket
      |> assign(:changeset, changeset)

    {:noreply, socket}
  end
codeanpeace

codeanpeace

Hmm, what does your HEEX code look like?

And as a sanity check, could you add an IO.inspect(changeset, label: "changeset: ") and post the console output? It also might be worth setting liveSocket.enableDebug() and sharign what comes through in your browser’s developer console.

trisolaran

trisolaran

This might be a long shot, but could it be that the element in the form whose value you want to update is the one having focus? Because in that case LiveView would never overwrite the value entered by the user.

Where Next?

Popular in Questions Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> somethi...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
yawaramin
In the Dialyzer docs ( dialyzer — OTP 29.0.2 (dialyzer 6.0.1) ), there is a way to turn off a specific warning for a function: -dialyzer...
New

Other popular topics Top

chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement