Components Forms (v1)

Forms (v1)

This page is for users using the old form structure (pre Phoenix 1.7).

v1 way (pre Phoenix 1.7):

<.form :let={f} as={:user} for={@changeset} phx-submit="on_submit">
  <.form_field type="text_input" form={f} field={:your_field} />

  <.form_field
    form={f}
    field={:a_select_field}
    type="select"
    options={[{"Option 1", "1"}, {"Option 2", "2"}]}
  />

  <.button type="submit" label="Submit" />
</.form>

v2 way (Phoenix 1.7):

<.form for={@form} phx-submit="on_submit">
  <.field field={@form[:email]} />

  <.field
    field={@form[:email]}
    type="select"
    options={[{"Option 1", "1"}, {"Option 2", "2"}]}
  />

  <.button type="submit" label="Submit" />
</.form>

Go here for the v2 docs.

There are two ways of creating form fields
  1. All inclusive option: Use `.form_field', which includes the input label and any errors on the changeset. Use this if you just want a good looking form that works with errors out of the box.
  2. Explicit option: Individually write out the label, input and errors. Do this when you want to be more explicit option on where the label or errors go.
The following code shows both methods for each form element.
Form field
`.form_field` is the easiest way to create input fields. We support every field Phoenix supports plus more.
Gender
heex
          <.form :let={f} as={:user} for={@changeset}>
  <.form_field
    type="text_input"
    form={f}
    field={:your_field}
    placeholder="Placeholder"
  />
  <.form_field
    type="select"
    options={[Admin: "admin", User: "user"]}
    form={f}
    field={:select}
  />
  <.form_field type="password_input" form={f} field={:password} />
  <.form_field
    type="radio_group"
    options={[Male: "male", Female: "female", Other: "other"]}
    form={f}
    field={:gender}
  />
  <div class="flex justify-end gap-3">
    <.button type="button" label="Cancel" color="white" />
    <.button type="submit" label="Submit" />
  </div>
</.form>

        
Form Field properties
elixir
            # <.form_field>
  attr(:form, :any, doc: "the form object", required: true)
  attr(:field, :atom, doc: "field in changeset / form", required: true)
  attr(:label, :string, doc: "labels your field")
  attr(:label_class, :string, default: nil, doc: "extra CSS for your label")
  attr(:help_text, :string, default: nil, doc: "context/help for your field")

  attr(:type, :string, default: "text_input", values: [
    "text_input",
    "email_input",
    "number_input",
    "password_input",
    "search_input",
    "telephone_input",
    "url_input",
    "time_input",
    "time_select",
    "date_input",
    "date_select",
    "datetime_local_input",
    "datetime_select",
    "color_input",
    "file_input",
    "range_input",
    "textarea",
    "select",
    "checkbox",
    "checkbox_group",
    "radio_group",
    "switch",
    "hidden_input"],
  doc: "The type of input")

attr(:wrapper_classes, :string, default: "pc-form-field-wrapper", doc: "CSS class for wrapper")
attr :rest, :global, include: @form_attrs

        
Text input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.text_input form={f} field={:your_field} placeholder="eg. John" />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field
  type="text_input"
  form={f}
  field={:your_field}
  placeholder="Placeholder"
/>

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Email input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.email_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="email_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Number input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.number_input form={f} field={:your_field} placeholder="eg. 1" />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="number_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Password input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.password_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="password_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Search input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.search_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="search_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Telephone input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.telephone_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="telephone_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
URL input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.url_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="url_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Hidden input
heex
          <!-- Explicit option  -->
<.hidden_input form={f} field={:your_field} />

<!-- All inclusive option  -->
<.form_field type="hidden_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Time input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.time_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="time_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Time select
Time select
:
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.time_select form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="time_select" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#time_select/3 as opts.
Date input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.date_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="date_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#text_input/3 as opts.
Date select
Date select
/ /
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.date_select form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="date_select" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#time_select/3 as opts.
Datetime local input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.datetime_local_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="datetime_local_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#datetime_local_input/3 as opts.
Datetime select
Datetime select
/ / :
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.datetime_select form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="datetime_select" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#datetime_select/3 as opts.
Color input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.search_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="color_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#color_input/3 as opts.
File input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.file_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="file_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#file_input/3 as opts.
Range input
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.range_input form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="range_input" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#range_input/3 as opts.
Textarea
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.textarea form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="textarea" form={f} field={:your_field} />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#textarea/3 as opts.
Select
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />
<.select
  options={["Admin": "admin", "User": "user"]}
  form={f}
  field={:your_field}
/>
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field
  type="select"
  options={["Admin": "admin", "User": "user"]}
  form={f}
  field={:your_field}
/>

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#select/4 as opts.
Multiple select

We are yet to implement the HTML5 multiple select due to it being hard to use for end users. Instead we recommend using our checkbox group component.

Switch
heex
          <!-- Explicit option  -->
<.switch form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="switch" form={f} field={:your_field} label="I agree" />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#checkbox/3 as opts.
Checkbox
heex
          <!-- Explicit option  -->
<.checkbox form={f} field={:your_field} />
<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field type="checkbox" form={f} field={:your_field} label="I accept" />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#checkbox/3 as opts.
Checkbox group

Use this instead of a multiple select (when the field data type is a list).

Column layout
Row layout
heex
          <.form_field
  type="checkbox_group"
  form={f}
  field={:your_field}
  label="Column layout"
  options={[
    {"Option 1", "option_1"},
    {"Option 2", "option_2"},
    {"Option 3", "option_3"},
    {"Option 4", "option_4"}
  ]}
/>

<.form_field
  type="checkbox_group"
  form={f}
  layout={:row}
  field={:your_field}
  label="Row layout"
  options={[
    {"Option 1", "option_1"},
    {"Option 2", "option_2"},
    {"Option 3", "option_3"},
    {"Option 4", "option_4"}
  ]}
/>

        
Properties
elixir
            attr(:form, :any, default: nil, doc: "")
  attr(:field, :atom, default: nil, doc: "")
  attr(:label, :string, default: nil, doc: "labels your field")
  attr(:class, :string, default: "", doc: "extra classes for the text input")
  attr(:options, :list, default: [], doc: "options for the select")
  attr(:layout, :atom, default: :col, values: [:row, :col], doc: "layout for the checkboxes")
  attr(:checked, :list, doc: "a list of checked values")
  attr(:rest, :global, include: @form_attrs)

        
Radio
Column layout
Row layout
heex
          <!-- Explicit option  -->
<.form_label form={f} field={:your_field} />

<div class="flex flex-col gap-1">
  <label class="inline-flex items-center gap-3 text-sm text-gray-900 dark:text-gray-200">
    <.radio form={f} field={:your_field} value="green" />
    <div>Green</div>
  </label>

  <label class="inline-flex items-center gap-3 text-sm text-gray-900 dark:text-gray-200">
    <.radio form={f} field={:your_field} value="blue" />
    <div>Blue</div>
  </label>

  <label class="inline-flex items-center gap-3 text-sm text-gray-900 dark:text-gray-200">
    <.radio form={f} field={:your_field} value="gray" />
    <div>Gray</div>
  </label>
</div>

<.form_field_error form={f} field={:your_field} class="mt-1" />

<!-- All inclusive option  -->
<.form_field
  type="radio_group"
  form={f}
  field={:radio}
  options={["Option 1": "option_1", "Option 2": "option_2", "Option 3": "option_3"]}
  label="Column layout"
/>

<.form_field
  type="radio_group"
  form={f}
  field={:radio_group}
  layout={:row}
  label="Row layout"
  options={[
    "Option 1": "option_1",
    "Option 2": "option_2",
    "Option 3": "option_3"
  ]}
/>

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#radio_button/4 as opts.
Form label

Usually paired with inputs.

heex
          <.form_label form={f} field={:email} />
<.form_label form={f} field={:email} label="Custom label" />

        

Properties

All properties are forwarded to Phoenix.HTML.Form.html#label/3 as opts.
Form field error

Will display any errors in your changeset for a particular field.

heex
          <.form_field_error form={f} field={:your_field} />

        
Help text

You can add additional instructions at the bottom of any input.

Type your email above
heex
          <.form_label form={f} field={:email} />
<.text_input form={f} field={:email} />
<.form_help_text class="mt-2">Type your email above</.form_help_text>

OR

<.form_field
  type="text_input"
  form={f}
  field={:email}
  help_text="Type your email above"
/>