Skip to content

Commit adf1c38

Browse files
authored
Merge pull request #439 from phoenixframework/cm-form-action-changed
Add form action and consider input changed if action changes
2 parents c50f33d + 323a65a commit adf1c38

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

lib/phoenix_html/form.ex

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ defmodule Phoenix.HTML.Form do
6464
id: nil,
6565
name: nil,
6666
data: nil,
67+
action: nil,
6768
hidden: [],
6869
params: %{},
6970
errors: [],
@@ -74,6 +75,7 @@ defmodule Phoenix.HTML.Form do
7475
source: Phoenix.HTML.FormData.t(),
7576
name: String.t(),
7677
data: %{field => term},
78+
action: atom(),
7779
params: %{binary => term},
7880
hidden: Keyword.t(),
7981
options: Keyword.t(),
@@ -191,18 +193,32 @@ defmodule Phoenix.HTML.Form do
191193
@doc """
192194
Receives two forms structs and checks if the given field changed.
193195
194-
The field will have changed if either its associated value or errors
195-
changed. This is mostly used for optimization engines as an extension
196-
of the `Access` behaviour.
196+
The field will have changed if either its associated value, errors,
197+
action, or implementation changed. This is mostly used for optimization
198+
engines as an extension of the `Access` behaviour.
197199
"""
198200
@spec input_changed?(t, t, field()) :: boolean()
199201
def input_changed?(
200-
%Form{impl: impl1, id: id1, name: name1, errors: errors1, source: source1} = form1,
201-
%Form{impl: impl2, id: id2, name: name2, errors: errors2, source: source2} = form2,
202+
%Form{
203+
impl: impl1,
204+
id: id1,
205+
name: name1,
206+
errors: errors1,
207+
source: source1,
208+
action: action1
209+
} = form1,
210+
%Form{
211+
impl: impl2,
212+
id: id2,
213+
name: name2,
214+
errors: errors2,
215+
source: source2,
216+
action: action2
217+
} = form2,
202218
field
203219
)
204220
when is_atom(field) or is_binary(field) do
205-
impl1 != impl2 or id1 != id2 or name1 != name2 or
221+
impl1 != impl2 or id1 != id2 or name1 != name2 or action1 != action2 or
206222
field_errors(errors1, field) != field_errors(errors2, field) or
207223
impl1.input_value(source1, form1, field) != impl2.input_value(source2, form2, field)
208224
end

lib/phoenix_html/form_data.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ defprotocol Phoenix.HTML.FormData do
5656
applies if the field value is a list and no parameters were
5757
sent through the form.
5858
59+
* `:action` - The user defined action being taken by the form, such
60+
as `:validate`, `:save`, etc.
5961
"""
6062
@spec to_form(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field(), Keyword.t()) ::
6163
[Phoenix.HTML.Form.t()]
@@ -79,6 +81,7 @@ defimpl Phoenix.HTML.FormData, for: Map do
7981
def to_form(conn_or_atom_or_map, opts) do
8082
{name, params, opts} = name_params_and_opts(conn_or_atom_or_map, opts)
8183
{errors, opts} = Keyword.pop(opts, :errors, [])
84+
{action, opts} = Keyword.pop(opts, :action, nil)
8285
id = Keyword.get(opts, :id) || name
8386

8487
unless is_binary(id) or is_nil(id) do
@@ -93,6 +96,7 @@ defimpl Phoenix.HTML.FormData, for: Map do
9396
params: params,
9497
data: %{},
9598
errors: errors,
99+
action: action,
96100
options: opts
97101
}
98102
end
@@ -118,6 +122,7 @@ defimpl Phoenix.HTML.FormData, for: Map do
118122
{name, opts} = Keyword.pop(opts, :as)
119123
{id, opts} = Keyword.pop(opts, :id)
120124
{hidden, opts} = Keyword.pop(opts, :hidden, [])
125+
{action, opts} = Keyword.pop(opts, :action)
121126

122127
id = to_string(id || form.id <> "_#{field}")
123128
name = to_string(name || form.name <> "[#{field}]")
@@ -133,6 +138,7 @@ defimpl Phoenix.HTML.FormData, for: Map do
133138
id: id,
134139
name: name,
135140
data: default,
141+
action: action,
136142
params: params || %{},
137143
hidden: hidden,
138144
options: opts
@@ -157,6 +163,7 @@ defimpl Phoenix.HTML.FormData, for: Map do
157163
source: conn_or_atom_or_map,
158164
impl: __MODULE__,
159165
index: index,
166+
action: action,
160167
id: id <> "_" <> index_string,
161168
name: name <> "[" <> index_string <> "]",
162169
data: data,

test/phoenix_html/form_test.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ defmodule Phoenix.HTML.FormTest do
138138
assert input_changed?(form, form(%{"foo" => "bar"}), "foo")
139139
end
140140

141+
test "input_changed? with changed action or method" do
142+
form = form(%{}, action: :validate)
143+
refute input_changed?(form, %{form | action: :validate}, :foo)
144+
assert input_changed?(form, %{form | action: :save}, :foo)
145+
end
146+
141147
describe "access" do
142148
test "without name and atom keys" do
143149
form =

0 commit comments

Comments
 (0)