Introduction
Filament’s forms package allows you to easily build dynamic forms in your app. It’s used within other Filament packages to render forms within panel resources, action modals, table filters, and more. Learning how to build forms is essential to learning how to use these Filament packages. This guide will walk you through the basics of building forms with Filament’s form package. If you’re planning to add a new form to your own Livewire component, you should do that first and then come back. If you’re adding a form to a panel resource, or another Filament package, you’re ready to go!Form fields
Form field classes can be found in theFilament\Form\Components namespace. They reside within the schema array of components. Filament ships with many types of field, suitable for editing different types of data:
- Text input
- Select
- Checkbox
- Toggle
- Checkbox list
- Radio
- Date-time picker
- File upload
- Rich editor
- Markdown editor
- Repeater
- Builder
- Tags input
- Textarea
- Key-value
- Color picker
- Toggle buttons
- Slider
- Code editor
- Hidden
make() method, passing its unique name. Usually, the name of a field corresponds to the name of an attribute on an Eloquent model:
Validating fields
In Laravel, validation rules are usually defined in arrays like['required', 'max:255'] or a combined string like required|max:255. This is fine if you’re exclusively working in the backend with simple form requests. But Filament is also able to give your users frontend validation, so they can fix their mistakes before any backend requests are made.
In Filament, you can add validation rules to your fields by using methods like required() and maxLength(). This is also advantageous over Laravel’s validation syntax, since your IDE can autocomplete these methods:
required(), and has a maxLength(). We have methods for most of Laravel’s validation rules, and you can even add your own custom rules.
Setting a field’s label
By default, the label of the field will be automatically determined based on its name. To override the field’s label, you may use thelabel() method:
As well as allowing a static value, the label() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
label() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Hiding a field’s label
It may be tempting to set the label to an empty string to hide it, but this is not recommended. Setting the label to an empty string will not communicate the purpose of the field to screen readers, even if the purpose is clear visually. Instead, you should use thehiddenLabel() method, so it is hidden visually but still accessible to screen readers:
As well as allowing a static value, the hiddenLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
hiddenLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Setting the default value of a field
Fields may have a default value. The default is only used when a schema is loaded with no data. In a standard panel resource, defaults are used on the Create page, not the Edit page. To define a default value, use thedefault() method:
As well as allowing a static value, the default() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
default() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Disabling a field
You may disable a field to prevent it from being edited by the user:As well as allowing a static value, the disabled() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
disabled() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
saved() method:
If you choose to save the field when disabled, a skilled user could still edit the field’s value by manipulating Livewire’s JavaScript.
As well as allowing a static value, the saved() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
saved() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Disabling a field based on the current operation
The “operation” of a schema is the current action being performed on it. Usually, this is eithercreate, edit or view, if you are using the panel resource.
You can disable a field based on the current operation by passing an operation to the disabledOn() method:
disabledOn() method, and the field will be disabled if the current operation is any of the operations in the array:
Hiding a field
You may hide a field:As well as allowing a static value, the hidden() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
hidden() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
visible() method to control if the field should be hidden or not. In some situations, this may help to make your code more readable:
As well as allowing a static value, the visible() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
visible() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
If both
hidden() and visible() are used, they both need to indicate that the field should be visible for it to be shown.Hiding a field using JavaScript
If you need to hide a field based on a user interaction, you can use thehidden() or visible() methods, passing a function that uses utilities injected to determine whether the field should be hidden or not:
role field is set to live(), which means that the schema will reload the schema each time the role field is changed. This will cause the function that is passed to the hidden() method to be re-evaluated, which will hide the is_admin field if the role field is not set to staff.
However, reloading the schema each time a field causes a network request to be made, since there is no way to re-run the PHP function from the client-side. This is not ideal for performance.
Alternatively, you can write JavaScript to hide the field based on the value of another field. This is done by passing a JavaScript expression to the hiddenJs() method:
hiddenJs() looks very similar to PHP, it is actually JavaScript. Filament provides the $get() utility function to JavaScript that behaves very similar to its PHP equivalent, but without requiring the depended-on field to be live().
Any JavaScript string passed to the
hiddenJs() method will be executed in the browser, so you should never add user input directly into the string, as it could lead to cross-site scripting (XSS) vulnerabilities. User input from $state or $get() should never be evaluated as JavaScript code, but is safe to use as a string value, like in the example above.visibleJs() method is also available, which works in the same way as hiddenJs(), but controls if the field should be visible or not:
Any JavaScript string passed to the
visibleJs() method will be executed in the browser, so you should never add user input directly into the string, as it could lead to cross-site scripting (XSS) vulnerabilities. User input from $state or $get() should never be evaluated as JavaScript code, but is safe to use as a string value, like in the example above.If both
hiddenJs() and visibleJs() are used, they both need to indicate that the field should be visible for it to be shown.Hiding a field based on the current operation
The “operation” of a schema is the current action being performed on it. Usually, this is eithercreate, edit or view, if you are using the panel resource.
You can hide a field based on the current operation by passing an operation to the hiddenOn() method:
hiddenOn() method, and the field will be hidden if the current operation is any of the operations in the array:
visibleOn() method to control if the field should be hidden or not. In some situations, this may help to make your code more readable:
The
visibleOn() method will overwrite any previous calls to the visible() method, and vice versa.Inline labels
Fields may have their labels displayed inline with the field, rather than above it. This is useful for forms with many fields, where vertical space is at a premium. To display a field’s label inline, use theinlineLabel() method:
As well as allowing a static value, the inlineLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
inlineLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Using inline labels in multiple places at once
If you wish to display all labels inline in a layout component like a section or tab, you can use theinlineLabel() on the component itself, and all fields within it will have their labels displayed inline:
inlineLabel() on the entire schema to display all labels inline:
inlineLabel() on a layout component or schema, you can still opt-out of inline labels for individual fields by using the inlineLabel(false) method on the field:
Autofocusing a field when the schema is loaded
Most fields are autofocusable. Typically, you should aim for the first significant field in your schema to be autofocused for the best user experience. You can nominate a field to be autofocused using theautofocus() method:
As well as allowing a static value, the autofocus() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
autofocus() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Setting the placeholder of a field
Many fields can display a placeholder for when they have no value. This is displayed in the UI but never saved when the form is submitted. You may customize this placeholder using theplaceholder() method:
As well as allowing a static value, the placeholder() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
placeholder() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Fusing fields together into a group
AFusedGroup component can be used to “fuse” multiple fields together. The following fields can be fused together the best:
The fields that should be fused are passed to the make() method of the FusedGroup component:
label() method:
columns() method, the same as for layout components to display the fields horizontally:
columnSpan() to each field:
Adding extra content to a field
Fields contain many “slots” where content can be inserted in a child schema. Slots can accept text, any schema component, actions and action groups. Usually, prime components are used for content. The following slots are available for all fields:aboveLabel()beforeLabel()afterLabel()belowLabel()aboveContent()beforeContent()afterContent()belowContent()aboveErrorMessage()belowErrorMessage()
As well as allowing static values, the slot methods also accept functions to dynamically calculate them. You can inject various utilities into the functions as parameters.
Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Schema::start() (default), Schema::end() or Schema::between():
Adding extra content above a field’s label
You can insert extra content above a field’s label using theaboveLabel() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the aboveLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
aboveLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content before a field’s label
You can insert extra content before a field’s label using thebeforeLabel() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the beforeLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
beforeLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content after a field’s label
You can insert extra content after a field’s label using theafterLabel() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the afterLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
afterLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
afterLabel() schema is aligned to the end of the container. If you wish to align it to the start of the container, you should pass a Schema::start() object containing the content:
As well as allowing a static value, the afterLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
afterLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content below a field’s label
You can insert extra content below a field’s label using thebelowLabel() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the belowLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
belowLabel() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
This may seem like the same as the
aboveContent() method. However, when using inline labels, the aboveContent() method will place the content above the field, not below the label, since the label is displayed in a separate column to the field content.Adding extra content above a field’s content
You can insert extra content above a field’s content using theaboveContent() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the aboveContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
aboveContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
This may seem like the same as the
belowLabel() method. However, when using inline labels, the belowLabel() method will place the content below the label, not above the field’s content, since the label is displayed in a separate column to the field content.Adding extra content before a field’s content
You can insert extra content before a field’s content using thebeforeContent() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the beforeContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
beforeContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content after a field’s content
You can insert extra content after a field’s content using theafterContent() method. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the afterContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
afterContent() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content above a field’s error message
You can insert extra content above a field’s error message using theaboveErrorMessage() method. It will not be visible unless an error message is displayed. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the aboveErrorMessage() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
aboveErrorMessage() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra content below a field’s error message
You can insert extra content below a field’s error message using thebelowErrorMessage() method. It will not be visible unless an error message is displayed. You can pass any content to this method, like text, a schema component, an action, or an action group:
As well as allowing a static value, the belowErrorMessage() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
belowErrorMessage() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra HTML attributes to a field
You can pass extra HTML attributes to the field via theextraAttributes() method, which will be merged onto its outer HTML element. The attributes should be represented by an array, where the key is the attribute name and the value is the attribute value:
As well as allowing a static value, the extraAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
extraAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra HTML attributes to the input element of a field
Some fields use an underlying<input> or <select> DOM element, but this is often not the outer element in the field, so the extraAttributes() method may not work as you wish. In this case, you may use the extraInputAttributes() method, which will merge the attributes onto the <input> or <select> element in the field’s HTML:
As well as allowing a static value, the extraInputAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
extraInputAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Adding extra HTML attributes to the field wrapper
You can also pass extra HTML attributes to the very outer element of the “field wrapper” which surrounds the label and content of the field. This is useful if you want to style the label or spacing of the field via CSS, since you could target elements as children of the wrapper:As well as allowing a static value, the extraFieldWrapperAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
extraFieldWrapperAttributes() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Field utility injection
The vast majority of methods used to configure fields accept functions as parameters instead of hardcoded values:Injecting the current state of the field
If you wish to access the current value (state) of the field, define a$state parameter:
Injecting the raw state of the field
If a field casts its state automatically to a more useful format, you may wish to access the raw state. To do this, define a$rawState parameter:
Injecting the state of another field
You may also retrieve the state (value) of another field from within a callback, using a$get parameter:
Type-safe retrieval of another field’s state
You may use a “typed” method on theGet utility to retrieve the state of another field in a type-safe manner:
null. To force a nullable return type, pass the isNullable: true argument:
Injecting the current Eloquent record
You may retrieve the Eloquent record for the current schema using a$record parameter:
Injecting the current operation
If you’re writing a schema for a panel resource or relation manager, and you wish to check if a schema iscreate, edit or view, use the $operation parameter:
You can manually set a schema’s operation using the
$schema->operation() method.Injecting the current Livewire component instance
If you wish to access the current Livewire component instance, define a$livewire parameter:
Injecting the current field instance
If you wish to access the current component instance, define a$component parameter:
Injecting multiple utilities
The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order:Injecting dependencies from Laravel’s container
You may inject anything from Laravel’s container like normal, alongside utilities:Using JavaScript to determine text content
Methods that allow HTML to be rendered, such aslabel() and Text::make() passed to a belowContent() method can use JavaScript to calculate their content instead. This is achieved by passing a JsContent object to the method, which is Htmlable:
$state and $get utilities are available in this JavaScript context, so you can use them to access the state of the field and other fields in the schema.
The basics of reactivity
Livewire is a tool that allows Blade-rendered HTML to dynamically re-render without requiring a full page reload. Filament schemas are built on top of Livewire, so they are able to re-render dynamically, allowing their content to adapt after they are initially rendered. By default, when a user uses a field, the schema will not re-render. Since rendering requires a round-trip to the server, this is a performance optimization. However, if you wish to re-render the schema after the user has interacted with a field, you can use thelive() method:
status field, the schema will re-render. This allows you to then make changes to fields in the schema based on the new value of the status field. Also, you can hook in to the field’s lifecycle to perform custom logic when the field is updated.
Reactive fields on blur
By default, when a field is set tolive(), the schema will re-render every time the field is interacted with. However, this may not be appropriate for some fields like the text input, since making network requests while the user is still typing results in suboptimal performance. You may wish to re-render the schema only after the user has finished using the field, when it becomes out of focus. You can do this using the live(onBlur: true) method:
Debouncing reactive fields
You may wish to find a middle ground betweenlive() and live(onBlur: true), using “debouncing”. Debouncing will prevent a network request from being sent until a user has finished typing for a certain period of time. You can do this using the live(debounce: 500) method:
500 is the number of milliseconds to wait before sending a network request. You can customize this number to whatever you want, or even use a string like '1s'.
Field lifecycle
Each field in a schema has a lifecycle, which is the process it goes through when the schema is loaded, when it is interacted with by the user, and when it is submitted. You may customize what happens at each stage of this lifecycle using a function that gets run at that stage.Field hydration
Hydration is the process that fills fields with data. It runs when you call the schema’sfill() method. You may customize what happens after a field is hydrated using the afterStateHydrated() method.
In this example, the name field will always be hydrated with the correctly capitalized name:
formatStateUsing() method:
Field updates
You may use theafterStateUpdated() method to customize what happens after the user updates a field:
The afterStateUpdated() method injects various utilities into the function as parameters.
afterStateUpdated() method injects various utilities into the function as parameters.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Old state
$old
mixed
The old value of the field, before it was updated.
Old raw state
$oldRaw
mixed
The old value of the field, before state casts were applied.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
Set function
$set
Filament\Schemas\Components\Utilities\Set
A function to set values in the current form data.
State
$state
mixed
The current value of the field. Validation is not run.
Setting the state of another field
In a similar way to$get, you may also set the value of another field from within afterStateUpdated(), using a $set parameter:
title field will be updated, and the schema will re-render with the new title.
By default, the afterStateUpdated() method of the field you set is not called when you use $set(). If you wish to call it, you can pass shouldCallUpdatedHooks: true as an argument:
Field dehydration
Dehydration is the process that gets data from the fields in your schemas, optionally transforms it, and returns it. It runs when you call the schema’sgetState() method, which is usually called when a form is submitted.
You may customize how the state is transformed when it is dehydrated using the dehydrateStateUsing() function. In this example, the name field will always be dehydrated with the correctly capitalized name:
Preventing a field from being saved
You may prevent a field from being saved altogether usingsaved(false). In this example, the field will not be present in the array returned from getState(), and any relationships associated with the field will not be saved either:
Even when a field is not saved, it is still validated. To learn more about this behavior, see the validation section.
Field rendering
Each time a reactive field is updated, the HTML of the entire Livewire component that the schema belongs to is re-generated and sent to the frontend via a network request. In some cases, this may be overkill, especially if the schema is large and only certain components have changed.Field partial rendering
In this example, the value of the “name” input is used in the label of the “email” input. The “name” input islive(), so when the user types in the “name” input, the entire schema is re-rendered. This is not ideal, since only the “email” input needs to be re-rendered:
partiallyRenderComponentsAfterStateUpdated(), passing the names of other fields to re-render, will make the schema re-render only the specified fields after the state is updated:
partiallyRenderAfterStateUpdated(). This is useful if the reactive component is the only one that depends on its current state:
Preventing the Livewire component from rendering after a field is updated
If you wish to prevent the Livewire component from re-rendering when a field is updated, you can use theskipRenderAfterStateUpdated() method. This is useful if you want to perform some action when the field is updated, but you don’t want the Livewire component to re-render:
afterStateUpdated() function using the $set() method will actually just mutate the frontend state of fields, you don’t even need a network request in the first place. The afterStateUpdatedJs() method accepts a JavaScript expression that runs each time the value of the field changes. The $state, $get() and $set() utilities are available in the JavaScript context, so you can use them to set the state of other fields:
Any JavaScript string passed to the
afterStateUpdatedJs() method will be executed in the browser, so you should never add user input directly into the string, as it could lead to cross-site scripting (XSS) vulnerabilities. User input from $state or $get() should never be evaluated as JavaScript code, but is safe to use as a string value, like in the example above.Reactive forms cookbook
This section contains a collection of recipes for common tasks you may need to perform when building an advanced form.Conditionally hiding a field
To conditionally hide or show a field, you can pass a function to thehidden() method, and return true or false depending on whether you want the field to be hidden or not. The function can inject utilities as parameters, so you can do things like check the value of another field:
is_company checkbox is live(). This allows the schema to rerender when the value of the is_company field changes. You can access the value of that field from within the hidden() function using the $get() utility. The value of the field is inverted using ! so that the company_name field is hidden when the is_company field is false.
Alternatively, you can use the visible() method to show a field conditionally. It does the exact inverse of hidden(), and could be used if you prefer the clarity of the code when written this way:
Conditionally making a field required
To conditionally make a field required, you can pass a function to therequired() method, and return true or false depending on whether you want the field to be required or not. The function can inject utilities as parameters, so you can do things like check the value of another field:
company_name field is live(onBlur: true). This allows the schema to rerender after the value of the company_name field changes and the user clicks away. You can access the value of that field from within the required() function using the $get() utility. The value of the field is checked using filled() so that the vat_number field is required when the company_name field is not null or an empty string. The result is that the vat_number field is only required when the company_name field is filled in.
Using a function is able to make any other validation rule dynamic in a similar way.
Generating a slug from a title
To generate a slug from a title while the user is typing, you can use theafterStateUpdated() method on the title field to $set() the value of the slug field:
title field is live(onBlur: true). This allows the schema to rerender when the value of the title field changes and the user clicks away. The afterStateUpdated() method is used to run a function after the state of the title field is updated. The function injects the $set() utility and the new state of the title field. The Str::slug() utility method is part of Laravel and is used to generate a slug from a string. The slug field is then updated using the $set() function.
One thing to note is that the user may customize the slug manually, and we don’t want to overwrite their changes if the title changes. To prevent this, we can use the old version of the title to work out if the user has modified it themselves. To access the old version of the title, you can inject $old, and to get the current value of the slug before it gets changed, we can use the $get() utility:
Dependant select options
To dynamically update the options of a select field based on the value of another field, you can pass a function to theoptions() method of the select field. The function can inject utilities as parameters, so you can do things like check the value of another field using the $get() utility:
category field is live(). This allows the schema to rerender when the value of the category field changes. You can access the value of that field from within the options() function using the $get() utility. The value of the field is used to determine which options should be available in the sub_category field. The match () statement in PHP is used to return an array of options based on the value of the category field. The result is that the sub_category field will only show options relevant to the selected category field.
You could adapt this example to use options loaded from an Eloquent model or other data source, by querying within the function:
Dynamic fields based on a select option
You may wish to render a different set of fields based on the value of a field, like a select. To do this, you can pass a function to theschema() method of any layout component, which checks the value of the field and returns a different schema based on that value. Also, you will need a way to initialise the new fields in the dynamic schema when they are first loaded.
type field is live(). This allows the schema to rerender when the value of the type field changes. The afterStateUpdated() method is used to run a function after the state of the type field is updated. In this case, we inject the current select field instance, which we can then use to get the schema “container” instance that holds both the select and the grid components. With this container, we can target the grid component using a unique key (dynamicTypeFields) that we have assigned to it. With that grid component instance, we can call fill(), just as we do on a normal form to initialise it. The schema() method of the grid component is then used to return a different schema based on the value of the type field. This is done by using the $get() utility, and returning a different schema array dynamically.
Auto-hashing password field
You have a password field:filled() helper):
$operation utility, and then conditionally making the field required:
In this example,
Hash::make($state) shows how to use a dehydration function. However, you don’t need to do this if your Model uses 'password' => 'hashed' in its casts function — Laravel will handle hashing automatically.Saving data to relationships
As well as being able to give structure to fields, layout components are also able to “teleport” their nested fields into a relationship. Filament will handle loading data from aHasOne, BelongsTo or MorphOne Eloquent relationship, and then it will save the data back to the same relationship. To set this behavior up, you can use the relationship() method on any layout component:
title, description and image are automatically loaded from the metadata relationship, and saved again when the form is submitted. If the metadata record does not exist, it is automatically created.
This functionality is not just limited to fieldsets - you can use it with any layout component. For example, you could use a Group component which has no styling associated with it:
Saving data to a BelongsTo or MorphTo relationship
Please note that if you are saving the data to a BelongsTo or MorphTo relationship, then the foreign key column in your database must be nullable(). This is because Filament saves the schema first, before saving the relationship. Since the schema is saved first, the foreign ID does not exist yet, so it must be nullable. Immediately after the schema is saved, Filament saves the relationship, which will then fill in the foreign ID and save it again.
It is worth noting that if you have an observer on your schema model, then you may need to adapt it to ensure that it does not depend on the relationship existing when it is created. For example, if you have an observer that sends an email to a related record when a schema is created, you may need to switch to using a different hook that runs after the relationship is attached, like updated().
Specifying the related model for a MorphTo relationship
If you are using a MorphTo relationship, and you want Filament to be able to create MorphTo records instead of just updating them, you need to specify the related model using the relatedModel parameter of the relationship() method:
customer is a MorphTo relationship, and could be an Individual or Organization. By specifying the relatedModel parameter, Filament will be able to create Organization records when the form is submitted. If you do not specify this parameter, Filament will only be able to update existing records.
The relatedModel parameter also accepts a function that returns the related model class name. This is useful if you want to dynamically determine the related model based on the current state of the form. You can inject various utilities into this function.
relatedModel parameter also accepts a function that returns the related model class name. This is useful if you want to dynamically determine the related model based on the current state of the form. You can inject various utilities into this function.Learn more about utility injection.
Field
$component
Filament\Forms\Components\Field
The current field component instance.
Get function
$get
Filament\Schemas\Components\Utilities\Get
A function for retrieving values from the current form data. Validation is not run.
Livewire
$livewire
Livewire\Component
The Livewire component instance.
Eloquent model FQN
$model
?string<Illuminate\Database\Eloquent\Model>
The Eloquent model FQN for the current schema.
Operation
$operation
string
The current operation being performed by the schema. Usually
create, edit, or view.Raw state
$rawState
mixed
The current value of the field, before state casts were applied. Validation is not run.
Eloquent record
$record
?Illuminate\Database\Eloquent\Model
The Eloquent record for the current schema.
State
$state
mixed
The current value of the field. Validation is not run.
Conditionally saving data to a relationship
Sometimes, saving the related record may be optional. If the user fills out the customer fields, then the customer will be created / updated. Otherwise, the customer will not be created, or will be deleted if it already exists. To do this, you can pass acondition function as an argument to relationship(), which can use the $state of the related form to determine whether the relationship should be saved or not:
required(), and the email address is only required when the name is filled. The condition function is used to check whether the name field is filled, and if it is, then the customer will be created / updated. Otherwise, the customer will not be created, or will be deleted if it already exists.
Global settings
If you wish to change the default behavior of a field globally, then you can call the staticconfigureUsing() method inside a service provider’s boot() method or a middleware. Pass a closure which is able to modify the component. For example, if you wish to make all checkboxes inline(false), you can do it like so: