Languages

Version

Theme

表单

概述

简介

Account settings form example

表单字段类在 Filament\Form\Components 命名空间之下。它们位于组件的 Schema 数组中。Filament 自带多种类型的字段,适用于编辑不同类型的数据:

你也可以创建自定义字段,以按照你希望的方式编辑数据。、

字段可以通过静态的 make() 方法创建,并传递其唯一名称。通常,字段名称与 Eloquent 模型上的属性名称相对应:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
Form field

你可以使用“点语法”将字段绑定到数组中的键:

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')
除了允许静态值之外,label() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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())
除了允许静态值之外,hiddenLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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')
除了允许静态值之外,default() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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()
Disabled form field

或者,你也可以传入布尔值以控制字段是否该被禁用:

use Filament\Forms\Components\Toggle;

Toggle::make('is_admin')
    ->disabled(! FeatureFlag::active())
除了允许静态值之外,disabled() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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

如果你选择脱水该字段,熟练的用户仍然可以通过操作 Livewire 的 JavaScript 来编辑该字段的值。

或者,你也可以传入布尔值以控制字段是否该被脱水(dehydrated):

use Filament\Forms\Components\Toggle;

Toggle::make('is_admin')
    ->disabled()
    ->dehydrated(FeatureFlag::active())
除了允许静态值之外,dehydrated() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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 的“操作”是指当前正在对其执行的操作。通常,如果你使用的是面板资源,则操作为 createeditview

你可以根据当前操作禁用字段,只需将操作传递给 disabledOn() 方法即可:

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')

你也可以传入操作数组到 disabledOn() 方法中,如果当前操作存在于该操作数组中,字段将会被禁用:

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

disabledOn() 方法将会覆盖此前对 disabled() 方法的调用,反之亦然。

隐藏字段

你也可以隐藏字段:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->hidden()

或者,你也可以传入布尔值以控制字段是否该被隐藏:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->hidden(! FeatureFlag::active())
除了允许静态值之外,hidden() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.

此外,你也可以使用 visible() 方法控制字段是否隐藏。在某些情况下,该方法可以让你的代码更具可读性:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->visible(FeatureFlag::active())
除了允许静态值之外,visible() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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

如果 hidden()visible() 同时使用,它们都需要同时指示该字段应该是可见的才能显示。

使用 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(),则需要它们都说明该字段是否可见才能显示。

基于当前操作隐藏字段

Schema 的“操作(Operaton)”是当前执行的操作。通常,如果你使用的是面板资源,则可以是 createedit 或者 view

你可以通过将操作传递给 hiddenOn() 方法来基于当前操作隐藏字段:

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')

你可以将一个操作数组传递个 hiddenOn() 方法,如果当前操作是数组中的其中一项,该字段将会被隐藏:

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

hiddenOn() 方法将会重写任何之前的 hidden() 调用,反之亦然。

此外,你也可以使用 visibleOn() 控制是否隐藏字段。在某些情况下,该方法会让你的代码更具可读性:

use Filament\Forms\Components\Toggle;

Toggle::make('is_admin')
    ->visibleOn('create')

Toggle::make('is_admin')
    ->visibleOn(['create', 'edit'])

NOTE

visibleOn() 方法将会重写任何之前的 visible() 调用,反之亦然。

行内标签

字段可以设置为让标签与之同行显示,而不是让标签在其上方。这对于有许多标签的表单非常有用,因为其纵向空间非常宝贵。要让字段标签在行内展示,请使用 inlineLabel() 方法:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->inlineLabel()
Form field with inline label

此外,你也可以传入一个布尔值,控制其标签是否行内显示:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->inlineLabel(FeatureFlag::active())
除了允许静态值之外,inlineLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.

一次性在多处使用行内标签

如果你希望在 布局组件(例如 sectiontab)中以内联方式显示所有标签,则可以在组件本身上使用 inlineLabel(),其中所有字段的标签都将以内联方式显示:

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'),
    ])
Form fields with inline labels in a section

你也可以在全体 Schema 上使用 inlineLabel() 来内联显示所有标签:

use Filament\Schemas\Schema;

public function form(Schema $schema): Schema
{
    return $schema
        ->inlineLabel()
        ->components([
            // ...
        ]);
}

在布局组件或 Schema 上使用 inlineLabel() 时,你仍然可以通过在字段上使用 inlineLabel(false) 方法选择退出单个字段的内联标签:

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),
    ])

Schema 加载时自动聚焦字段

大部分字段是可以自动聚焦的。通常,为了最佳用户体验,你应该自动聚焦到表单中第一个重要字段。使用 autofocus() 方法可以指定自动聚焦的字段:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->autofocus()

或者,你也可以传入布尔值以控制字段是否自动聚焦:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->autofocus(FeatureFlag::active())
除了允许静态值之外,autofocus() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.

设置字段占位符

许多字段会在没有值的时候显示占位符。占位符会在 UI 中展示,不过如果字段提交时为空值,并不会将其保存。你可以使用 placeholder() 方法自定义占位符:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->placeholder('John Doe')
除了允许静态值之外,placeholder() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with placeholder

将字段融合到一个分组

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([
            // ...
        ]),
])
Fused group of form fields

你可以使用 label() 方法为以上字段分组添加标签:

use Filament\Schemas\Components\FusedGroup;

FusedGroup::make([
    // ...
])
    ->label('Location')
Fused group of form fields with label

默认情况下,每个字段都独自一行。在移动设备上,这通常是最佳体验,但在桌面端,你可以使用 columns() 方法水平显示字段,它与布局组件相同:

use Filament\Schemas\Components\FusedGroup;

FusedGroup::make([
    // ...
])
    ->label('Location')
    ->columns(2)
Fused group of form fields in columns

你可以传入 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)
Fused group of form fields in columns with customized span

添加额外内容到字段中

字段包含许多“插槽”,可以在子 Schema 中插入内容。插槽可以接受文本、Schema 组件Action以及 Action 群组。通常,会使用 prime 组件作为内容:

以下插槽可用于所有字段:

  • aboveLabel()
  • beforeLabel()
  • afterLabel()
  • belowLabel()
  • aboveContent()
  • beforeContent()
  • afterContent()
  • belowContent()
  • aboveErrorMessage()
  • belowErrorMessage()
除了允许静态值之外,插槽方法也可以使用函数来动态计算它们的值。你可以将多个 utility 作为参数注入到这些函数中。 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')
    ->belowContent('This is the user\'s full name.')
Form field with text below content

要插入 Schema 组件,通常为 Prime 组件,你可以将组件传递给这些方法:

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))
Form field with component below content

要插入 Action 或者 Action 群组,你可以将它们传递给这些方法:

use Filament\Actions\Action;
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->belowContent(Action::make('generate'))
Form field with action below content

你也可以将内容数组传递给这些方法,将内容组合插入这些插槽中:

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'),
    ])
Form field with multiple components below content

通过传递数组内容给 Schema::start() (默认)、Schema::end() 或者 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

所上例的 Schema::between() 所示,它使用了 Flex 组件来将图标和文本分组到一起,使得这两个组件之间没有多余空间。图标使用了 grow(false) 以防止它占用一半的水平空间,而让文本占用剩余的空间。

Form field with aligned components below content

在字段标签上方添加额外内容

使用 aboveLabel() 方法你可以在字段标签的上方插入额外内容。你可以传递任何内容到该方法中,比如文本、Schema 组件、Action 或者 Action 分组:

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'
    ])
除了允许静态值之外,aboveLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content above label

在字段标签之前添加额外内容

使用 beforeLabel() 方法你可以在字段标签之前插入额外内容。你可以传递任何内容到该方法中,比如文本、Schema 组件、Action 或者 Action 分组:

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;

TextInput::make('name')
    ->beforeLabel(Icon::make(Heroicon::Star))
除了允许静态值之外,beforeLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content before label

在字段标签之后添加额外内容

使用 afterLabel() 方法你可以在字段标签之后插入额外内容。你可以传递任何内容到该方法中,比如文本、Schema 组件、Action 或者 Action 分组:

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'
    ])
除了允许静态值之外,afterLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content after label

默认情况下,afterContent() Schema 中的内容对齐到容器的尾部。如果你想对齐到容器的起始位置,请传入 Schema::start() 使之包含内容:

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'
    ]))
除了允许静态值之外,afterLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content after label aligned to the start

在字段标签下方添加额外内容

使用 belowLabel() 方法你可以在字段标签下方插入额外内容。你可以传递任何内容到该方法中,比如文本、Schema 组件、Action 或者 Action 分组:

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'
    ])
除了允许静态值之外,belowLabel() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content below label

NOTE

这看起来和 aboveContent() 方法相似。但是,使用行内标签时,aboveContent() 方法会将该内容放在字段上方,而不是标签下方,因为其标签显示在与字段内容不同的列中。

在字段内容上方添加额外内容

你可以使用 aboveContent() 方法在字段内容上方插入额外内容。你可以传递任何内容 到此方法,例如文本、Schema 组件、操作或操作分组:

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'
    ])
除了允许静态值之外,aboveContent() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content above content

NOTE

这看起来和 belowLabel() 方法相似。但是,使用行内标签时,belowLabel() 方法会将该内容放在标签下方,而不是放在字段内容上方,因为其标签显示在与字段内容不同的列中。

在字段内容之前添加额外内容

你可以使用 beforeContent() 方法在字段内容之前插入额外内容。你可以传递任何内容 到此方法,例如文本、Schema 组件、操作或操作分组:

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;

TextInput::make('name')
    ->beforeContent(Icon::make(Heroicon::Star))
除了允许静态值之外,beforeContent() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content before content

TIP

有些字段,比如,文本输入框Select日期时间选择器字段,有一个 prefix() 方法用于在字段内容之前、字段旁边插入内容。这通常是比使用 beforeContent() 更好的 UI 选择。

Text input with affixes

在字段内容之后添加额外内容

使用 afterContent() 方法,你可以在字段内容后插入额外内容。你可以将任何内容传递 到此方法,例如文本、架构组件、操作或操作组。

use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Icon;
use Filament\Support\Icons\Heroicon;

TextInput::make('name')
    ->afterContent(Icon::make(Heroicon::Star))
除了允许静态值之外,afterContent() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content after content

TIP

有些字段,比如,文本输入框Select日期时间选择器字段,有一个 prefix() 方法用于在字段内容之前、字段旁边插入内容。这通常是比使用 afterContent() 更好的 UI 选择。

Text input with affixes

在字段错误消息上方添加额外内容

使用 aboveErrorMessage() 方法,你可以在字段的错误消息上方插入额外内容。除非显示的是错误消息,否则这些内容不可见。你可以将任何内容传递 给此方法,例如文本、Schema 组件、Action 或 Action 分组:

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'
    ])
除了允许静态值之外,aboveErrorMessage() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content above error message

在字段错误消息下方添加额外内容

你可以使用 belowErrorMessage() 方法在字段的错误消息下方插入额外内容。除非显示错误消息,否则这些内容不可见。你可以将任何内容传递 给此方法,例如文本、Schema 组件、操作或操作分组:

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'
    ])
除了允许静态值之外,belowErrorMessage() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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.
Form field with extra content below error message

添加额外 HTML 属性到字段中

你可以通过 extraAttributes() 方法向字段传递额外的 HTML 属性,这些属性将被合并到其外层 HTML 元素中。这些属性应该用一个数组表示,其中键是属性名称,值是属性值:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->extraAttributes(['title' => 'Text input'])
除了允许静态值之外,extraAttributes() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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

默认情况下,多次调用 extraAttributes() 将覆盖之前的属性。如果你希望合并属性,可以向该方法传递 merge: true

添加额外 HTML 属性到字段输入元素中

有些字段使用底层的 <input><select> DOM 元素,但这通常不是字段的外层元素,因此 extraAttributes() 方法可能无法正常工作。在这种情况下,你可以使用 extraInputAttributes() 方法,它会将属性合并到字段 HTML 中的 <input><select> 元素上:

use Filament\Forms\Components\TextInput;

TextInput::make('categories')
    ->extraInputAttributes(['width' => 200])
除了允许静态值之外,extraInputAttributes() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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

默认情况下,多次调用 extraInputAttributes() 将覆盖之前的属性。如果你希望合并属性,可以向该方法传递 merge: true

向字段包装器添加额外的 HTML 属性

你还可以将额外的 HTML 属性传递给“字段包装器”的最外层元素,该元素包围着字段的标签和内容。如果你想通过 CSS 设置字段的标签或间距样​​式,这非常有用,因为你可以将元素作为包装器的子元素:

use Filament\Forms\Components\TextInput;

TextInput::make('categories')
    ->extraFieldWrapperAttributes(['class' => 'components-locked'])
除了允许静态值之外,extraFieldWrapperAttributes() 方法也接受一个函数来动态计算其值。你可以将多个 utility 作为参数注入到该函数中。 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

默认情况下,多次调用 extraFieldWrapperAttributes() 将覆盖之前的属性。如果你希望合并属性,可以向该方法传递 merge: true

字段 utility 注入

用于配置字段的绝大多数方法都接受函数作为参数,而不是硬编码值:

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())

仅凭这一点就解锁了许多自定义可能性。

该包还可以注入许多 utility,以作为这些函数内部的参数使用。所有接受函数作为参数的自定义方法都可以注入 utility。

这些注入的 utility 需要使用特定的参数名称。否则,Filament 将无从知晓要注入的是什么。

注入字段的当前状态

如果你想访问字段的当前值(状态),请定义 $state 参数:

function ($state) {
    // ...
}

注入字段的原始状态

如果字段值被强制转换成更常用的格式,而你希望访问原始值,请定义 $rawState 参数:

function ($rawState) {
    // ...
}

注入另一个字段的状态

你也可以使用 $get 参数从回调中检索另一个字段的状态(值):

use Filament\Schemas\Components\Utilities\Get;

function (Get $get) {
    $email = $get('email'); // Store the value of the `email` field in the `$email` variable.
    //...
}

TIP

除非表单字段是响应式的,当字段值改变时,Schema 不会刷新,而只会在用户下一次交互发起请求到服务器时才会刷新。如果你需要字段值响应式变更,请使用 live()

注入当前 Eloquent 记录

你可以使用 $record 参数,检索当前 Schma 的 Eloquent 记录:

use Illuminate\Database\Eloquent\Model;

function (?Model $record) {
    // ...
}

注入当前操作

如果你正在为面板资源或关联管理器编写 Schema ,并且希望检查 Schema 是否为 createedit 或者 view,请使用 $operation 参数:

function (string $operation) {
    // ...
}

NOTE

使用 $schema->operation() 方法,手动设置 Schema 的操作。

注入当前 Livewire 组件实例

如果你想访问当前 Livewire 组件实例,请使用 $livewire 参数:

use Livewire\Component;

function (Component $livewire) {
    // ...
}

注入当前字段实例

如果你想访问当前组件实例,请使用 $component 参数:

use Filament\Forms\Components\Field;

function (Field $component) {
    // ...
}

注入多个 utility

参数使用反射动态注入,因此你可以以任何顺序联合使用多个参数:

use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Livewire\Component as Livewire;

function (Livewire $livewire, Get $get, Set $set) {
    // ...
}

注入来自 Laravel 容器的依赖项

你可以像平常一样注入来自 Laravel 的容器的任何东西,以及 utility:

use Filament\Schemas\Components\Utilities\Set;
use Illuminate\Http\Request;

function (Request $request, Set $set) {
    // ...
}

使用 JavaScript 确定文本内容

允许渲染 HTML 的方法,例如 label()传递给 belowContent() 方法的 Text::make(),可以使用 JavaScript 来计算其内容。这可以通过将 JsContent 对象传递给 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
    ))

$state$get utility 在此 JavaScript 上下文中可用,因此你可以使用它们来访问该字段的状态以及 Schema 中的其他字段。

响应式基础

Livewire 是一款工具,允许 Blade 渲染的 HTML 动态重新渲染,而无需重新加载整个页面。Filament 的b Scgena 构建于 Livewire 之上,因此它们能够动态重新渲染,使其内容在初始渲染后能够进行调整。

默认情况下,当用户使用某个字段时,Schema 不会重新渲染。由于渲染需要往返服务器,因此这是一种性能优化。但是,如果你希望在用户与某个字段交互后重新渲染 Schema,可以使用 live() 方法:

use Filament\Forms\Components\Select;

Select::make('status')
    ->options([
        'draft' => 'Draft',
        'reviewing' => 'Reviewing',
        'published' => 'Published',
    ])
    ->live()

此例中,当用户更改 status 字段的值时,Schema 将重新渲染。这允许你根据 status 字段的新值更改架构中的字段。此外,你还可以勾入到字段的生命周期,以便在字段更新时执行自定义逻辑。

响应式字段失焦

默认情况下,当字段设置为 live() 时,Schema 会在每次与该字段交互时重新渲染。但是,这可能不适用于某些字段(例如文本输入),因为在用户输入时发出网络请求会导致性能不佳。你可能希望仅在用户完成该字段后(即字段失去焦点时)重新渲染 Schema。你可以使用 live(onBlur: true) 方法来实现:

use Filament\Forms\Components\TextInput;

TextInput::make('username')
    ->live(onBlur: true)

响应式字段防抖

你可能希望在 live()live(onBlur: true) 之间找到一个折中方案,比如防抖(debouncing)。防抖(Debounce)会阻止网络请求发送,直到用户完成输入后一段时间后再发送请求。你可以使用 live(debounce: 500) 方法来实现这一点:

use Filament\Forms\Components\TextInput;

TextInput::make('username')
    ->live(debounce: 500) // Wait 500ms before re-rendering the schema.

本例中,500 是发送请求之前需要等待的毫秒数。你可以根据需要自定义该数字,或者使用字符串如 '1s'

字段生命周期

Schema 中的每个字段都有一个生命周期,即 Schema 加载、用户交互以及提交时所经历的过程。你可以使用在生命周期的每个阶段运行的函数来自定义该生命周期内发生的事情。

字段注水

注水(Hydration)是指用数据填充字段的过程。当你调用 Schema 的 fill() 方法时,它会运行。你可以使用 afterStateHydrated() 方法自定义字段填充后的操作。

在此示例中,name 字段将始终使用正确大写的名称进行填充:

use Closure;
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->required()
    ->afterStateHydrated(function (TextInput $component, string $state) {
        $component->state(ucwords($state));
    })

作为在注水时格式化字段状态的快捷方式,你可以使用 formatStateUsing() 方法:

use Closure;
use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->formatStateUsing(fn (string $state): string => ucwords($state))

字段更新

你可以使用 afterStateUpdated() 方法自定义用户更新字段后的事情:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->afterStateUpdated(function (?string $state, ?string $old) {
        // ...
    })
afterStateUpdated() 方法可以注入多个 utility 到函数中作为参数。 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

在响应式字段上使用 afterStateUpdated() 时,由于会发起网络请求,交互上可能感觉非即时的。有几个方法可以优化及避免渲染,让交互感觉更快。

设置另一个字段的状态

$get 类似,你也可以使用 $set 参数在 afterStateUpdated() 中设置另一个字段的值:

use Filament\Schemas\Components\Utilities\Set;

function (Set $set) {
    $set('title', 'Blog Post'); // Set the `title` field to `Blog Post`.
    //...
}

运行此函数时,title 字段的状态将被更新,并且 Schema 将使用新标题重新渲染。

默认情况下,使用 $set() 时不会调用你设置的字段的 afterStateUpdated() 方法。如果你希望调用它,可以传递 shouldCallUpdatedHooks: true 作为参数:

use Filament\Schemas\Components\Utilities\Set;

function (Set $set) {
    $set('title', 'Blog Post', shouldCallUpdatedHooks: true);
    //...
}

字段脱水

脱水(Dehydration)是从 Schema 中的字段获取数据、进行可选转换并返回数据的过程。当你调用 Schema 的 getState() 方法时,它会运行,该方法通常在表单提交时调用。

你可以使用 dehydrateStateUsing() 函数自定义脱水时状态的转换方式。在此示例中,name 字段将始终使用正确的大写名称进行脱水:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->required()
    ->dehydrateStateUsing(fn (string $state): string => ucwords($state))

防止字段脱水

你也可以使用 dehydrated(false) 完全阻止字段脱水。在此示例中,该字段将不会出现在 getState() 返回的数组中:

use Filament\Forms\Components\TextInput;

TextInput::make('password_confirmation')
    ->password()
    ->dehydrated(false)

如果 Schema 自动保存到数据库,比如在资源中, 这对于防止将纯粹用于展示目的的字段保存到数据库很有用。

NOTE

即使字段未脱水,它仍然会被验证。要了解有关此行为的更多信息,请参阅验证部分。

字段渲染

每次更新响应式字段时,都会重新生成该 Schema 所属的整个 Livewire 组件的 HTML,并通过网络请求发送到前端。在某些情况下,这可能有些过度,尤其是在 Schema 很大且只有某些组件发生变化的情况下。

字段部分渲染

本例中,“name” 输入框的值用作 “email” 输入框的标签。“name” 输入框是 live(),因此当用户输入到 “name” 输入框时,整个 Schema 都会重新渲染。这并不理想,因为只有 “email” 输入框需要重新渲染:

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')

在这种情况下,只需简单调用 partiallyRenderComponentsAfterStateUpdated(),传递要重新渲染的其他字段的名称,即可使 Schema 在 状态更新后 仅重新渲染指定的字段:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->live()
    ->partiallyRenderComponentsAfterStateUpdated(['email'])

或者,你也可以使用 partiallyRenderAfterStateUpdated() 指示 Filament 仅重新渲染当前组件。如果此响应式组件是唯一依赖于其当前状态的组件,则此方法非常有用:

use Filament\Forms\Components\TextInput;

TextInput::make('name')
    ->live()
    ->partiallyRenderAfterStateUpdated()
    ->belowContent(fn (Get $get): ?string => filled($get('name')) ? "Hi, {$get('name')}!" : null)

防止 Livewire 组件在字段更新后渲染

如果你希望在字段更新时阻止 Livewire 组件重新渲染,可以使用 skipRenderAfterStateUpdated() 方法。如果你希望在字段更新时执行某些操作,但不希望 Livewire 组件重新渲染,则此方法非常有用:

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.
    })

由于使用 $set() 方法从 afterStateUpdated() 函数设置另一个字段的状态实际上只会改变字段的前端状态,因此你甚至不需要网络请求。afterStateUpdatedJs() 方法接受一个 JavaScript 表达式,该表达式会在字段值每次更改时运行。$state$get()$set() utility 在 JavaScript 上下文中可用,因此你可以使用它们来设置其他字段的状态:

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')

响应式表单手册

本节包含构建高级表单时可能需要执行的常见任务的集合。

条件性地隐藏字段

要条件性地隐藏或者显示字段,你可以传入一个函数到 hidden() 方法中,并根据你需要该字段显示或隐藏返回 true 或者 false。该函数可以注入 utility作为参数,你可以检测另一个字段的值来确定是否隐藏:

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'))

本例中,is_company 复选框是 live() 的。这允许 Schema 在 is_company 字段的值发生变化时重新渲染。你可以使用 $get() utilityhidden() 函数中访问该字段的值。该字段的值使用 ! 反转,因此当 is_company 字段为 false 时,company_name 字段将被隐藏。

或者,你可以使用 visible() 方法有条件地显示字段。它的作用与 hidden() 完全相反,如果你希望代码清晰易懂,可以使用以下方法:

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

使用 live() 意味着 Schema 将在字段每次更新或触发网络请求时重载。 此外,你也可以使用 JavaScript 基于另一个字段的值隐藏该字段

条件性地使字段必填

要有条件地将某个字段设为必填字段,可以将一个函数传递给 required() 方法,并根据是否希望该字段为必填字段返回 truefalse。该函数可以注入 utility 作为参数,因此你可以执行诸如检查其他字段的值之类的操作:

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')))

本例中,company_name 字段为 live(onBlur: true)。这允许当 company_name 字段的值发生更改且用户点击离开时,Schema 重新渲染。使用$get() utility,你可以在 required() 函数内访问该字段的值。该字段的值适用 filled() 检查,以便当 company_name 字段不是 null 或者空字符串时,vat_number 字段为必需的。其结果是,vat_number 字段只有在 company_name 字段只有在 company_name 字段非空时是必填的。

使用函数可以让其他验证规则以类似的方式动态化。

根据标题生成 Slug

要在用户输入时根据标题生成 slug,你可以使用标题字段上的 afterStateUpdated() 方法 来通过 $set()设置 slug 字段的值:

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')

本例中,title 字段为 live(onBlur: true)。这允许当 title 字段的值发生更改且用户点击离开时,Schema 重新渲染。afterStateUpdated() 方法用于在 title 字段的状态更新后运行一个函数。该函数注入 $set() 实用程序title 字段的新状态。Str::slug() 方法是 Laravel 的函数,用于从字符串生成 slug。然后使用 $set() 函数更新 slug 字段。

需要注意的是,用户可能会手动自定义 slug,我们不希望在标题更改时覆盖他们的更改。为了防止这种情况,我们可以使用旧版本的标题来判断用户是否自行修改了它。要访问标题的旧版本,可以注入 $old,要在更改之前获取 slug 的当前值,我们可以使用 $get() 实用程序

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')

依赖式 Select 选项

要根据另一个字段的值动态更新 Select 字段的选项,你可以传递一个函数到 Select 字段的 options() 方法。该函数可以注入 utility作为参数,因此你可以使用 $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 => [],
    })

本例中,category 字段为 live()。这允许 Schema 在 category 字段的值更改时重新渲染。使用$get() utility,你可以在 options() 函数内访问该字段的值。该字段的值用于确定 sub_category 字段可以使用哪些选项。PHP 的 match() 用于基于 category 字段值返回选项数组。结果是,sub_category 字段只会显示 category 字段选中值相关的选项。

通过在函数中查询,你可以将该示例适用到从 Eloquent 模型或者其他数据源加载的选项:

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'))

基于 Select 选项的动态字段

你可能希望根据字段(如 Select)值渲染不同的字段集。为此,你可以将一个函数传递给任何布局组件schema() 方法,该方法会检查字段值并根据该值返回不同的 Schema。此外,你还需要一种方法来在首次加载时动态 Schema 中初始化新字段。

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')

本例中,type 字段为 live()。这允许 Schema 在 type 字段的值更改时重新渲染。afterStateUpdated() 方法用于在 type 字段的状态更新后运行一个函数。在本例中,我们注入当前的 select 字段实例,然后我们可以使用它来获取包含 Select 和 Grid 组件的 Schema “容器”实例。使用此容器,我们可以使用分配给它的唯一键 (dynamicTypeFields) 来定位 Grid 组件。使用该 Grid 组件实例,我们可以调用 fill(),就像在普通表单上初始化它一样。然后,使用 Grid 组件的 schema() 方法根据 type 字段的值返回不同的 Schema。这是通过使用 $get() utility并动态返回不同的 Schema 数组来完成的。

自动哈希密码字段

假设你有一个密码字段:

use Filament\Forms\Components\TextInput;

TextInput::make('password')
    ->password()

你可以使用 dehydration 函数以在表单提交时哈希密码:

use Filament\Forms\Components\TextInput;
use Illuminate\Support\Facades\Hash;

TextInput::make('password')
    ->password()
    ->dehydrateStateUsing(fn (string $state): string => Hash::make($state))

不过,如果你的 Schema 用于修改已有的密码,当该字段为空时,你并不希望已有密码。你可以在字段为空时使用 filled() 辅助函数阻止该字段被脱水

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))

不过,如果你希望当用户创建时密码为必需项,请注入 $operation utility,然后条件性地使该字段为必需项。 :

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

上例中,Hash::make($state) 显示了如何使用 dehydration 函数。不过,如果你的模型中在其 casts 函数中使用了 'password' => 'hashed',那么你无需进行此处理,Laravel 将会自动进行哈希处理。

保存数据到关联

除了能够为字段赋予结构外,布局组件还能够将嵌套的字段“传送”到关联中。Filament 将处理加载来自 HasOneBelongsToMorphOne Eloquent 关联的数据,然后将数据保存回相同的关联中。要设置此行为,你可以在任何布局组件上使用 relationship() 方法:

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'),
    ])

本例中,titledescriptionimage 自动加载来自 metadata 关联的数据,并在表单提交后再次保存。如果 metadata 记录不存在,它将自动创建新记录。

该功能不仅限于 Fieldset,其他布局组件同样适用。比如,你可以使用没有相关样式的 Group 组件:

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(),
    ])

将数据保存到 BelongsToMorphTo 关联

请注意,如果你将数据保存到 BelongsTo 或者 MorphTo 关联中,那么数据库中的外键字段必须为 nullable()。这是因为 Filament 在保存关联之前会首先保存其 Schema。由于 Schema 先保存,外键 ID 还不存在,因此它必须是可以为空。当保存完 Schema 后,Filament 会立即保存其关联,然后填充外键 ID 并重新保存。

值得注意的是,如果你的 Schema 模型上有观察者,那么你可能需要对其进行调整,以确保它不依赖于创建时存在的关联。例如,如果你有一个观察者在创建 Schema 时向关联记录发送电子邮件,你可能需要切换到使用在关联附加后运行的不同钩子,比如 updated()

MorphTo 关联指定关联模型

如果你使用 MorphTo 关联,并且希望 Filament 可以创建 MorphTo 记录而不只是更新记录,你需要使用 relationship() 方法的 relatedModel 参数指定关联模型:

use App\Models\Organization;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Group;

Group::make()
    ->relationship('customer', relatedModel: Organization::class)
    ->schema([
        // ...
    ])

本例中,customerMorphTo 关联,可以是 Individual 或者 Organization。通过指定 relatedModel 参数,Filament 可以在表单提交后创建 Organization 记录。如果未指定该参数,Filament 只可以更新已有记录。

relatedModel 参数也接受一个返回关联模型类名的函数。如果你想基于表单的当前状态动态确定关联模型,这很有用。你可以将各种 utility 注入到该函数中。 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.

条件性将数据保存到关联中

有时候,保存关联记录是可选的。如果用户填写了相关客户字段,那么将会创建或者更新客户。否则,不会创建客户,或者如果客户已存在将会将其删除。为此,你可以传递 condition 作为 relationship() 的参数,该参数可以使用关联表单的 $state 来确定是否该保存该关联:

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 GitHub

Still need help? Join our Discord community or open a GitHub discussion