I am having a real hard time trying to figure out how to prompt a user if is it OK to recalculate some fields values after the cost value of an item has changed. Since I am taking my first steps in Elixir/Phoenix/LiveView after 30+ years of Imperative-Non-Web development, I have no clue on how to do it using LiveView.
I understand that the form’s phx-change attribute will trigger an event whenever a value is changed and we use it to validate the form’s information in a handle_event function. Also, I included the phx-debounce="blur" to run the validate process only when the user has left each field, not with every key stroke.
So, I have 3 questions:
Is there an easy way to compare the new cost sent in the parameters of the handle_event function against the original value of an item’s cost?
Since the handle_event function is happening between the user changing a field’s value and the rendering process after this function returns the :noreply tuple, how can I ask the user if is it OK/Cancel, or Yes/No, to re-calculate other fields? I mean, the process is waiting for this function to finish in order to render the page, but I need to know if I need to re-calculate some values before completing this function.
Since running a phx-change for an specific field only sends the value for this specific field in the parameters of the handle_event function, I need to use the form’s phx-change trigger to have all the form’s fields available when validating the data. Is this forcing me to have a pretty huge handle_function with a pretty large case to validate the form’s fields I need to validate?
Changesets are about exactly that. changeset.data holds the original data and changeset.changes holds any changes made (if there are any).
You cannot solve this without letting the callback finish. You need to give control back to the user to be able to even click some confirmation. This will require a multi step process.
You can look at params["_target"] to get information of what field changed last – that might help.
I usually do this by setting a flag in the assigns that pops up the question using a modal dialog.
Initially assign it as false or nil in your mount/3, then something like:
<.modal id="confirm-modal" :if={@pop_question} show on_confirm={JS.push("recalculate")} on_cancel={JS.push("close_popup")}>
Recalculate?
<:confirm>OK</:confirm>
<:cancel>Cancel</:cancel>
</.modal>
Then handle these 2 new messages, by recalculating and setting the pop_question back to false.
Check your version of CoreComponents as I believe some things have changed with the modal, but you should get the gist.