View Source Phoenix.HTML.Form (Phoenix.HTML v4.0.0)

Define a Phoenix.HTML.Form struct and functions to interact with it.

For building actual forms in your Phoenix application, see the Phoenix.Component.form/1 component.

Access behaviour

The Phoenix.HTML.Form struct implements the Access behaviour. When you do form[field], it returns a Phoenix.HTML.FormField struct with the id, name, value, and errors prefilled.

The field name can be either an atom or a string. If it is an atom, it assumes the form keeps both data and errors as atoms. If it is a string, it considers that data and errors are stored as strings for said field. Forms backed by an Ecto.Changeset only support atom field names.

It is possible to "access" fields which do not exist in the source data structure. A Phoenix.HTML.FormField struct will be dynamically created with some attributes such as name and id populated.

Custom implementations

There is a protocol named Phoenix.HTML.FormData which can be implemented by any data structure that wants to be cast to the Phoenix.HTML.Form struct.

Summary

Functions

Defines the Phoenix.HTML.Form struct.

Receives two forms structs and checks if the given field changed.

Returns an id of a corresponding form field.

Returns an id of a corresponding form field and value attached to it.

Returns a name of a corresponding form field.

Returns the HTML validations that would apply to the given field.

Returns a value of a corresponding form field.

Normalizes an input value according to its input type.

Returns options to be used inside a select.

Types

@type field() :: atom() | String.t()
@type t() :: %Phoenix.HTML.Form{
  data: %{required(field()) => term()},
  errors: [{field(), term()}],
  hidden: Keyword.t(),
  id: String.t(),
  impl: module(),
  index: nil | non_neg_integer(),
  name: String.t(),
  options: Keyword.t(),
  params: %{required(binary()) => term()},
  source: Phoenix.HTML.FormData.t()
}

Functions

Link to this function

%Phoenix.HTML.Form{}

View Source (struct)

Defines the Phoenix.HTML.Form struct.

Its fields are:

  • :source - the data structure given to form_for/4 that implements the form data protocol

  • :impl - the module with the form data protocol implementation. This is used to avoid multiple protocol dispatches.

  • :id - the id to be used when generating input fields

  • :index - the index of the struct in the form

  • :name - the name to be used when generating input fields

  • :data - the field used to store lookup data

  • :params - the parameters associated with this form

  • :hidden - a keyword list of fields that are required to submit the form behind the scenes as hidden inputs

  • :options - a copy of the options given when creating the form via form_for/4 without any form data specific key

  • :errors - a keyword list of errors that are associated with the form

Link to this function

input_changed?(form1, form2, field)

View Source
@spec input_changed?(t(), t(), field()) :: boolean()

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.

@spec input_id(t() | atom(), field()) :: String.t()

Returns an id of a corresponding form field.

The form should either be a Phoenix.HTML.Form emitted by form_for or an atom.

Link to this function

input_id(name, field, value)

View Source
@spec input_id(t() | atom(), field(), Phoenix.HTML.Safe.t()) :: String.t()

Returns an id of a corresponding form field and value attached to it.

Useful for radio buttons and inputs like multiselect checkboxes.

Link to this function

input_name(form_or_name, field)

View Source
@spec input_name(t() | atom(), field()) :: String.t()

Returns a name of a corresponding form field.

The first argument should either be a Phoenix.HTML.Form or an atom.

Examples

iex> Phoenix.HTML.Form.input_name(:user, :first_name)
"user[first_name]"
Link to this function

input_validations(form, field)

View Source
@spec input_validations(t(), field()) :: Keyword.t()

Returns the HTML validations that would apply to the given field.

Link to this function

input_value(form, field)

View Source
@spec input_value(t() | atom(), field()) :: term()

Returns a value of a corresponding form field.

The form should either be a Phoenix.HTML.Form or an atom. The field is either a string or an atom. If the field is given as an atom, it will attempt to look data with atom keys. If a string, it will look data with string keys.

When a form is given, it will look for changes, then fallback to parameters, and finally fallback to the default struct/map value.

Since the function looks up parameter values too, there is no guarantee that the value will have a certain type. For example, a boolean field will be sent as "false" as a parameter, and this function will return it as is. If you need to normalize the result of input_value, see normalize_value/2.

Link to this function

normalize_value(arg1, value)

View Source

Normalizes an input value according to its input type.

Certain HTML input values must be cast, or they will have idiosyncracies when they are rendered. The goal of this function is to encapsulate this logic. In particular:

  • For "datetime-local" types, it converts DateTime and NaiveDateTime to strings without the second precision

  • For "checkbox" types, it returns a boolean depending on whether the input is "true" or not

  • For "textarea", it prefixes a newline to ensure newlines won't be ignored on submission. This requires however that the textarea is rendered with no spaces after its content

Link to this function

options_for_select(options, selected_values)

View Source

Returns options to be used inside a select.

This is useful when building the select by hand. It expects all options and one or more select values.

Examples

options_for_select(["Admin": "admin", "User": "user"], "admin")
#=> <option value="admin" selected>Admin</option>
#=> <option value="user">User</option>

Multiple selected values:

options_for_select(["Admin": "admin", "User": "user", "Moderator": "moderator"],
  ["admin", "moderator"])
#=> <option value="admin" selected>Admin</option>
#=> <option value="user">User</option>
#=> <option value="moderator" selected>Moderator</option>

Groups are also supported:

options_for_select(["Europe": ["UK", "Sweden", "France"], ...], nil)
#=> <optgroup label="Europe">
#=>   <option>UK</option>
#=>   <option>Sweden</option>
#=>   <option>France</option>
#=> </optgroup>