diff --git a/lib/phoenix_html/form.ex b/lib/phoenix_html/form.ex
index 53a7eec..2207254 100644
--- a/lib/phoenix_html/form.ex
+++ b/lib/phoenix_html/form.ex
@@ -60,25 +60,25 @@ defmodule Phoenix.HTML.Form do
id: nil,
name: nil,
data: nil,
+ action: nil,
hidden: [],
params: %{},
errors: [],
options: [],
- index: nil,
- action: nil
+ index: nil
@type t :: %Form{
source: Phoenix.HTML.FormData.t(),
name: String.t(),
data: %{field => term},
+ action: nil | String.t() | atom(),
params: %{binary => term},
hidden: Keyword.t(),
options: Keyword.t(),
errors: [{field, term}],
impl: module,
id: String.t(),
- index: nil | non_neg_integer,
- action: nil | String.t()
+ index: nil | non_neg_integer
}
@type field :: atom | String.t()
@@ -189,18 +189,32 @@ defmodule Phoenix.HTML.Form do
@doc """
Receives two forms structs and checks if the given field changed.
- The field will have changed if either its associated value or errors
- changed. This is mostly used for optimization engines as an extension
- of the `Access` behaviour.
+ The field will have changed if either its associated value, errors,
+ action, or implementation changed. This is mostly used for optimization
+ engines as an extension of the `Access` behaviour.
"""
@spec input_changed?(t, t, field()) :: boolean()
def input_changed?(
- %Form{impl: impl1, id: id1, name: name1, errors: errors1, source: source1} = form1,
- %Form{impl: impl2, id: id2, name: name2, errors: errors2, source: source2} = form2,
+ %Form{
+ impl: impl1,
+ id: id1,
+ name: name1,
+ errors: errors1,
+ source: source1,
+ action: action1
+ } = form1,
+ %Form{
+ impl: impl2,
+ id: id2,
+ name: name2,
+ errors: errors2,
+ source: source2,
+ action: action2
+ } = form2,
field
)
when is_atom(field) or is_binary(field) do
- impl1 != impl2 or id1 != id2 or name1 != name2 or
+ impl1 != impl2 or id1 != id2 or name1 != name2 or action1 != action2 or
field_errors(errors1, field) != field_errors(errors2, field) or
impl1.input_value(source1, form1, field) != impl2.input_value(source2, form2, field)
end
diff --git a/lib/phoenix_html/form_data.ex b/lib/phoenix_html/form_data.ex
index 1444d35..3389d2b 100644
--- a/lib/phoenix_html/form_data.ex
+++ b/lib/phoenix_html/form_data.ex
@@ -56,6 +56,8 @@ defprotocol Phoenix.HTML.FormData do
applies if the field value is a list and no parameters were
sent through the form.
+ * `:action` - The user defined action being taken by the form, such
+ as `:validate`, `:save`, etc.
"""
@spec to_form(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field(), Keyword.t()) ::
[Phoenix.HTML.Form.t()]
@@ -86,6 +88,7 @@ defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom, Map] do
def to_form(conn_or_atom_or_map, opts) do
{name, params, opts} = name_params_and_opts(conn_or_atom_or_map, opts)
{errors, opts} = Keyword.pop(opts, :errors, [])
+ {action, opts} = Keyword.pop(opts, :action, nil)
id = Keyword.get(opts, :id) || name
unless is_binary(id) or is_nil(id) do
@@ -100,6 +103,7 @@ defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom, Map] do
params: params,
data: %{},
errors: errors,
+ action: action,
options: opts
}
end
@@ -146,6 +150,7 @@ defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom, Map] do
{name, opts} = Keyword.pop(opts, :as)
{id, opts} = Keyword.pop(opts, :id)
{hidden, opts} = Keyword.pop(opts, :hidden, [])
+ {action, opts} = Keyword.pop(opts, :action)
id = to_string(id || form.id <> "_#{field}")
name = to_string(name || form.name <> "[#{field}]")
@@ -161,6 +166,7 @@ defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom, Map] do
id: id,
name: name,
data: default,
+ action: action,
params: params || %{},
hidden: hidden,
options: opts
@@ -185,6 +191,7 @@ defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom, Map] do
source: conn_or_atom_or_map,
impl: __MODULE__,
index: index,
+ action: action,
id: id <> "_" <> index_string,
name: name <> "[" <> index_string <> "]",
data: data,
diff --git a/mix.exs b/mix.exs
index 5e44310..7a996f9 100644
--- a/mix.exs
+++ b/mix.exs
@@ -3,7 +3,7 @@ defmodule PhoenixHTML.Mixfile do
# Also change package.json version
@source_url "https://github.com/phoenixframework/phoenix_html"
- @version "3.3.3"
+ @version "3.3.4"
def project do
[
diff --git a/mix.lock b/mix.lock
index 273e659..05cd081 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,11 +1,11 @@
%{
- "earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"},
- "ex_doc": {:hex, :ex_doc, "0.30.6", "5f8b54854b240a2b55c9734c4b1d0dd7bdd41f71a095d42a70445c03cf05a281", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bd48f2ddacf4e482c727f9293d9498e0881597eae6ddc3d9562bd7923375109f"},
- "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
- "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
- "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"},
+ "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
+ "ex_doc": {:hex, :ex_doc, "0.34.0", "ab95e0775db3df71d30cf8d78728dd9261c355c81382bcd4cefdc74610bef13e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "60734fb4c1353f270c3286df4a0d51e65a2c1d9fba66af3940847cc65a8066d7"},
+ "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
+ "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
+ "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"},
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
- "nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
+ "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"plug": {:hex, :plug, "1.11.0", "f17217525597628298998bc3baed9f8ea1fa3f1160aa9871aee6df47a6e4d38e", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d9c633f0499f9dc5c2fd069161af4e2e7756890b81adcbb2ceaa074e8308876"},
"plug_crypto": {:hex, :plug_crypto, "1.2.0", "1cb20793aa63a6c619dd18bb33d7a3aa94818e5fd39ad357051a67f26dfa2df6", [:mix], [], "hexpm", "a48b538ae8bf381ffac344520755f3007cc10bd8e90b240af98ea29b69683fc2"},
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
diff --git a/package.json b/package.json
index 03bf9bd..8c20dc9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "phoenix_html",
- "version": "3.3.3",
+ "version": "3.3.4",
"main": "./priv/static/phoenix_html.js",
"repository": {},
"files": [
diff --git a/test/phoenix_html/form_test.exs b/test/phoenix_html/form_test.exs
index da2e9df..5834573 100644
--- a/test/phoenix_html/form_test.exs
+++ b/test/phoenix_html/form_test.exs
@@ -103,9 +103,9 @@ defmodule Phoenix.HTML.FormTest do
{:safe, ["2017-09-21", ?T, "20:21"]}
assert normalize_value("datetime-local", "2017-09-21 20:21:53") ==
- {:safe, "2017-09-21 20:21:53"}
+ "2017-09-21 20:21:53"
- assert normalize_value("datetime-local", "other") == {:safe, "other"}
+ assert normalize_value("datetime-local", "other") == "other"
end
test "for textarea" do
@@ -138,6 +138,12 @@ defmodule Phoenix.HTML.FormTest do
assert input_changed?(form, form(%{"foo" => "bar"}), "foo")
end
+ test "input_changed? with changed action or method" do
+ form = form(%{}, action: :validate)
+ refute input_changed?(form, %{form | action: :validate}, :foo)
+ assert input_changed?(form, %{form | action: :save}, :foo)
+ end
+
describe "access" do
test "without name and atom keys" do
form =