useLiveForm composable for building complex forms with server-side validation, nested objects, and dynamic arrays in LiveVue.
Quick example
Here’s how a typical form setup looks withuseLiveForm:
Why useLiveForm?
Traditional client-side forms present several challenges:- Validation synchronization between client and server
- Complex state management for nested objects and arrays
- Type safety for deeply nested form structures
- Accessibility and proper ARIA attributes
- User experience patterns like field states and error handling
useLiveForm composable solves these problems by:
- Providing seamless server-side validation with debouncing
- Offering type-safe field access for complex structures
- Managing all form state reactively (dirty, touched, valid)
- Automatically generating proper input attributes and accessibility features
- Handling nested objects and dynamic arrays with ease
Form API reference
useLiveForm()
Creates a reactive form instance with validation and state management.form- Reactive reference to the form data from LiveView (typically() => props.form)options- Configuration object for form behavior
| Option | Type | Default | Description |
|---|---|---|---|
changeEvent | string | null | null | Event sent on field changes (set to null to disable validation events) |
submitEvent | string | "submit" | Event sent on form submission |
debounceInMiliseconds | number | 300 | Debounce delay for change events to reduce server load |
prepareData | function | (data) => data | Transform data before sending to server |
Form instance properties
Form instance properties
Form-level state:
Field factory functions:
Form actions:
| Property | Type | Description |
|---|---|---|
isValid | Ref<boolean> | No validation errors exist |
isDirty | Ref<boolean> | Form values differ from initial |
isTouched | Ref<boolean> | At least one field has been interacted with |
isValidating | Readonly<Ref<boolean>> | Whether validation requests are in progress |
submitCount | Readonly<Ref<number>> | Number of submission attempts |
initialValues | Readonly<Ref<T>> | Original form values for reset |
| Method | Description |
|---|---|
field(path, options?) | Get a typed field instance for the given path |
fieldArray(path) | Get an array field instance for managing dynamic lists |
| Method | Description |
|---|---|
submit() | Submit form to server (returns Promise) |
reset() | Reset to initial values and clear state |
FormField
Individual form field with reactive state and helpers:Field properties
Field properties
Reactive state:
Input binding:
Navigation methods:
Field actions:
| Property | Type | Description |
|---|---|---|
value | Ref<T> | Current field value |
errors | Readonly<Ref<string[]>> | Validation errors from server |
errorMessage | Readonly<Ref<string | undefined>> | First error message |
isValid | Ref<boolean> | No validation errors |
isDirty | Ref<boolean> | Value differs from initial |
isTouched | Ref<boolean> | Field has been blurred |
| Property | Description |
|---|---|
inputAttrs | Object containing value, event handlers, name, id, and accessibility attributes. Use with v-bind |
| Method | Description |
|---|---|
field(key) | Access nested object field |
fieldArray(key) | Access nested array field |
| Method | Description |
|---|---|
blur() | Mark field as touched |
FormFieldArray
Array field with additional methods for array manipulation:Array field properties
Array field properties
Array operations:
Reactive array:
Individual array item access:
| Method | Description |
|---|---|
add(item?) | Add new item to array. Returns a promise. |
remove(index) | Remove item by index. Returns a promise. |
move(from, to) | Move item to different position. Returns a promise. |
| Property | Description |
|---|---|
fields | Array of field instances for iteration (FormField<T>[]) |
| Method | Description |
|---|---|
field(path) | Get individual array item fields (e.g., field(0), field('[0].name')) |
fieldArray(path) | Get nested array fields within array items |
Working with fields
Field state
Each field provides reactive state that updates automatically:Input binding
TheinputAttrs property provides all necessary attributes for form inputs:
Checkbox fields
LiveVue supports three checkbox patterns:- Boolean checkbox
- Single with value
- Multiple checkboxes
For simple true/false fields:
Nested fields
Object navigation
Access nested object fields using dot notation:Complex nested structures
Array fields
Basic array operations
Complex array structures
Handle arrays of objects with nested properties:Server-side integration
Ecto changeset integration
LiveVue forms work seamlessly with Ecto changesets:LiveView form handling
Form reset on successful submission
By default,useLiveForm does not automatically reset form state after submission. You can opt into automatic form reset by returning {:reply, %{reset: true}, socket} from your submit event handler:
- Reset all field values to their current server state
- Clear all touched states (
isTouchedbecomesfalse) - Reset submit count to 0
- Clear dirty states (
isDirtybecomesfalse) - Update
initialValuesto match current form values
Advanced patterns
Data transformation
Transform form data before sending to the server usingprepareData:
Conditional field logic
Show/hide fields based on form state:Next steps
- Configuration for advanced setup and customization options
- Basic usage for fundamental patterns