-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support phx-trigger-action #135
base: main
Are you sure you want to change the base?
Changes from all commits
01b9a05
ea23778
de3c1e8
95053a5
9060e9b
b61d1f3
d62c264
7f8f72c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -339,7 +339,22 @@ defmodule PhoenixTest.Live do | |||||||||
end | ||||||||||
|
||||||||||
defp maybe_redirect(html, session) when is_binary(html) do | ||||||||||
maybe_put_patch_path(session) | ||||||||||
case Form.find(html, "form[phx-trigger-action]") do | ||||||||||
:not_found -> | ||||||||||
maybe_put_patch_path(session) | ||||||||||
|
||||||||||
{:found, form} -> | ||||||||||
active_form = session.active_form | ||||||||||
active_form? = form.selector == active_form.selector | ||||||||||
form_data = form.form_data ++ if(active_form?, do: active_form.form_data, else: []) | ||||||||||
|
||||||||||
session.conn | ||||||||||
|> PhoenixTest.Static.build() | ||||||||||
|> PhoenixTest.Static.submit_form(form.selector, form_data) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a question here. Do you know what happens in a normal LiveView if a form has something like a In this case, we're giving "priority" to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you maybe have misread the code. Or I'm wrong. Either way, I'm adding a test to clarify. My understanding: These two clauses match first: defp maybe_redirect({:error, {:redirect, %{to: path}}}, session) do
defp maybe_redirect({:error, {:live_redirect, %{to: path}}} = result, session) do So, given <form phx-trigger-action={@trigger_submit} phx-change="redirect"> handle_event("redirect", _, socket) do
socket
|> push_navigate(to: "/elsewhere")
|> assign(:trigger_submit: true)
end a change to the form will cause a redirect to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double checked the actual behaviour:
So I think we're fine. You're right in that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once again, running the same test against an actual browser as well as the
Comment on lines
+351
to
+353
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would imagine our implementation here is good. But I haven't done stuff with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the Should we use
|
Form.has_action?(form) -> | |
session.conn | |
|> PhoenixTest.Static.build() | |
|> PhoenixTest.Static.submit_form(selector, form_data) |
For that we could use LiveViewTest.submit_form
. Which uses the same helper function as LiveViewTest.follow_trigger_action
.
For the sake of simplicity (my interpretation) we don't do that and rather just call the Static driver directly.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -441,6 +441,47 @@ defmodule PhoenixTest.IndexLive do | |
|
||
<div id="hook" phx-hook="SomeHook"></div> | ||
<div id="hook-with-redirect" phx-hook="SomeOtherHook"></div> | ||
|
||
<form | ||
id="trigger-form" | ||
phx-submit="trigger-form" | ||
phx-trigger-action={@trigger_submit} | ||
action="/page/create_record" | ||
method="post" | ||
> | ||
<input type="hidden" name="trigger_action_hidden_input" value="trigger_action_hidden_value" /> | ||
<label>Trigger action <input type="text" name="trigger_action_input" /></label> | ||
</form> | ||
|
||
<button phx-click="trigger-form">Trigger from elsewhere</button> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
<form | ||
id="trigger-multiple-form-1" | ||
phx-submit="trigger-form" | ||
phx-trigger-action={@trigger_multiple_submit} | ||
/> | ||
|
||
<form | ||
id="trigger-multiple-form-2" | ||
phx-submit="trigger-form" | ||
phx-trigger-action={@trigger_multiple_submit} | ||
/> | ||
|
||
<button phx-click="trigger-multiple-forms">Trigger multiple</button> | ||
|
||
<form | ||
id="redirect-and-trigger-form" | ||
phx-change="patch-and-trigger-form" | ||
phx-trigger-action={@redirect_and_trigger_submit} | ||
action="/page/create_record" | ||
method="post" | ||
> | ||
<label> | ||
Patch and trigger action <input type="text" name="patch_and_trigger_action" /> | ||
</label> | ||
<button phx-click="redirect-and-trigger-form">Redirect and trigger action</button> | ||
<button phx-click="navigate-and-trigger-form">Navigate and trigger action</button> | ||
</form> | ||
""" | ||
end | ||
|
||
|
@@ -463,6 +504,9 @@ defmodule PhoenixTest.IndexLive do | |
|> assign(:show_form_errors, false) | ||
|> assign(:cities, []) | ||
|> assign(:hidden_input_race, "human") | ||
|> assign(:trigger_submit, false) | ||
|> assign(:trigger_multiple_submit, false) | ||
|> assign(:redirect_and_trigger_submit, false) | ||
|> allow_upload(:avatar, accept: ~w(.jpg .jpeg)) | ||
|> allow_upload(:main_avatar, accept: ~w(.jpg .jpeg)) | ||
|> allow_upload(:backup_avatar, accept: ~w(.jpg .jpeg)) | ||
|
@@ -499,6 +543,35 @@ defmodule PhoenixTest.IndexLive do | |
} | ||
end | ||
|
||
def handle_event("trigger-form", _form_data, socket) do | ||
{:noreply, assign(socket, :trigger_submit, true)} | ||
end | ||
|
||
def handle_event("trigger-multiple-forms", _form_data, socket) do | ||
{:noreply, assign(socket, :trigger_multiple_submit, true)} | ||
end | ||
|
||
def handle_event("patch-and-trigger-form", _form_data, socket) do | ||
{:noreply, | ||
socket | ||
|> assign(:redirect_and_trigger_submit, true) | ||
|> push_patch(to: "/live/index_no_layout")} | ||
end | ||
|
||
def handle_event("redirect-and-trigger-form", _form_data, socket) do | ||
{:noreply, | ||
socket | ||
|> redirect(to: "/live/page_2") | ||
|> assign(:redirect_and_trigger_submit, true)} | ||
end | ||
|
||
def handle_event("navigate-and-trigger-form", _form_data, socket) do | ||
{:noreply, | ||
socket | ||
|> push_navigate(to: "/live/page_2") | ||
|> assign(:redirect_and_trigger_submit, true)} | ||
end | ||
|
||
def handle_event("set-hidden-race", form_data, socket) do | ||
race = | ||
case form_data["name"] do | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it a little strange that we'd be looking for a form inside
maybe_redirect
.I imagine it'd be more duplication to do this in the places where we're submitting forms, but I wonder if we could find a better design for this?
I'd image there are places where we're dealing with a form (probably through a phx-change) where we already have the
form
data structure. Maybe we could check for aForm.phx_trigger_action?
there? (similar to how we do it with other attributes like that)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think the
phx-trigger-action
is a bit like a client side redirect.Two things to consider:
phx-trigger-action
can be set on any re-render, not just when clicking a submit button for a formphx-trigger-action
can be set on any form, not necessarily the one the user is interacting withI agree that the common use case is:
handle_event("save"
assignstrigger_submit: true
But I think we should limit the implementation to that common use case.
I think its best to mimmick LiveView JS to support all kinds of uses cases:
Whenever something changed, check the HTML for forms with
phx-trigger-action
.If present, then submit that form.
That's what I tried to to in this PR.
We could separate
maybe_redirect
andmaybe_trigger_action
.Do you think that would help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit e2dd5b4
I separated them into two separate post processing steps.
I tried to keep both functions completely separate by introducing a token flow.
Feels over-engineered. Maybe just renaming
maybe_redirect
tomaybe_trigger_form_action_or_redirect
would be good enough?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree. I appreciate you taking the time to try a different approach to see if we landed at something better. But it does seem to introduce more confusion. I think your original
maybe_redirect
implementation was best -- especially since you explained howtrigger_action
works. I thought it was more limited.I think that's a good north star for sure. As we evaluate what to include and not include, I think there are two levels that I like to keep in mind:
All that being said, any chance to revert the last commit, and I think we might be good to go? Do you think it'd be helpful to write test cases for the scenarios you mentioned? (when a different event happens and the trigger-action still happens?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted and added tests.
Also stumbled over #143.