Introduction
Actions can open modals before executing, allowing you to collect additional information from users or require confirmation for important operations. Modals can contain forms, wizards, custom content, and action buttons.Confirmation modals
The simplest modal is a confirmation dialog that asks users to verify their intent before executing a destructive action:Confirmation modals are not available when using
url() instead of action(). If you need to redirect to a URL after confirmation, do so within the action() closure.Customizing confirmation text
You can customize the modal’s heading, description, and submit button label:Form modals
You can render a form inside a modal to collect data from users before the action executes:use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
Action::make('updateAuthor')
->schema([
Select::make('authorId')
->label('Author')
->options(User::query()->pluck('name', 'id'))
->required(),
TextInput::make('reason')
->label('Reason for change')
->required(),
])
->action(function (array $data, Post $record): void {
$record->author()->associate($data['authorId']);
$record->update(['author_change_reason' => $data['reason']]);
})
->action(function (array $data) {
// $data['authorId'] contains the selected author ID
// $data['reason'] contains the reason text
})
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();
})
Disabling form fields
Make all form fields read-only usingdisabledForm():
Wizard modals
Create multi-step workflows inside modals using wizards:Allowing step navigation
By default, users must complete each step in order. Allow free navigation withskippableSteps():
Modal appearance
Action::make('delete')
->requiresConfirmation()
->modalIcon('heroicon-o-trash')
->modalIconColor('danger')
->action(fn () => $this->post->delete())
use Filament\Support\Enums\Width;
Action::make('updateAuthor')
->schema([...])
->modalWidth(Width::FiveExtraLarge)
Custom modal content
You can render custom Blade views inside your modals:Passing data to views
Pass data to your custom views using a closure:Modal footer actions
Action::make('help')
->modalContent(view('actions.help'))
->modalSubmitActionLabel('Got it')
->modalCancelActionLabel('Close')
Action::make('help')
->modalCancelAction(fn (Action $action) => $action->label('Close')->color('gray'))
Action::make('create')
->schema([...])
->extraModalFooterActions(fn (Action $action): array => [
$action->makeModalSubmitAction('createAnother', arguments: ['another' => true]),
])
->action(function (array $data, array $arguments): void {
Category::create($data);
if ($arguments['another'] ?? false) {
// Reset form and keep modal open
}
})
Nested actions
You can open child action modals from parent actions:Use
cancelParentActions() to close parent modals when a child action completes. You can pass a specific parent action name to only cancel that action and its children.