> For AI agents: the complete documentation index is at [llms.txt](https://reflex.dev/docs/llms.txt). Markdown versions are available by appending `.md` or sending `Accept: text/markdown`.

---
components:
  - rx.form
  - rx.form.root
  - rx.form.field
  - rx.form.control
  - rx.form.label
  - rx.form.message
  - rx.form.submit

FormRoot: |
  lambda **props: rx.form.root(
      rx.form.field(
          rx.flex(
              rx.form.label("Email"),
              rx.form.control(
                  rx.input(
                      placeholder="Email Address",
                      # type attribute is required for "typeMismatch" validation
                      type="email",
                  ),
                  as_child=True,
              ),
              rx.form.message("Please enter a valid email"),
              rx.form.submit(
                  rx.button("Submit"),
                  as_child=True,
              ),
              direction="column",
              spacing="2",
              align="stretch",
          ),
          name="email",
      ),
      **props,
  )

FormField: |
  lambda **props: rx.form.root(
      rx.form.field(
          rx.flex(
              rx.form.label("Email"),
              rx.form.control(
                  rx.input(
                      placeholder="Email Address",
                      # type attribute is required for "typeMismatch" validation
                      type="email",
                  ),
                  as_child=True,
              ),
              rx.form.message("Please enter a valid email", match="typeMismatch"),
              rx.form.submit(
                  rx.button("Submit"),
                  as_child=True,
              ),
              direction="column",
              spacing="2",
              align="stretch",
          ),
          **props,
      ),
      reset_on_submit=True,
  )

FormLabel: |
  lambda **props: rx.form.root(
      rx.form.field(
          rx.flex(
              rx.form.label("Email", **props,),
              rx.form.control(
                  rx.input(
                      placeholder="Email Address",
                      # type attribute is required for "typeMismatch" validation
                      type="email",
                  ),
                  as_child=True,
              ),
              rx.form.message("Please enter a valid email", match="typeMismatch"),
              rx.form.submit(
                  rx.button("Submit"),
                  as_child=True,
              ),
              direction="column",
              spacing="2",
              align="stretch",
          ),
      ),
      reset_on_submit=True,
  )

FormMessage: |
  lambda **props: rx.form.root(
              rx.form.field(
                  rx.flex(
                      rx.form.label("Email"),
                      rx.form.control(
                          rx.input(
                              placeholder="Email Address",
                              # type attribute is required for "typeMismatch" validation
                              type="email",
                          ),
                          as_child=True,
                      ),
                      rx.form.message("Please enter a valid email", **props,),
                      rx.form.submit(
                          rx.button("Submit"),
                          as_child=True,
                      ),
                      direction="column",
                      spacing="2",
                      align="stretch",
                  ),
                  name="email",
              ),
              on_submit=lambda form_data: rx.window_alert(form_data.to_string()),
              reset_on_submit=True,
          )
---

```python exec
import reflex as rx
```

# Form

Forms are used to collect user input. The `rx.form` component is used to group inputs and submit them together.

The form component's children can be form controls such as `rx.input`, `rx.checkbox`, `rx.slider`, `rx.textarea`, `rx.radio_group`, `rx.select` or `rx.switch`. The controls should have a `name` attribute that is used to identify the control in the form data. The `on_submit` event trigger submits the form data as a dictionary to the `handle_submit` event handler.

The form is submitted when the user clicks the submit button or presses enter on the form controls.

```python demo exec
class FormState(rx.State):
    form_data: dict = {}

    @rx.event
    def handle_submit(self, form_data: dict):
        """Handle the form submit."""
        self.form_data = form_data


def form_example():
    return rx.vstack(
        rx.form(
            rx.vstack(
                rx.input(placeholder="First Name", name="first_name"),
                rx.input(placeholder="Last Name", name="last_name"),
                rx.hstack(
                    rx.checkbox("Checked", name="check"),
                    rx.switch("Switched", name="switch"),
                ),
                rx.button("Submit", type="submit"),
            ),
            on_submit=FormState.handle_submit,
            reset_on_submit=True,
        ),
        rx.divider(),
        rx.heading("Results"),
        rx.text(FormState.form_data.to_string()),
    )
```

```md alert warning
# When using the form you must include a button or input with `type='submit'`.
```

```md alert info
# Using `name` vs `id`.

When using the `name` attribute in form controls like `rx.switch`, `rx.radio_group`, and `rx.checkbox`, these controls will only be included in the form data if their values are set (e.g., if the checkbox is checked, the switch is toggled, or a radio option is selected).

If you need these controls to be passed in the form data even when their values are not set, you can use the `id` attribute instead of name. The id attribute ensures that the control is always included in the submitted form data, regardless of whether its value is set or not.
```

```md video https://youtube.com/embed/ITOZkzjtjUA?start=5287&end=6040
# Video: Forms
```

## Dynamic Forms

Forms can be dynamically created by iterating through state vars using `rx.foreach`.

This example allows the user to add new fields to the form prior to submit, and all
fields will be included in the form data passed to the `handle_submit` function.

```python demo exec
class DynamicFormState(rx.State):
    form_data: dict = {}
    form_fields: list[str] = ["first_name", "last_name", "email"]

    @rx.var(cache=True)
    def form_field_placeholders(self) -> list[str]:
        return [
            " ".join(w.capitalize() for w in field.split("_"))
            for field in self.form_fields
        ]

    @rx.event
    def add_field(self, form_data: dict):
        new_field = form_data.get("new_field")
        if not new_field:
            return
        field_name = new_field.strip().lower().replace(" ", "_")
        self.form_fields.append(field_name)

    @rx.event
    def handle_submit(self, form_data: dict):
        self.form_data = form_data


def dynamic_form():
    return rx.vstack(
        rx.form(
            rx.vstack(
                rx.foreach(
                    DynamicFormState.form_fields,
                    lambda field, idx: rx.input(
                        placeholder=DynamicFormState.form_field_placeholders[idx],
                        name=field,
                    ),
                ),
                rx.button("Submit", type="submit"),
            ),
            on_submit=DynamicFormState.handle_submit,
            reset_on_submit=True,
        ),
        rx.form(
            rx.hstack(
                rx.input(placeholder="New Field", name="new_field"),
                rx.button("+", type="submit"),
            ),
            on_submit=DynamicFormState.add_field,
            reset_on_submit=True,
        ),
        rx.divider(),
        rx.heading("Results"),
        rx.text(DynamicFormState.form_data.to_string()),
    )
```

## API Reference

### rx.form

The Form component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `access_key` | str | - | Provides a hint for generating a keyboard shortcut for the current element. |
| `auto_capitalize` | Literal["off", "none", "on", "sentences", "words", "characters"] | - | Controls whether and how text input is automatically capitalized as it is entered/edited by the user. |
| `content_editable` | Literal["inherit", "plaintext-only"], bool | - | Indicates whether the element's content is editable. |
| `context_menu` | str | - | Defines the ID of a <menu> element which will serve as the element's context menu. |
| `dir` | str | - | Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left). |
| `draggable` | bool | - | Defines whether the element can be dragged. |
| `enter_key_hint` | Literal["enter", "done", "go", "next", "previous", "search", "send"] | - | Hints what media types the media element is able to play. |
| `hidden` | bool | - | Defines whether the element is hidden. |
| `input_mode` | Literal["none", "text", "tel", "url", "email", "numeric", "decimal", "search"] | - | Defines the type of the element. |
| `item_prop` | str | - | Defines the name of the element for metadata purposes. |
| `lang` | str | - | Defines the language used in the element. |
| `role` | Literal["alert", "alertdialog", "application", "article", "banner", "button", "cell", "checkbox", "columnheader", "combobox", "complementary", "contentinfo", "definition", "dialog", "directory", "document", "feed", "figure", "form", "grid", "gridcell", "group", "heading", "img", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "none", "note", "option", "presentation", "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", "searchbox", "separator", "slider", "spinbutton", "status", "switch", "tab", "table", "tablist", "tabpanel", "term", "textbox", "timer", "toolbar", "tooltip", "tree", "treegrid", "treeitem"] | - | Defines the role of the element. |
| `slot` | str | - | Assigns a slot in a shadow DOM shadow tree to an element. |
| `spell_check` | bool | - | Defines whether the element may be checked for spelling errors. |
| `tab_index` | int | - | Defines the position of the current element in the tabbing order. |
| `title` | str | - | Defines a tooltip for the element. |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |
| `accept` | str | - | MIME types the server accepts for file upload. |
| `accept_charset` | str | - | Character encodings to be used for form submission. |
| `action` | str | - | URL where the form's data should be submitted. |
| `auto_complete` | str | - | Whether the form should have autocomplete enabled. |
| `enc_type` | str | - | Encoding type for the form data when submitted. |
| `method` | str | - | HTTP method to use for form submission. |
| `name` | str | - | Name of the form. |
| `no_validate` | bool | - | Indicates that the form should not be validated on submit. |
| `target` | str | - | Where to display the response after submitting the form. |
| `reset_on_submit` | bool | - | If true, the form will be cleared after submit. |
| `handle_submit_unique_name` | str | - | The name used to make this form's submit handler function unique. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

Component-specific event triggers:

| Event Trigger | Description |
| --- | --- |
| `on_submit` | Fired when the form is submitted. |
| `on_clear_server_errors` | Fired when the errors are cleared. |

### rx.form.root

The root component of a radix form.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `access_key` | str | - | Provides a hint for generating a keyboard shortcut for the current element. |
| `auto_capitalize` | Literal["off", "none", "on", "sentences", "words", "characters"] | - | Controls whether and how text input is automatically capitalized as it is entered/edited by the user. |
| `content_editable` | Literal["inherit", "plaintext-only"], bool | - | Indicates whether the element's content is editable. |
| `context_menu` | str | - | Defines the ID of a <menu> element which will serve as the element's context menu. |
| `dir` | str | - | Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left). |
| `draggable` | bool | - | Defines whether the element can be dragged. |
| `enter_key_hint` | Literal["enter", "done", "go", "next", "previous", "search", "send"] | - | Hints what media types the media element is able to play. |
| `hidden` | bool | - | Defines whether the element is hidden. |
| `input_mode` | Literal["none", "text", "tel", "url", "email", "numeric", "decimal", "search"] | - | Defines the type of the element. |
| `item_prop` | str | - | Defines the name of the element for metadata purposes. |
| `lang` | str | - | Defines the language used in the element. |
| `role` | Literal["alert", "alertdialog", "application", "article", "banner", "button", "cell", "checkbox", "columnheader", "combobox", "complementary", "contentinfo", "definition", "dialog", "directory", "document", "feed", "figure", "form", "grid", "gridcell", "group", "heading", "img", "link", "list", "listbox", "listitem", "log", "main", "marquee", "math", "menu", "menubar", "menuitem", "menuitemcheckbox", "menuitemradio", "navigation", "none", "note", "option", "presentation", "progressbar", "radio", "radiogroup", "region", "row", "rowgroup", "rowheader", "scrollbar", "search", "searchbox", "separator", "slider", "spinbutton", "status", "switch", "tab", "table", "tablist", "tabpanel", "term", "textbox", "timer", "toolbar", "tooltip", "tree", "treegrid", "treeitem"] | - | Defines the role of the element. |
| `slot` | str | - | Assigns a slot in a shadow DOM shadow tree to an element. |
| `spell_check` | bool | - | Defines whether the element may be checked for spelling errors. |
| `tab_index` | int | - | Defines the position of the current element in the tabbing order. |
| `title` | str | - | Defines a tooltip for the element. |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |
| `accept` | str | - | MIME types the server accepts for file upload. |
| `accept_charset` | str | - | Character encodings to be used for form submission. |
| `action` | str | - | URL where the form's data should be submitted. |
| `auto_complete` | str | - | Whether the form should have autocomplete enabled. |
| `enc_type` | str | - | Encoding type for the form data when submitted. |
| `method` | str | - | HTTP method to use for form submission. |
| `name` | str | - | Name of the form. |
| `no_validate` | bool | - | Indicates that the form should not be validated on submit. |
| `target` | str | - | Where to display the response after submitting the form. |
| `reset_on_submit` | bool | - | If true, the form will be cleared after submit. |
| `handle_submit_unique_name` | str | - | The name used to make this form's submit handler function unique. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

Component-specific event triggers:

| Event Trigger | Description |
| --- | --- |
| `on_submit` | Fired when the form is submitted. |
| `on_clear_server_errors` | Fired when the errors are cleared. |

### rx.form.field

A form field component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |
| `name` | str | - | The name of the form field, that is passed down to the control and used to match with validation messages. |
| `server_invalid` | bool | - | Flag to mark the form field as invalid, for server side validation. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

### rx.form.control

A form control component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

### rx.form.label

A form label component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

### rx.form.message

A form message component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |
| `name` | str | - | Used to target a specific field by name when rendering outside of a Field part. |
| `match` | Literal["badInput", "patternMismatch", "rangeOverflow", "rangeUnderflow", "stepMismatch", "tooLong", "tooShort", "typeMismatch", "valid", "valueMissing"] | - | Used to indicate on which condition the message should be visible. |
| `force_match` | bool | - | Forces the message to be shown. This is useful when using server-side validation. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/

### rx.form.submit

A form submit component.

#### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as_child` | bool | - | Change the default rendered element for the one passed as a child. |

#### Event Triggers

Base event triggers: https://reflex.dev/docs/api-reference/event-triggers/
