Skip to content
全部文档

模态框

简介

操作在运行前可能需要用户额外确认或输入。你可以在执行操作前打开模态框来完成此事。

确认模态框

你可以使用 requiresConfirmation() 方法要求在运行操作前进行确认。这对删除记录等破坏性较强的操作很有用。

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('delete')
    ->action(fn (Post $record) => $record->delete())
    ->requiresConfirmation()
确认模态框确认模态框

WARNING

当设置的是 url() 而不是 action() 时,确认模态框不可用。此时应在 action() 闭包内重定向到该 URL。

INFO

确认模态框使用 alertdialog ARIA 角色而非 dialog,因此屏幕阅读器会将其播报为警报,并在打开时自动朗读模态框的描述。

控制模态框内容

自定义模态框标题、描述与提交操作标签

你可以自定义模态框中的标题、描述以及提交按钮的标签:

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('delete')
    ->action(fn (Post $record) => $record->delete())
    ->requiresConfirmation()
    ->modalHeading('Delete post')
    ->modalDescription('Are you sure you\'d like to delete this post? This cannot be undone.')
    ->modalSubmitActionLabel('Yes, delete it')
带自定义文本的确认模态框带自定义文本的确认模态框

在模态框中渲染 schema

Filament 允许你在模态框中渲染 schema,从而可以使用任意可用组件构建 UI。通常适合在 schema 中构建表单,以便在操作运行前向用户收集额外信息,但也可以渲染任意 UI:

php
use Filament\Actions\Action;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Infolists\Components\TextEntry;
use Filament\Schemas\Components\Section;

Action::make('viewUser')
    ->schema([
        Grid::make(2)
            ->schema([
                Section::make('Details')
                    ->schema([
                        TextInput::make('name'),
                        Select::make('position')
                            ->options([
                                'developer' => 'Developer',
                                'designer' => 'Designer',
                            ]),
                        Checkbox::make('is_admin'),
                    ]),
                Section::make('Auditing')
                    ->schema([
                        TextEntry::make('created_at')
                            ->dateTime(),
                        TextEntry::make('updated_at')
                            ->dateTime(),
                    ]),
            ]),
    ])

TIP

除了允许静态值外,schema() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

带 schema 布局的模态框带 schema 布局的模态框

在模态框中渲染表单

你可以使用 表单字段 创建操作模态表单。表单数据可在 action() 闭包的 $data 数组中获取:

php
use App\Models\Post;
use App\Models\User;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;

Action::make('updateAuthor')
    ->schema([
        Select::make('authorId')
            ->label('Author')
            ->options(User::query()->pluck('name', 'id'))
            ->required(),
    ])
    ->action(function (array $data, Post $record): void {
        $record->author()->associate($data['authorId']);
        $record->save();
    })
带表单的模态框带表单的模态框
用已有数据填充表单

你可以使用 fillForm() 方法用已有数据填充表单:

php
use App\Models\Post;
use App\Models\User;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;

Action::make('updateAuthor')
    ->fillForm(fn (Post $record): array => [
        'authorId' => $record->author->id,
    ])
    ->schema([
        Select::make('authorId')
            ->label('Author')
            ->options(User::query()->pluck('name', 'id'))
            ->required(),
    ])
    ->action(function (array $data, Post $record): void {
        $record->author()->associate($data['authorId']);
        $record->save();
    })

TIP

fillForm() 方法也接受一个函数来动态计算要填充到表单的数据。你可以将各种实用工具作为参数注入该函数。

禁用所有表单字段

你可能希望禁用模态框中的所有表单字段,确保用户无法编辑。可以使用 disabledForm() 方法实现:

php
use App\Models\Post;
use Filament\Actions\Action;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;

Action::make('approvePost')
    ->schema([
        TextInput::make('title'),
        Textarea::make('content'),
    ])
    ->disabledForm()
    ->action(function (Post $record): void {
        $record->approve();
    })
带禁用表单字段的模态框带禁用表单字段的模态框

在模态框中渲染向导

你可以在模态框中创建 多步表单向导。不要使用 schema(),而是定义 steps() 数组并传入你的 Step 对象:

php
use Filament\Actions\Action;
use Filament\Forms\Components\MarkdownEditor;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Wizard\Step;

Action::make('create')
    ->steps([
        Step::make('Name')
            ->description('Give the category a unique name')
            ->schema([
                TextInput::make('name')
                    ->required()
                    ->live()
                    ->afterStateUpdated(fn ($state, callable $set) => $set('slug', Str::slug($state))),
                TextInput::make('slug')
                    ->disabled()
                    ->required()
                    ->unique(Category::class, 'slug'),
            ])
            ->columns(2),
        Step::make('Description')
            ->description('Add some extra details')
            ->schema([
                MarkdownEditor::make('description'),
            ]),
        Step::make('Visibility')
            ->description('Control who can view it')
            ->schema([
                Toggle::make('is_visible')
                    ->label('Visible to customers.')
                    ->default(true),
            ]),
    ])
带向导的模态框带向导的模态框

在模态框中添加图标

你可以使用 modalIcon() 方法在模态框中添加 图标

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('delete')
    ->action(fn (Post $record) => $record->delete())
    ->requiresConfirmation()
    ->modalIcon('heroicon-o-trash')

TIP

modalIcon() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

带图标的确认模态框带图标的确认模态框

默认情况下,图标会继承操作按钮的颜色。你可以使用 modalIconColor() 方法自定义图标颜色:

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('delete')
    ->action(fn (Post $record) => $record->delete())
    ->requiresConfirmation()
    ->color('danger')
    ->modalIcon('heroicon-o-trash')
    ->modalIconColor('warning')

TIP

modalIconColor() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

带自定义图标颜色的确认模态框带自定义图标颜色的确认模态框

自定义模态框内容对齐方式

默认情况下,模态框内容会左对齐(start);若模态框 宽度xssm,则会居中。若要更改模态框内容的对齐方式,可以使用 modalAlignment() 方法并传入 Alignment::StartAlignment::Center

php
use Filament\Actions\Action;
use Filament\Support\Enums\Alignment;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->modalAlignment(Alignment::Center)

TIP

modalAlignment() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

内容居中对齐的模态框内容居中对齐的模态框

使模态框页眉固定

当内容超出模态框尺寸时,模态框页眉会随内容滚出视野。而 slide-over 则有始终可见的固定页眉。你可以使用 stickyModalHeader() 控制此行为:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->stickyModalHeader()

默认情况下,模态框页脚会内联渲染在内容之后。而 slide-over 则有在滚动内容时始终显示的固定页脚。你也可以使用 stickyModalFooter() 为模态框启用此行为:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->stickyModalFooter()
带固定页眉和页脚的模态框带固定页眉和页脚的模态框

自定义模态框内容

你可以定义要在模态框内渲染的自定义内容,方法是将 Blade 视图传给 modalContent() 方法:

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('advance')
    ->action(fn (Post $record) => $record->advance())
    ->modalContent(view('filament.pages.actions.advance'))

TIP

modalContent() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

向自定义模态框内容传递数据

你可以通过从函数返回数据来将其传给视图。例如,若操作设置了 $record,你可以将它传给视图:

php
use Filament\Actions\Action;
use Illuminate\Contracts\View\View;

Action::make('advance')
    ->action(fn (Contract $record) => $record->advance())
    ->modalContent(fn (Contract $record): View => view(
        'filament.pages.actions.advance',
        ['record' => $record],
    ))

在表单下方添加自定义模态框内容

默认情况下,若存在模态表单,自定义内容会显示在其上方;若希望显示在下方,可以使用 modalContentFooter()

php
use App\Models\Post;
use Filament\Actions\Action;

Action::make('advance')
    ->action(fn (Post $record) => $record->advance())
    ->modalContentFooter(view('filament.pages.actions.advance'))

TIP

modalContentFooter() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

向自定义模态框内容添加操作

你可以在自定义模态框内容中添加操作按钮,适合需要添加执行主操作以外行为的按钮时使用。做法是用 registerModalActions() 方法注册操作,再将其传给视图:

php
use App\Models\Post;
use Filament\Actions\Action;
use Illuminate\Contracts\View\View;

Action::make('advance')
    ->registerModalActions([
        Action::make('report')
            ->requiresConfirmation()
            ->action(fn (Post $record) => $record->report()),
    ])
    ->action(fn (Post $record) => $record->advance())
    ->modalContent(fn (Action $action): View => view(
        'filament.pages.actions.advance',
        ['action' => $action],
    ))

现在,在视图文件中,你可以通过调用 getModalAction() 来渲染操作按钮:

blade
<div>
    {{ $action->getModalAction('report') }}
</div>

使用 slide-over 代替模态框

你可以使用 slideOver() 方法打开「slide-over」对话框,而不是模态框:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->slideOver()
带表单的 slide-over带表单的 slide-over

内容不再从屏幕中央打开,而是从右侧滑入,并占满浏览器的整个高度。

更改 slide-over 位置

默认情况下,slide-over 从屏幕末端进入(从左到右语言为右侧,从右到左语言为左侧)。你可以通过向 slideOverPosition() 方法传入 SlideOverPosition::Start,改为从屏幕起始侧进入:

php
use Filament\Actions\Action;
use Filament\Support\Enums\SlideOverPosition;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->slideOver()
    ->slideOverPosition(SlideOverPosition::Start)
从屏幕起始侧滑入的 slide-over从屏幕起始侧滑入的 slide-over

这在操作触发器位于视口起始侧时很有用——例如表格行开头的行操作——这样 slide-over 会在触发器旁边打开,而不是横跨整个屏幕。

更改模态框宽度

你可以使用 modalWidth() 方法更改模态框宽度。选项对应 Tailwind 的 max-width 比例。可用选项为 ExtraSmallSmallMediumLargeExtraLargeTwoExtraLargeThreeExtraLargeFourExtraLargeFiveExtraLargeSixExtraLargeSevenExtraLargeScreen

php
use Filament\Actions\Action;
use Filament\Support\Enums\Width;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->modalWidth(Width::FiveExtraLarge)

TIP

modalWidth() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

自定义宽度的模态框自定义宽度的模态框

模态框打开时执行代码

你可以在模态框打开时,通过向 mountUsing() 方法传入闭包来执行代码:

php
use Filament\Actions\Action;
use Filament\Schemas\Schema;

Action::make('create')
    ->mountUsing(function (Schema $form) {
        $form->fill();

        // ...
    })
默认情况下,Filament 使用 `mountUsing()` 方法初始化 [表单](#rendering-a-form-in-a-modal)。若你覆盖此方法,需要调用 `$form->fill()` 以确保表单正确初始化。若希望用数据填充表单,可以向 `fill()` 方法传入数组,而不必 [在操作本身上使用 `fillForm()`](#filling-the-form-with-existing-data)。

默认情况下,模态框页脚有两个操作。第一个是提交按钮,会执行 action()。第二个按钮关闭模态框并取消操作。

若要修改用于渲染默认操作按钮之一的操作实例,可以向 modalSubmitAction()modalCancelAction() 方法传入闭包:

php
use Filament\Actions\Action;

Action::make('help')
    ->modalContent(view('actions.help'))
    ->modalCancelAction(fn (Action $action) => $action->label('Close'))

用于自定义触发按钮的方法 均可用于修改闭包内的 $action 实例。

TIP

若只需自定义模态框中的按钮标签,且不需要进一步定制,可使用 modalSubmitActionLabel()modalCancelActionLabel() 方法,而不必向 modalSubmitAction()modalCancelAction() 传入函数。

若要移除默认操作,可以向 modalSubmitAction()modalCancelAction() 传入 false

php
use Filament\Actions\Action;

Action::make('help')
    ->modalContent(view('actions.help'))
    ->modalSubmitAction(false)

你可以使用 extraModalFooterActions() 方法传入额外操作数组,它们会渲染在模态框页脚的默认操作之间:

php
use Filament\Actions\Action;

Action::make('create')
    ->schema([
        // ...
    ])
    // ...
    ->extraModalFooterActions(fn (Action $action): array => [
        $action->makeModalSubmitAction('createAnother', arguments: ['another' => true]),
    ])

TIP

extraModalFooterActions() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

带额外页脚操作按钮的模态框带额外页脚操作按钮的模态框

$action->makeModalSubmitAction() 返回一个操作实例,可用 自定义触发按钮的方法 进行定制。

makeModalSubmitAction() 的第二个参数允许你传入参数数组,可在操作的 action() 闭包中通过 $arguments 访问。它们可用作标志,以根据用户决定让操作表现不同:

php
use Filament\Actions\Action;

Action::make('create')
    ->schema([
        // ...
    ])
    // ...
    ->extraModalFooterActions(fn (Action $action): array => [
        $action->makeModalSubmitAction('createAnother', arguments: ['another' => true]),
    ])
    ->action(function (array $data, array $arguments): void {
        // Create

        if ($arguments['another'] ?? false) {
            // Reset the form and don't close the modal
        }
    })

你可以嵌套操作,从而从额外页脚操作打开新的模态框:

php
use Filament\Actions\Action;

Action::make('edit')
    // ...
    ->extraModalFooterActions([
        Action::make('delete')
            ->requiresConfirmation()
            ->action(function () {
                // ...
            }),
    ])

现在,编辑模态框页脚会有一个「Delete」按钮,点击后会打开确认模态框。该操作与 edit 操作完全独立,点击时不会运行 edit 操作。

不过在此示例中,你可能希望在运行 delete 操作时取消 edit 操作。可以使用 cancelParentActions() 方法实现:

php
use Filament\Actions\Action;

Action::make('delete')
    ->requiresConfirmation()
    ->action(function () {
        // ...
    })
    ->cancelParentActions()

若嵌套较深且有多个父操作,但你不想取消全部,可以向 cancelParentActions() 传入要取消的父操作名称(含其子操作):

php
use Filament\Actions\Action;

Action::make('first')
    ->requiresConfirmation()
    ->action(function () {
        // ...
    })
    ->extraModalFooterActions([
        Action::make('second')
            ->requiresConfirmation()
            ->action(function () {
                // ...
            })
            ->extraModalFooterActions([
                Action::make('third')
                    ->requiresConfirmation()
                    ->action(function () {
                        // ...
                    })
                    ->extraModalFooterActions([
                        Action::make('fourth')
                            ->requiresConfirmation()
                            ->action(function () {
                                // ...
                            })
                            ->cancelParentActions('second'),
                    ]),
            ]),
    ])

在此示例中,若运行 fourth 操作,则会取消 second 操作,同时也会取消作为 second 子操作的 third。但 first 操作不会被取消,因为它是 second 的父操作。first 操作的模态框将保持打开。

从子操作访问父操作信息

你可以在嵌套操作使用的函数中注入 $mountedActions 数组,以访问父操作实例及其原始数据和参数。例如,要获取页面上当前最顶层的父操作,可以使用 $mountedActions[0]。然后可通过调用 $mountedActions[0]->getRawData() 获取该操作的原始数据。请注意,由于操作尚未提交,原始数据未经验证:

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

Action::make('first')
    ->schema([
        TextInput::make('foo'),
    ])
    ->action(function () {
        // ...
    })
    ->extraModalFooterActions([
        Action::make('second')
            ->requiresConfirmation()
            ->action(function (array $mountedActions) {
                dd($mountedActions[0]->getRawData());
            
                // ...
            }),
    ])

对于父操作的当前参数,可以用类似方式通过 $mountedActions[0]->getArguments() 方法获取。

即使有多层嵌套,$mountedActions 数组也会包含当前激活的每一个操作,因此你可以访问它们的信息:

php
use Filament\Actions\Action;

Action::make('first')
    ->schema([
        TextInput::make('foo'),
    ])
    ->action(function () {
        // ...
    })
    ->extraModalFooterActions([
        Action::make('second')
            ->schema([
                TextInput::make('bar'),
            ])
            ->arguments(['number' => 2])
            ->action(function () {
                // ...
            })
            ->extraModalFooterActions([
                Action::make('third')
                    ->schema([
                        TextInput::make('baz'),
                    ])
                    ->arguments(['number' => 3])
                    ->action(function () {
                        // ...
                    })
                    ->extraModalFooterActions([
                        Action::make('fourth')
                            ->requiresConfirmation()
                            ->action(function (array $mountedActions) {
                                dd(
                                    $mountedActions[0]->getRawData(),
                                    $mountedActions[0]->getArguments(),
                                    $mountedActions[1]->getRawData(),
                                    $mountedActions[1]->getArguments(),
                                    $mountedActions[2]->getRawData(),
                                    $mountedActions[2]->getArguments(),
                                );
                                // ...
                            }),
                    ]),
            ]),
    ])

关闭模态框

通过点击外部关闭模态框

默认情况下,点击模态框外部会关闭它。若要为特定操作禁用此行为,可以使用 closeModalByClickingAway(false) 方法:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->closeModalByClickingAway(false)

TIP

closeModalByClickingAway() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

若要更改应用中所有模态框的行为,可以在服务提供者或中间件中调用 ModalComponent::closedByClickingAway()

php
use Filament\Support\View\Components\ModalComponent;

ModalComponent::closedByClickingAway(false);

通过 Escape 关闭模态框

默认情况下,在模态框上按 Escape 会关闭它。若要为特定操作禁用此行为,可以使用 closeModalByEscaping(false) 方法:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->closeModalByEscaping(false)

TIP

closeModalByEscaping() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

若要更改应用中所有模态框的行为,可以在服务提供者或中间件中调用 ModalComponent::closedByEscaping()

php
use Filament\Support\View\Components\ModalComponent;

ModalComponent::closedByEscaping(false);

禁用未保存更改提醒

当面板启用了 未保存更改提醒 时,若操作模态框仍打开,用户在离开页面前会收到警告。若某个操作的模态框不可能包含未保存更改,可以使用 unsavedChangesAlert(false) 方法为其禁用该警告:

php
use Filament\Actions\Action;
use Filament\Infolists\Components\TextEntry;

Action::make('viewAuthor')
    ->schema([
        TextEntry::make('name'),
        TextEntry::make('email'),
    ])
    ->unsavedChangesAlert(false)

TIP

unsavedChangesAlert() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

默认情况下,带有 禁用 schema 的操作(例如 ViewAction)不会触发该提醒,因为其模态框不接受用户输入。

隐藏模态框关闭按钮

默认情况下,模态框右上角有关闭按钮。若要隐藏关闭按钮,可以使用 modalCloseButton(false) 方法:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->modalCloseButton(false)

TIP

modalCloseButton() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

若要隐藏应用中所有模态框的关闭按钮,可以在服务提供者或中间件中调用 ModalComponent::closeButton(false)

php
use Filament\Support\View\Components\ModalComponent;

ModalComponent::closeButton(false);
无关闭按钮的模态框无关闭按钮的模态框

使模态框可穿透点击

默认情况下,模态框打开时会阻止与页面其余部分的交互。若希望用户仍能与模态框后方的页面交互,可以使用 modalClickThrough() 方法使其「可穿透点击」:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->modalClickThrough()

当模态框可穿透点击时,其背景遮罩会被移除,模态窗口外的点击会传递到下方页面,且页面仍可滚动。仍可通过关闭按钮或按 Escape 键关闭模态框。

INFO

可穿透点击的模态框无法通过点击外部关闭,因为这与和后方页面交互不兼容。因此启用 modalClickThrough() 会自动禁用点击外部关闭。

TIP

modalClickThrough() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

阻止模态框自动聚焦

默认情况下,模态框打开时会自动聚焦第一个可聚焦元素。若要禁用此行为,可以使用 modalAutofocus(false) 方法:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->schema([
        // ...
    ])
    ->action(function (array $data): void {
        // ...
    })
    ->modalAutofocus(false)

TIP

modalAutofocus() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

若要禁用应用中所有模态框的自动聚焦,可以在服务提供者或中间件中调用 ModalComponent::autofocus(false)

php
use Filament\Support\View\Components\ModalComponent;

ModalComponent::autofocus(false);

将子操作模态框叠放在父操作模态框之上

默认情况下,当子操作打开其模态框时,父操作的模态框会暂时关闭,并在子操作关闭后重新打开。若希望子操作的模态框叠放在父操作模态框之上(父级仍可见),可以在子操作上使用 overlayParentActions() 方法:

php
use Filament\Actions\Action;
use Filament\Schemas\Components\Repeater;

Action::make('editItems')
    ->slideOver()
    ->schema([
        Repeater::make('items')
            ->schema([
                // ...
            ])
            ->deleteAction(
                fn (Action $action) => $action
                    ->requiresConfirmation()
                    ->overlayParentActions(),
            ),
    ])
    ->action(function () {
        // ...
    })

在此示例中,当用户点击 repeater 项上的删除按钮时,确认对话框会叠在 slide-over 之上,而不是先关闭 slide-over。这能带来更流畅的体验,尤其适合 slide-over 内的操作或复杂表单——关闭并重新打开父级会让人迷失方向。

叠放在父级 slide-over 上的子确认模态框叠放在父级 slide-over 上的子确认模态框

关闭模态框时取消父操作

上文的 cancelParentActions() 方法仅在子操作运行时取消父操作。若用户改为关闭子模态框——通过按 Escape、点击背景遮罩或使用关闭按钮——默认只会关闭该模态框,父操作仍保持挂载。若要在关闭模态框时也取消父操作,让用户可以一次性放弃整个多步流程,而不是一次关一个模态框,请使用 cancelParentActionsOnClose() 方法:

php
use Filament\Actions\Action;

Action::make('createPost')
    ->schema([
        // ...
    ])
    ->extraModalFooterActions([
        Action::make('saveAsDraft')
            ->schema([
                // ...
            ])
            ->cancelParentActionsOnClose()
            ->action(function (): void {
                // ...
            }),
    ])
    ->action(function (array $data): void {
        // ...
    })

现在,关闭 saveAsDraft 模态框也会取消 createPost 操作并关闭其模态框。

cancelParentActions() 一样,你可以传入父操作名称,以取消到特定父操作(含其子操作),而不是全部取消:

php
use Filament\Actions\Action;

Action::make('editPostMetadata')
    ->schema([
        // ...
    ])
    ->cancelParentActionsOnClose('createPost')
    ->action(function (): void {
        // ...
    })

优化模态框配置方法

当你在 modalHeading() 等模态框配置方法中使用数据库查询或其他较重操作时,它们可能会被执行多次。因为 Filament 既用这些方法判断是否渲染模态框,也用它们渲染模态框内容。

若要跳过 Filament 判断是否渲染模态框的检查,可以使用 modal() 方法,告知 Filament 该操作存在模态框,无需再次检查:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->modal()

按条件隐藏模态框

你可能需要按条件显示确认模态框,否则回退到默认操作。这可以通过 modalHidden() 实现:

php
use Filament\Actions\Action;

Action::make('create')
    ->action(function (array $data): void {
        // ...
    })
    ->modalHidden($this->role !== 'admin')
    ->modalContent(view('filament.pages.actions.create'))

TIP

modalHidden() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

为模态窗口添加额外属性

你可以通过 extraModalWindowAttributes() 方法向模态窗口传入额外 HTML 属性,这些属性会合并到其外层 HTML 元素上。属性应以数组表示,键为属性名,值为属性值:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->extraModalWindowAttributes(['class' => 'update-author-modal'])

TIP

除了允许静态值外,extraModalWindowAttributes() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

TIP

默认情况下,多次调用 extraModalWindowAttributes() 会覆盖先前的属性。若希望改为合并属性,可以向该方法传入 merge: true

为模态遮罩添加额外属性

你可以通过 extraModalOverlayAttributes() 向模态遮罩传入额外 HTML 属性。属性应以数组表示,键为属性名,值为属性值:

php
use Filament\Actions\Action;

Action::make('updateAuthor')
    ->extraModalOverlayAttributes(['class' => 'update-author-overlay'])

TIP

除了允许静态值外,extraModalOverlayAttributes() 方法也接受一个函数来动态计算值。你可以将各种实用工具作为参数注入该函数。

TIP

默认情况下,多次调用 extraModalOverlayAttributes() 会覆盖先前的属性。若希望改为合并属性,可以向该方法传入 merge: true