表单
概述
简介

表单字段类在 Filament\Form\Components
命名空间之下。它们位于组件的 schema 数组中。Filament 自带多种类型的字段,适用于编辑不同类型的数据:
- Text input
- Select
- Checkbox
- Toggle
- Checkbox list
- Radio
- 日期时间选择器
- 文件上传
- 富文本编辑器
- Markdown 编辑器
- Repeater
- Builder
- Tags input
- Textarea
- Key-value
- 颜色选择器
- Toggle 按钮
- Slider
- 代码编辑器
- Hidden
你也可以创建自定义字段,以按照你希望的方式编辑数据。、
字段可以通过静态的 make()
方法创建,并传递其唯一名称。通常,字段名称与 Eloquent 模型上的属性名称相对应:
use Filament\Forms\Components\TextInput;
TextInput::make('name')

你可以使用“点语法”将字段绑定到数组中的键:
use Filament\Forms\Components\TextInput;
TextInput::make('socials.github_url')
验证字段
在 Laravel 中,验证规则通常定义在像 ['required','max:255']
这样的数组中, 或者像 required|max:255
这样的组合字符串中。如果你只在后端处理简单的表单请求,这很好。但 Filament 也能够为你的用户提供前端验证,这样他们就可以在发出任何后端请求之前修复错误。
在 Filament 中,你可以使用 required()
和 maxLength()
等方法向字段添加验证规则。这也优于 Laravel 的验证语法,因为你的 IDE 可以自动补全这些方法:
use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
TextInput::make('name')
->required()
->maxLength(255)
在此示例中,该字段是 required()
的且有一个 maxLength()
验证。大部分 Laravel 的验证规则都可以以方法的方式调用,你甚至可以添加自己的自定义规则。
设置字段标签
默认情况下,字段的标签将基于字段名称自动生成。要重写字段标签,请使用 label()
方法:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->label('Full name')
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
如果你需要为本地化使用翻译字符串,那么以此方式自定义标签非常有用:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->label(__('fields.name'))
TIP
你也可以使用 JavaScript 表达式来确定标签的内容,它可以读取表单中字段的当前值、
隐藏字段标签
将标签设置为空字符串以隐藏它可能很诱人,但不建议这样做。将标签设置为空字符串不会向屏幕阅读器传达字段的目的,即使目的在视觉上很明确。你应该使用 hiddenLabel()
方法,这样它在视觉上是隐藏的,但屏幕阅读器仍然可以访问:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->hiddenLabel()
或者,你也可以传入布尔值以控制字段是否该被隐藏:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->hiddenLabel(FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
设置字段默认值
字段可能有一个默认值。该默认值只在 Schema 加载时没有数据时使用。在标准的面板资源中,默认值只在新建页中使用,而不在编辑页中生效。要定义默认值,请使用 default()
方法:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->default('John')
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
禁用字段
你可以禁用字段以阻止用户编辑:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->disabled()

或者,你也可以传入布尔值以控制字段是否该被禁用:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->disabled(! FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
禁用字段将阻止其被保存。如果你想使之可保存,但不可编辑,请使用 dehydrated()
方法:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->disabled()
->dehydrated()
NOTE
If you choose to dehydrate the field, a skilled user could still edit the field’s value by manipulating Livewire’s JavaScript.
或者,你也可以传入布尔值以控制字段是否该被脱水(dehydrated):
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->disabled()
->dehydrated(FeatureFlag::active())
As well as allowing a static value, the dehydrated()
method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
基于当前操作禁用字段
The “operation” of a schema is the current action being performed on it. Usually, this is either create
, 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:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->disabledOn('edit')
// is the same as
Toggle::make('is_admin')
->disabled(fn (string $operation): bool => $operation === 'edit')
You can also pass an array of operations to the disabledOn()
method, and the field will be disabled if the current operation is any of the operations in the array:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->disabledOn(['edit', 'view'])
// is the same as
Toggle::make('is_admin')
->disabled(fn (string $operation): bool => in_array($operation, ['edit', 'view']))
NOTE
The disabledOn()
method will overwrite any previous calls to the disabled()
method, and vice versa.
隐藏字段
你也可以隐藏字段:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->hidden()
Optionally, you may pass a boolean value to control if the field should be hidden or not:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->hidden(! FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
Alternatively, you may use the visible()
method to control if the field should be hidden or not. In some situations, this may help to make your code more readable:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->visible(FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
NOTE
If both hidden()
and visible()
are used, they both need to indicate that the field should be visible for it to be shown.
使用 JavaScript 隐藏字段
如果你需要基于用户互动隐藏字段,你可以使用 hidden()
或 visible()
方法,并传入一个注入 utility 的函数,以确定是否该隐藏字段:
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
Select::make('role')
->options([
'user' => 'User',
'staff' => 'Staff',
])
->live()
Toggle::make('is_admin')
->hidden(fn (Get $get): bool => $get('role') !== 'staff')
本例中,role
字段设置成 live()
,这意味着,该 role
字段每次发生变化时, Schema 都会重新加载。这将会导致传入 hidden()
方法的函数重新计算,使之在 role
字段未设为 staff
时隐藏 is_admin
字段。
不过,每次都重新加载 Schema 会导致每次都需要重新发起网络请求,因为你没办法在客户端重新运行 PHP 函数。这对于性能不太友好。
作为替代方案,你可以编写 JavaScript 使之基于另一个字段值隐藏。这可以通过将 JavaScript 表达式传递给 hiddenJs()
方法来实现:
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
Select::make('role')
->options([
'user' => 'User',
'staff' => 'Staff',
])
Toggle::make('is_admin')
->hiddenJs(<<<'JS'
$get('role') !== 'staff'
JS)
虽然,传递给 hiddenJs()
的代码非常类似于 PHP,但它其实是 JavaScript。Filament 为 JavaScript 提供了 $get()
实用函数,使之行为与 PHP 的等效函数非常相似,而无需依赖于字段的 live()
。
visibleJs()
方法的用法也类似于 hiddenJs()
,它用以控制字段是否为可见:
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;
Select::make('role')
->options([
'user' => 'User',
'staff' => 'Staff',
])
Toggle::make('is_admin')
->visibleJs(<<<'JS'
$get('role') === 'staff'
JS)
NOTE
如果同时使用了 hiddenJs()
和 visibleJs()
,则需要它们都说明该字段是否可见才能显示。
基于当前操作隐藏字段
The “operation” of a schema is the current action being performed on it. Usually, this is either create
, 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:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->hiddenOn('edit')
// is the same as
Toggle::make('is_admin')
->hidden(fn (string $operation): bool => $operation === 'edit')
You can also pass an array of operations to the hiddenOn()
method, and the field will be hidden if the current operation is any of the operations in the array:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->hiddenOn(['edit', 'view'])
// is the same as
Toggle::make('is_admin')
->hidden(fn (string $operation): bool => in_array($operation, ['edit', 'view']))
NOTE
The hiddenOn()
method will overwrite any previous calls to the hidden()
method, and vice versa.
Alternatively, you may use the visibleOn()
method to control if the field should be hidden or not. In some situations, this may help to make your code more readable:
use Filament\Forms\Components\Toggle;
Toggle::make('is_admin')
->visibleOn('create')
Toggle::make('is_admin')
->visibleOn(['create', 'edit'])
NOTE
The visibleOn()
method will overwrite any previous calls to the visible()
method, and vice versa.
内联标签
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 the inlineLabel()
method:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->inlineLabel()

Optionally, you may pass a boolean value to control if the label should be displayed inline or not:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->inlineLabel(FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the inlineLabel()
on the component itself, and all fields within it will have their labels displayed inline:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
Section::make('Details')
->inlineLabel()
->schema([
TextInput::make('name'),
TextInput::make('email')
->label('Email address'),
TextInput::make('phone')
->label('Phone number'),
])

You can also use inlineLabel()
on the entire schema to display all labels inline:
use Filament\Schemas\Schema;
public function form(Schema $schema): Schema
{
return $schema
->inlineLabel()
->components([
// ...
]);
}
When using 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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Section;
Section::make('Details')
->inlineLabel()
->schema([
TextInput::make('name'),
TextInput::make('email')
->label('Email address'),
TextInput::make('phone')
->label('Phone number')
->inlineLabel(false),
])
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 the autofocus()
method:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->autofocus()
Optionally, you may pass a boolean value to control if the field should be autofocused or not:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->autofocus(FeatureFlag::active())
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the placeholder()
method:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->placeholder('John Doe')
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

将字段融合到一个分组
FusedGroup
组件可用于将多个字段”融合“到一起。以下这些字段可以很好的进行融合:
请将要融合的字段传入到 FusedGroup
组件的 make()
方法中:
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\FusedGroup;
FusedGroup::make([
TextInput::make('city')
->placeholder('City'),
Select::make('country')
->placeholder('Country')
->options([
// ...
]),
])

你可以使用 label()
方法为以上字段分组添加标签:
use Filament\Schemas\Components\FusedGroup;
FusedGroup::make([
// ...
])
->label('Location')

默认情况下,每个字段都独自一行。在移动设备上,这通常是最佳体验,但在桌面端,你可以使用 columns()
方法水平显示字段,它与布局组件相同:
use Filament\Schemas\Components\FusedGroup;
FusedGroup::make([
// ...
])
->label('Location')
->columns(2)

你可以传入 columnSpan()
到每个字段,以调整字段在网格中的宽度:
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\FusedGroup;
FusedGroup::make([
TextInput::make('city')
->placeholder('City')
->columnSpan(2),
Select::make('country')
->placeholder('Country')
->options([
// ...
]),
])
->label('Location')
->columns(3)

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.Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
To insert plain text, you can pass a string to these methods:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->belowContent('This is the user\'s full name.')

To insert a schema component, often a prime component, you can pass the component to the method:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Text;
use Filament\Support\Enums\FontWeight;
TextInput::make('name')
->belowContent(Text::make('This is the user\'s full name.')->weight(FontWeight::Bold))

To insert an action or action group, you can pass the action or action group to the method:
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->belowContent(Action::make('generate'))

You can insert any combination of content into the slots by passing an array of content to the method:
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->belowContent([
Icon::make(Heroicon::InformationCircle),
'This is the user\'s full name.',
Action::make('generate'),
])

You can also align the content in the slots by passing the array of content to either Schema::start()
(default), Schema::end()
or Schema::between()
:
use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Flex;
use Filament\Schemas\Components\Icon;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->belowContent(Schema::end([
Icon::make(Heroicon::InformationCircle),
'This is the user\'s full name.',
Action::make('generate'),
]))
TextInput::make('name')
->belowContent(Schema::between([
Icon::make(Heroicon::InformationCircle),
'This is the user\'s full name.',
Action::make('generate'),
]))
TextInput::make('name')
->belowContent(Schema::between([
Flex::make([
Icon::make(Heroicon::InformationCircle)
->grow(false),
'This is the user\'s full name.',
]),
Action::make('generate'),
]))
TIP
As you can see in the above example for Schema::between()
, a Flex
component is used to group the icon and text together so they do not have space between them. The icon uses grow(false)
to prevent it from taking up half of the horizontal space, allowing the text to consume the remaining space.

Adding extra content above a field’s label
You can insert extra content above a field’s label using the aboveLabel()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->aboveLabel([
Icon::make(Heroicon::Star),
'This is the content above the field\'s label'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the beforeLabel()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->beforeLabel(Icon::make(Heroicon::Star))
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the afterLabel()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->afterLabel([
Icon::make(Heroicon::Star),
'This is the content after the field\'s label'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

By default, the content in the 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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->afterLabel(Schema::start([
Icon::make(Heroicon::Star),
'This is the content after the field\'s label'
]))
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the belowLabel()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->belowLabel([
Icon::make(Heroicon::Star),
'This is the content below the field\'s label'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

NOTE
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 the aboveContent()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->aboveContent([
Icon::make(Heroicon::Star),
'This is the content above the field\'s content'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

NOTE
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 the beforeContent()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->beforeContent(Icon::make(Heroicon::Star))
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

TIP
Some fields, such as the text input, select, and date-time picker fields, have a prefix()
method to insert content before the field’s content, adjoined to the field itself. This is often a better UI choice than using beforeContent()
.

Adding extra content after a field’s content
You can insert extra content after a field’s content using the afterContent()
method. You can pass any content to this method, like text, a schema component, an action, or an action group:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->afterContent(Icon::make(Heroicon::Star))
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |

TIP
Some fields, such as the text input, select, and date-time picker fields, have a suffix()
method to insert content after the field’s content, adjoined to the field itself. This is often a better UI choice than using beforeContent()
.

Adding extra content above a field’s error message
You can insert extra content above a field’s error message using the aboveErrorMessage()
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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->required()
->aboveErrorMessage([
Icon::make(Heroicon::Star),
'This is the content above the field\'s error message'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the belowErrorMessage()
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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;
TextInput::make('name')
->required()
->belowErrorMessage([
Icon::make(Heroicon::Star),
'This is the content below the field\'s error message'
])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | 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 the extraAttributes()
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:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->extraAttributes(['title' => 'Text input'])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
TIP
By default, calling extraAttributes()
multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass merge: true
to the method.
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:
use Filament\Forms\Components\TextInput;
TextInput::make('categories')
->extraInputAttributes(['width' => 200])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
TIP
By default, calling extraInputAttributes()
multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass merge: true
to the method.
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:
use Filament\Forms\Components\TextInput;
TextInput::make('categories')
->extraFieldWrapperAttributes(['class' => 'components-locked'])
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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
TIP
By default, calling extraFieldWrapperAttributes()
multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass merge: true
to the method.
Field utility injection
The vast majority of methods used to configure fields accept functions as parameters instead of hardcoded values:
use App\Models\User;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
DatePicker::make('date_of_birth')
->displayFormat(function (): string {
if (auth()->user()->country_id === 'us') {
return 'm/d/Y';
}
return 'd/m/Y';
})
Select::make('user_id')
->options(function (): array {
return User::query()->pluck('name', 'id')->all();
})
TextInput::make('middle_name')
->required(fn (): bool => auth()->user()->hasMiddleName())
This alone unlocks many customization possibilities.
The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities.
These injected utilities require specific parameter names to be used. Otherwise, Filament doesn’t know what to inject.
Injecting the current state of the field
If you wish to access the current value (state) of the field, define a $state
parameter:
function ($state) {
// ...
}
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:
function ($rawState) {
// ...
}
Injecting the state of another field
You may also retrieve the state (value) of another field from within a callback, using a $get
parameter:
use Filament\Schemas\Components\Utilities\Get;
function (Get $get) {
$email = $get('email'); // Store the value of the `email` field in the `$email` variable.
//...
}
TIP
Unless a form field is reactive, the schema will not refresh when the value of the field changes, only when the next user interaction occurs that makes a request to the server. If you need to react to changes in a field’s value, it should be live()
.
Injecting the current Eloquent record
You may retrieve the Eloquent record for the current schema using a $record
parameter:
use Illuminate\Database\Eloquent\Model;
function (?Model $record) {
// ...
}
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 is create
, edit
or view
, use the $operation
parameter:
function (string $operation) {
// ...
}
NOTE
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:
use Livewire\Component;
function (Component $livewire) {
// ...
}
Injecting the current field instance
If you wish to access the current component instance, define a $component
parameter:
use Filament\Forms\Components\Field;
function (Field $component) {
// ...
}
Injecting multiple utilities
The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Livewire\Component as Livewire;
function (Livewire $livewire, Get $get, Set $set) {
// ...
}
Injecting dependencies from Laravel’s container
You may inject anything from Laravel’s container like normal, alongside utilities:
use Filament\Schemas\Components\Utilities\Set;
use Illuminate\Http\Request;
function (Request $request, Set $set) {
// ...
}
Using JavaScript to determine text content
Methods that allow HTML to be rendered, such as label()
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
:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\JsContent;
TextInput::make('greetingResponse')
->label(JsContent::make(<<<'JS'
($get('name') === 'John Doe') ? 'Hello, John!' : 'Hello, stranger!'
JS
))
The $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 the live()
method:
use Filament\Forms\Components\Select;
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->live()
In this example, when the user changes the value of the 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 to live()
, 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:
use Filament\Forms\Components\TextInput;
TextInput::make('username')
->live(onBlur: true)
Debouncing reactive fields
You may wish to find a middle ground between live()
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:
use Filament\Forms\Components\TextInput;
TextInput::make('username')
->live(debounce: 500) // Wait 500ms before re-rendering the schema.
In this example, 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’s fill()
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:
use Closure;
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required()
->afterStateHydrated(function (TextInput $component, string $state) {
$component->state(ucwords($state));
})
As a shortcut for formatting the field’s state like this when it is hydrated, you can use the formatStateUsing()
method:
use Closure;
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->formatStateUsing(fn (string $state): string => ucwords($state))
Field updates
You may use the afterStateUpdated()
method to customize what happens after the user updates a field:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->afterStateUpdated(function (?string $state, ?string $old) {
// ...
})
The afterStateUpdated()
method injects various utilities into the function as parameters.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Old state | mixed | $old | The old value of the field, before it was updated. |
Old raw state | mixed | $oldRaw | The old value of the field, before state casts were applied. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
Set function | Filament\Schemas\Components\Utilities\Set | $set | A function to set values in the current form data. |
State | mixed | $state | The current value of the field. Validation is not run. |
TIP
When using afterStateUpdated()
on a reactive field, interactions will not feel instant since a network request is made. There are a few ways you can optimize and avoid rendering which will make the interaction feel faster.
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:
use Filament\Schemas\Components\Utilities\Set;
function (Set $set) {
$set('title', 'Blog Post'); // Set the `title` field to `Blog Post`.
//...
}
When this function is run, the state of the 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:
use Filament\Schemas\Components\Utilities\Set;
function (Set $set) {
$set('title', 'Blog Post', shouldCallUpdatedHooks: true);
//...
}
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’s getState()
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:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required()
->dehydrateStateUsing(fn (string $state): string => ucwords($state))
Preventing a field from being dehydrated
You may also prevent a field from being dehydrated altogether using dehydrated(false)
. In this example, the field will not be present in the array returned from getState()
:
use Filament\Forms\Components\TextInput;
TextInput::make('password_confirmation')
->password()
->dehydrated(false)
If your schema auto-saves data to the database, like in a resource, this is useful to prevent a field from being saved to the database if it is purely used for presentational purposes.
NOTE
Even when a field is not dehydrated, it is still validated. To learn more about this behavior, see the validation section.
字段渲染
Each time a reactive field is updated, the HTML 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.
字段部分渲染
In this example, the value of the “name” input is used in the label of the “email” input. The “name” input is live()
, 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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Get;
TextInput::make('name')
->live()
TextInput::make('email')
->label(fn (Get $get): string => filled($get('name')) ? "Email address for {$get('name')}" : 'Email address')
In this case, a simple call to 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:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->live()
->partiallyRenderComponentsAfterStateUpdated(['email'])
Alternatively, you can instruct Filament to re-render the current component only, using partiallyRenderAfterStateUpdated()
. This is useful if the reactive component is the only one that depends on its current state:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->live()
->partiallyRenderAfterStateUpdated()
->belowContent(fn (Get $get): ?string => filled($get('name')) ? "Hi, {$get('name')}!" : null)
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 the skipRenderAfterStateUpdated()
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:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->live()
->skipRenderAfterStateUpdated()
->afterStateUpdated(function (string $state) {
// Do something with the state, but don't re-render the Livewire component.
})
Since setting the state of another field from an 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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Utilities\Set;
// Old name input that is `live()`, so it makes a network request and render each time it is updated.
TextInput::make('name')
->live()
->afterStateUpdated(fn (Set $set, ?string $state) => $set('email', ((string) str($state)->replace(' ', '.')->lower()) . '@example.com'))
// New name input that uses `afterStateUpdatedJs()` to set the state of the email field and doesn't make a network request.
TextInput::make('name')
->afterStateUpdatedJs(<<<'JS'
$set('email', ($state ?? '').replaceAll(' ', '.').toLowerCase() + '@example.com')
JS)
TextInput::make('email')
->label('Email address')
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 the hidden()
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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\TextInput;
Checkbox::make('is_company')
->live()
TextInput::make('company_name')
->hidden(fn (Get $get): bool => ! $get('is_company'))
In this example, the 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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\TextInput;
Checkbox::make('is_company')
->live()
TextInput::make('company_name')
->visible(fn (Get $get): bool => $get('is_company'))
TIP
Using live()
means the schema reloads every time the field changes, triggering a network request.
Alternatively, you can use JavaScript to hide the field based on another field’s value.
Conditionally making a field required
To conditionally make a field required, you can pass a function to the required()
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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\TextInput;
TextInput::make('company_name')
->live(onBlur: true)
TextInput::make('vat_number')
->required(fn (Get $get): bool => filled($get('company_name')))
In this example, the 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 the afterStateUpdated()
method on the title field to $set()
the value of the slug field:
use Filament\Schemas\Components\Utilities\Set;
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Str;
TextInput::make('title')
->live(onBlur: true)
->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state)))
TextInput::make('slug')
In this example, the 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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Str;
TextInput::make('title')
->live(onBlur: true)
->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) {
if (($get('slug') ?? '') !== Str::slug($old)) {
return;
}
$set('slug', Str::slug($state));
})
TextInput::make('slug')
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 the options()
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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\Select;
Select::make('category')
->options([
'web' => 'Web development',
'mobile' => 'Mobile development',
'design' => 'Design',
])
->live()
Select::make('sub_category')
->options(fn (Get $get): array => match ($get('category')) {
'web' => [
'frontend_web' => 'Frontend development',
'backend_web' => 'Backend development',
],
'mobile' => [
'ios_mobile' => 'iOS development',
'android_mobile' => 'Android development',
],
'design' => [
'app_design' => 'Panel design',
'marketing_website_design' => 'Marketing website design',
],
default => [],
})
In this example, the 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:
use Filament\Schemas\Components\Utilities\Get;
use Filament\Forms\Components\Select;
use Illuminate\Support\Collection;
Select::make('category')
->options(Category::query()->pluck('name', 'id'))
->live()
Select::make('sub_category')
->options(fn (Get $get): Collection => SubCategory::query()
->where('category', $get('category'))
->pluck('name', 'id'))
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 the schema()
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.
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Utilities\Get;
Select::make('type')
->options([
'employee' => 'Employee',
'freelancer' => 'Freelancer',
])
->live()
->afterStateUpdated(fn (Select $component) => $component
->getContainer()
->getComponent('dynamicTypeFields')
->getChildSchema()
->fill())
Grid::make(2)
->schema(fn (Get $get): array => match ($get('type')) {
'employee' => [
TextInput::make('employee_number')
->required(),
FileUpload::make('badge')
->image()
->required(),
],
'freelancer' => [
TextInput::make('hourly_rate')
->numeric()
->required()
->prefix('€'),
FileUpload::make('contract')
->required(),
],
default => [],
})
->key('dynamicTypeFields')
In this example, the 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:
use Filament\Forms\Components\TextInput;
TextInput::make('password')
->password()
And you can use a dehydration function to hash the password when the form is submitted:
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Facades\Hash;
TextInput::make('password')
->password()
->dehydrateStateUsing(fn (string $state): string => Hash::make($state))
But if your schema is used to change an existing password, you don’t want to overwrite the existing password if the field is empty. You can prevent the field from being dehydrated if the field is null or an empty string (using the filled()
helper):
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Facades\Hash;
TextInput::make('password')
->password()
->dehydrateStateUsing(fn (string $state): string => Hash::make($state))
->dehydrated(fn (?string $state): bool => filled($state))
However, you want to require the password to be filled when the user is being created, by injecting the $operation
utility, and then conditionally making the field required:
use Filament\Forms\Components\TextInput;
use Illuminate\Support\Facades\Hash;
TextInput::make('password')
->password()
->dehydrateStateUsing(fn (string $state): string => Hash::make($state))
->dehydrated(fn (?string $state): bool => filled($state))
->required(fn (string $operation): bool => $operation === 'create')
NOTE
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 a HasOne
, 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:
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Fieldset;
Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])
In this example, the 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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Group;
Group::make()
->relationship('customer')
->schema([
TextInput::make('name')
->label('Customer')
->required(),
TextInput::make('email')
->label('Email address')
->email()
->required(),
])
将数据保存到 BelongsTo
或 MorphTo
关联
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()
.
为 MorphTo
关联指定关联模型
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:
use App\Models\Organization;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Group;
Group::make()
->relationship('customer', relatedModel: Organization::class)
->schema([
// ...
])
In this example, 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.
Learn more about utility injection.
Utility | Type | Parameter | Description |
---|---|---|---|
Field | Filament\Forms\Components\Field | $component | The current field component instance. |
Get function | Filament\Schemas\Components\Utilities\Get | $get | A function for retrieving values from the current form data. Validation is not run. |
Livewire | Livewire\Component | $livewire | The Livewire component instance. |
Eloquent model FQN | ?string<Illuminate\Database\Eloquent\Model> | $model | The Eloquent model FQN for the current schema. |
Operation | string | $operation | The current operation being performed by the schema. Usually create , edit , or view . |
Raw state | mixed | $rawState | The current value of the field, before state casts were applied. Validation is not run. |
Eloquent record | ?Illuminate\Database\Eloquent\Model | $record | The Eloquent record for the current schema. |
State | mixed | $state | The current value of the field. Validation is not run. |
条件性将数据保存到关联中
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 a condition
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:
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Group;
Group::make()
->relationship(
'customer',
condition: fn (?array $state): bool => filled($state['name']),
)
->schema([
TextInput::make('name')
->label('Customer'),
TextInput::make('email')
->label('Email address')
->email()
->requiredWith('name'),
])
本例中,客户名非必须的,而邮箱地址只有在 name
字段填写后才是必须的。condition
函数用以检测 name
字段是否已填写,如果填写了,该客户将被创建或更新。否则,客户将不会被创建,如果已经存在,则会被删除。
全局设置
如果你希望全局修改字段的默认行为,那么你可以在服务提供者的 boot()
方法或者中间件中调用静态的 configureUsing()
方法。传入一个可以修改组件的闭包。比如你想让所有的 Checkbox 都设为 inline(false)
,你可以这样设置:
use Filament\Forms\Components\Checkbox;
Checkbox::configureUsing(function (Checkbox $checkbox): void {
$checkbox->inline(false);
});
当然,你仍然可以单独在每个字段中重写该行为:
use Filament\Forms\Components\Checkbox;
Checkbox::make('is_admin')
->inline()
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion