Hi,
There are quite a few issues that describes the current situation when you want to distinguish which button was pressed to submit a form with liveview.
https://github.com/phoenixframework/phoenix_live_view/issues/184
https://github.com/phoenixframework/phoenix_live_view/issues/511
https://github.com/phoenixframework/phoenix_live_view/issues/1133
Here is my new hack to tackle this problem using current liveview implementation (0.17.5).
I’ve added this function to my app.js to properly factorize the code (but this is not mandatory, it could be put into the template file as well)
// webapp.submit submits the form form_id using event bypassing liveview phx-submit default
// ----------------------------------------------------------------------------------------
webapp.submit = (form_id, event) =>
webapp.live_socket.execJS(document.getElementById(form_id),
`[["push", {"event": "${event}"}]]`, 'submit')
note: webapp is my toplevel object in which I also stored the liveSocket
Then in the template you can simply create your buttons like here (extract from a modal template)
<section class="modal-card-body thin_scroll">
<.form let={f} for={@changeset} id="form_modal" phx-submit="save_goal" as="goal">
... your form content ....
</.form>
</section>
<footer class="modal-card-foot">
<button class="button is-primary" onclick="webapp.submit('form_modal', 'save_decision')"><%= gettext("Decision") %></button>
<button class="button is-primary" onclick="webapp.submit('form_modal', 'save_information')"><%= gettext("Information") %></button>
<button class="button is-primary" form="form_modal" type="submit"><%= gettext("Validate") %></button>
</footer>
Here I have kept a traditionnal submit button in third position that will trigger the default phx-submit event.
Finally, you only have to pattern match to get the wanted behaviour in you .ex file
def handle_event("save_decision", params, socket),
do: handle_event("save_goal", Map.put(params, "type", "decision"), socket)
def handle_event("save_information", params, socket),
do: handle_event("save_goal", Map.put(params, "type", "Information"), socket)
def handle_event("save_goal", params, %{assigns: assigns} = socket) do
Logger.info("params: #{inspect(params)}")
...
{:noreply, socket}
end
And that’s it !
Cheers,
Sébastien






















