Packages
phoenix_html
2.14.3
4.3.0
4.2.1
4.2.0
4.1.1
4.1.0
4.0.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.0
3.1.0
3.0.4
3.0.3
retired
3.0.2
retired
3.0.1
retired
3.0.0
retired
2.14.3
2.14.2
2.14.1
2.14.0
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.12.0
2.11.2
2.11.1
2.11.0
2.10.5
2.10.4
2.10.3
2.10.2
2.10.1
2.10.0
2.9.3
2.9.2
2.9.1
2.9.0
2.8.0
2.7.0
2.7.0-dev
2.6.2
2.6.1
2.6.0
2.5.1
2.5.0
2.4.0
2.4.0-dev
2.3.1
2.3.0
2.2.0
2.1.2
2.1.1
2.1.0
2.0.1
2.0.0
2.0.0-dev
1.4.0
1.3.0
1.2.1
1.2.0
1.1.0
1.0.1
1.0.0
Phoenix view functions for working with HTML templates
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/phoenix_html/form_data.ex
defprotocol Phoenix.HTML.FormData do
@moduledoc """
Converts a data structure into a [`Phoenix.HTML.Form`](`t:Phoenix.HTML.Form.t/0`) struct.
"""
@doc """
Converts a data structure into a [`Phoenix.HTML.Form`](`t:Phoenix.HTML.Form.t/0`) struct.
The options are the same options given to `form_for/4`. It
can be used by implementations to configure their behaviour
and it must be stored in the underlying struct, with any
custom field removed.
"""
@spec to_form(t, Keyword.t()) :: Phoenix.HTML.Form.t()
def to_form(data, options)
@doc """
Converts the field in the given form based on the data structure
into a list of [`Phoenix.HTML.Form`](`t:Phoenix.HTML.Form.t/0`) structs.
The options are the same options given to `inputs_for/4`. It
can be used by implementations to configure their behaviour
and it must be stored in the underlying struct, with any
custom field removed.
"""
@spec to_form(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field(), Keyword.t()) ::
[Phoenix.HTML.Form.t()]
def to_form(data, form, field, options)
@doc """
Returns the value for the given field.
"""
@spec input_value(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field()) :: term
def input_value(data, form, field)
@doc """
Returns the HTML5 validations that would apply to
the given field.
"""
@spec input_validations(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field()) :: Keyword.t()
def input_validations(data, form, field)
@doc """
Receives the given field and returns its input type (:text_input,
:select, etc). Returns `nil` if the type is unknown.
"""
@spec input_type(t, Phoenix.HTML.Form.t(), Phoenix.HTML.Form.field()) :: atom | nil
def input_type(data, form, field)
end
defimpl Phoenix.HTML.FormData, for: [Plug.Conn, Atom] do
def to_form(conn_or_atom, opts) do
{name, params, opts} = name_params_and_opts(conn_or_atom, opts)
{errors, opts} = Keyword.pop(opts, :errors, [])
%Phoenix.HTML.Form{
source: conn_or_atom,
impl: __MODULE__,
id: name,
name: name,
params: params,
data: %{},
errors: errors,
options: opts
}
end
case @for do
Atom ->
defp name_params_and_opts(atom, opts) do
{params, opts} = Keyword.pop(opts, :params, %{})
{Atom.to_string(atom), params, opts}
end
Plug.Conn ->
defp name_params_and_opts(conn, opts) do
case Keyword.pop(opts, :as) do
{nil, opts} ->
{nil, conn.params, opts}
{name, opts} ->
name = to_string(name)
{name, Map.get(conn.params, name) || %{}, opts}
end
end
end
def to_form(conn_or_atom, form, field, opts) when is_atom(field) or is_binary(field) do
{default, opts} = Keyword.pop(opts, :default, %{})
{prepend, opts} = Keyword.pop(opts, :prepend, [])
{append, opts} = Keyword.pop(opts, :append, [])
{name, opts} = Keyword.pop(opts, :as)
{id, opts} = Keyword.pop(opts, :id)
{hidden, opts} = Keyword.pop(opts, :hidden, [])
id = to_string(id || form.id <> "_#{field}")
name = to_string(name || form.name <> "[#{field}]")
params = Map.get(form.params, field_to_string(field))
cond do
# cardinality: one
is_map(default) ->
[
%Phoenix.HTML.Form{
source: conn_or_atom,
impl: __MODULE__,
id: id,
name: name,
data: default,
params: params || %{},
hidden: hidden,
options: opts
}
]
# cardinality: many
is_list(default) ->
entries =
if params do
params
|> Enum.sort_by(&elem(&1, 0))
|> Enum.map(&{nil, elem(&1, 1)})
else
Enum.map(prepend ++ default ++ append, &{&1, %{}})
end
for {{data, params}, index} <- Enum.with_index(entries) do
index_string = Integer.to_string(index)
%Phoenix.HTML.Form{
source: conn_or_atom,
impl: __MODULE__,
index: index,
id: id <> "_" <> index_string,
name: name <> "[" <> index_string <> "]",
data: data,
params: params,
hidden: hidden,
options: opts
}
end
end
end
def input_value(_conn_or_atom, %{data: data, params: params}, field)
when is_atom(field) or is_binary(field) do
case Map.fetch(params, field_to_string(field)) do
{:ok, value} ->
value
:error ->
Map.get(data, field)
end
end
def input_type(_conn_or_atom, _form, _field), do: :text_input
def input_validations(_conn_or_atom, _form, _field), do: []
# Normalize field name to string version
defp field_to_string(field) when is_atom(field), do: Atom.to_string(field)
defp field_to_string(field) when is_binary(field), do: field
end