Actions
模态框
概述
Action 可能会在运行前要求额外确认或者用户输入。你可以在 Action 执行之前打开模态框实现该功能。
确认模态框
使用 requiresConfirmation()
方法,你可以在 Action 运行之前请求确认。这对于破坏性操作,比如删除记录,特别有用。
use App\Models\Post; Action::make('delete') ->action(fn (Post $record) => $record->delete()) ->requiresConfirmation()
如果使用
url()
代替action()
,那确认模态框不可用。相反,你应该在action()
方法内,重定向 URL。
模态框表单
你也可以在模态框中渲染表单,在 Action 运行之前从用户那边收集额外的信息。
你可以使用表单构造器中的组件来创建自定义模态框表单。表单中的数据可以通过 action()
闭包中的 $data
数组获取:
use App\Models\Post;use App\Models\User;use Filament\Forms\Components\Select; Action::make('updateAuthor') ->form([ 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()
方法,你可以使用现有数据填充表单:
use App\Models\Post;use App\Models\User;use Filament\Forms\Components\Select;use Filament\Forms\Form; Action::make('updateAuthor') ->fillForm(fn (Post $record): array => [ 'authorId' => $record->author->id, ]) ->form([ 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(); })
使用 Wizard 作为模态框表单
你可以在模态框中创建多步骤表单向导卡(wizard)。定义 step()
字符串,并传入 Step
对象:
use Filament\Forms\Components\MarkdownEditor;use Filament\Forms\Components\TextInput;use Filament\Forms\Components\Toggle;use Filament\Forms\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), ]), ])
禁用所有表单字段
你可以使用 disabledForm()
方法,禁用模态框中的所有表单字段,确保用户不能对其进行编辑:
use App\Models\Post;use App\Models\User;use Filament\Forms\Components\Textarea;use Filament\Forms\Components\TextInput; Action::make('approvePost') ->form([ TextInput::make('title'), Textarea::make('content'), ]) ->fillForm(fn (Post $record): array => [ 'title' => $record->title, 'content' => $record->content, ]) ->disabledForm() ->action(function (Post $record): void { $record->approve(); })
自定义模态框标题、描述及按钮标签
你可以自定义模态框的标题、描述及提交按钮标签:
use App\Models\Post; 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')
在模态框中添加图标
使用 modalIcon()
方法,你可以在模态框中添加图标:
use App\Models\Post; Action::make('delete') ->action(fn (Post $record) => $record->delete()) ->requiresConfirmation() ->modalIcon('heroicon-o-trash')
默认情况下,图标继承了 Action 按钮的颜色。你可以使用 modalIconColor()
方法自定义图标颜色:
use App\Models\Post; Action::make('delete') ->action(fn (Post $record) => $record->delete()) ->requiresConfirmation() ->color('danger') ->modalIcon('heroicon-o-trash') ->modalIconColor('warning')
自定义模态框内容的对齐方式
默认情况下,模态框内容对齐到起始位置,或者如果模态框宽度是 xs
或 sm
,则对齐到中间。如果你想修改模态框内容的对齐方式,可以在 modalAlignment()
中传入 Alignment::Start
或者 Alignment::Center
:
use Filament\Support\Enums\Alignment; Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->modalAlignment(Alignment::Center)
自定义模态框内容
你可以将 Blade 视图传入 modalContent()
函数,在模态框中渲染自定义内容。
use App\Models\Post; Action::make('advance') ->action(fn (Post $record) => $record->advance()) ->modalContent(view('filament.pages.actions.advance'))
传递数据到自定义模态框内容
你可以通过返回函数,将数据传递到视图中。比如,如果设置了 Action 的 $record
,你可以将其传入到视图中:
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()
将内容添加到表单下面:
use App\Models\Post; Action::make('advance') ->action(fn (Post $record) => $record->advance()) ->modalContentFooter(view('filament.pages.actions.advance'))
添加 Action 到自定义模态框内容
你可以添加 Action 按钮到自定义模态框内容,如果你想添加按钮执行一个 Action(非主 Action),这就有用。你可以使用 registerModalActions()
方法注册 Action,并将其传入到视图中:
use App\Models\Post;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()
来渲染 Action 按钮:
<div> {{ $action->getModalAction('report') }}</div>
使用 SlideOver 替代模态框
使用 slideOver()
方法,你可以打开 slide-over
对话框,而非模态框:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->slideOver()
不再是在屏幕的中间打开,模态框内容现在会从右边滑入(slide in)并消费浏览器的全部高度。
粘性模态框 Header
当模态框内容超过模态框大小时,模态框的 Header 会滚动出屏幕。不过,SlideOver 使用了粘性 Header,使之总是可见。你可以使用 stickyModalHeader()
控制该行为:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->stickyModalHeader()
粘性模态框 Footer
默认情况下,模态框的 Footer 在内容之后进行行内渲染。不过,SlideOver 拥有一个粘性的 Footer,使之在内容滚动时总是显示。使用 stickyModalFooter()
,你可以为模态框启用该功能:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->stickyModalFooter()
修改模态框宽度
使用 modalWidth()
方法,你可以修改模态框宽度。宽度选项对应于 Tailwind 的 max-width 大小。可用选项包括 ExtraSmall
、Small
、Medium
、Large
、ExtraLarge
、TwoExtraLarge
、ThreeExtraLarge
、FourExtraLarge
、FiveExtraLarge
、SixExtraLarge
、SevenExtraLarge
、Screen
:
use Filament\Support\Enums\MaxWidth; Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->modalWidth(MaxWidth::FiveExtraLarge)
模态框打开时执行代码
使用 mountUsing()
方法,你可以在模态框打开时,在闭包中执行代码。
use Filament\Forms\Form; Action::make('create') ->mountUsing(function (Form $form) { $form->fill(); // ... })
默认情况下,Filament 使用
mountUsing()
方法去初始化表单。如果重写该方法,你需要调用$form->fill()
以确保表单正确初始化。如果你想要使用数据填充表单,你可以传入数组到fill()
方法中,而不是在 Action 中使用fillForm()
方法。
在模态框 Footer 中自定义 Action 按钮
默认情况下,模态框的 Footer 中有两个 Action。第一个是提交按钮,它将执行该 Action。第二个按钮关闭模态框并取消 Action。
修改默认模态框 Footer 的 Action 按钮
要修改 Action 实例,使之用于渲染其中一个默认 Action 按钮,你可以传递闭包到 modalSubmitAction()
和 modalCancelAction()
方法:
use Filament\Actions\StaticAction; Action::make('help') ->modalContent(view('actions.help')) ->modalCancelAction(fn (StaticAction $action) => $action->label('Close'))
自定义触发按钮的可用方法将用于在闭包中修改 $action
实例。
移除默认模态框 Footer 的 Action 按钮
要移除默认 Action,你可以在 modalSubmitAction()
或 modalCancelAction()
中传入 false
:
Action::make('help') ->modalContent(view('actions.help')) ->modalSubmitAction(false)
添加额外的模态框 Action 按钮到 Footer
使用 extraModalFooterActions()
方法,你可以传递要在默认 Action 之间渲染的额外的 Action 数组:
Action::make('create') ->form([ // ... ]) // ... ->extraModalFooterActions(fn (Action $action): array => [ $action->makeModalSubmitAction('createAnother', arguments: ['another' => true]), ])
$action->makeModalSubmitAction()
返回一个 Action 实例,该实例可以使用触发按钮可用方法进行自定义。
makeModalSubmitAction()
的第二个参数,允许你传递一个参数数组,该参数数组可在 Action 的 action()
闭包中以 $arguments
访问。这可以作为一个标志,用于说明该 Action 可以基于用户决定进行不同操作:
Action::make('create') ->form([ // ... ]) // ... ->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 } })
在额外的 Footer Action 中打开另一个模态框
你可以在 Action 中互相嵌套,这样可以从额外的 Footer Action 中打开新的模态框:
Action::make('edit') // ... ->extraModalFooterActions([ Action::make('delete') ->requiresConfirmation() ->action(function () { // ... }), ])
现在,编辑模态框的 Footer 中有一个 "Delete" 按钮,点击时会打开确认模态框。该 Action 完全独立于 edit
Action,点击时不会运行 edit
Action。
本例中, 如果 delete
Action 运行了,你可能希望取消 edit
Action。为此,你可以使用 cancelParentActions()
方法:
Action::make('delete') ->requiresConfirmation() ->action(function () { // ... }) ->cancelParentActions()
如果你使用了深层嵌套,有多个父级 Action;而不想取消所有父级,你可以将你要取消的父级 Action 名及其子 Action 传递给 cancelParentActions()
:
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
) Action 运行了,第二个(second
) Action 则会取消,不过,第三个(third
) Action 也会取消因为它是 second
的下级。第一个(first
) Action 没有取消,不过,它是第二个(second
) Action 的父级。第一个 (first
) Action 的模态框会保持打开状态,
点击离开关闭模态框
默认情况下,从模态框中点击离开(Click Away),它会自己关闭。如果你想为某个模态框禁用该行为,请使用 closeModalByClickingAway(false)
方法:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->closeModalByClickingAway(false)
如果你想改变应用中所有模态框的行为,你可以在服务提供者或中间件中调用 Modal::closedByClickingAway()
:
use Filament\Support\View\Components\Modal; Modal::closedByClickingAway(false);
通过 escape 关闭模态框
默认情况下,当你在模态上按下 escape 键时,它会关闭自己。如果你希望为特定 Action 禁用此行为,可以使用 closeModalByEscaping(false)
方法:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->closeModalByEscaping(false)
如果你想修改应用中的所有模态框的此个行为,你可以在服务提供者或中间件中调用 Modal::closedByEscaping()
:
use Filament\Support\View\Components\Modal; Modal::closedByEscaping(false);
隐藏模态框关闭按钮
默认情况下,模态框在右上脚有一个关闭按钮。如果你想隐藏该关闭按钮,你可以使用 modalCloseButton(fasle)
方法:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->modalCloseButton(false)
如果你想在应用中隐藏所有模态框的关闭按钮,你可以在服务提供者或中间件中调用 Modal::closeButton(false)
:
use Filament\Support\View\Components\Modal; Modal::closeButton(false);
防止模态框自动聚焦
默认情况下,模态框打开时会自动聚焦在第一个可聚焦元素上。如果要禁用此行为,可以使用 modalAutofocus(false)
方法:
Action::make('updateAuthor') ->form([ // ... ]) ->action(function (array $data): void { // ... }) ->modalAutofocus(false)
如果你想让应用中的所有模态框禁用自动聚焦,你可以在服务提供者或者中间件中调用 Modal::autofocus(false)
:
use Filament\Support\View\Components\Modal; Modal::autofocus(false);
优化模态框配置方法
当你在模态框配置方法(比如 modalHeading()
)中使用数据库查询或者其他大型操作时,其可以执行多次。这是因为 Filament 使用这些方法来决定是否渲染模态框,以及渲染模态框的内容。
要跳过这个确定是否渲染模态框的检查,你可以使用 modal()
方法,该方法会告诉 Filament 该模态框存在该 Action 中,且不需要再次检查:
Action::make('updateAuthor') ->modal()
条件性隐藏模态框
你可能需要条件性展示模态框。请使用 modalHidden()
:
Action::make('create') ->action(function (array $data): void { // ... }) ->modalHidden(fn (): bool => $this->role !== 'admin') ->modalContent(view('filament.pages.actions.create'))
向模态框窗口添加额外属性
使用 extraModalWindowAttributes()
,你也可以将额外的 HTML 属性传递给模态框窗口:
Action::make('updateAuthor') ->extraModalWindowAttributes(['class' => 'update-author-modal'])
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion