Bulk Actions
Bulk actions let users select one or more rows and apply an action to all of them. Actions are processed server-side via a signed POST route.
Basic Usage
$table->bulkAction(
label: 'Delete',
each: fn($user) => $user->delete(),
);
Signature
bulkAction(
string $label,
?callable $each = null,
?callable $before = null,
?callable $after = null,
bool|string $confirm = '',
string $confirmText = '',
string $confirmButton = '',
string $cancelButton = '',
bool|string $requirePassword = false,
): self
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
label |
string |
- | Button label shown in the UI |
each |
callable|null |
null |
Called once per selected row; receives the model instance |
before |
callable|null |
null |
Called once before processing starts; receives the array of IDs |
after |
callable|null |
null |
Called once after all rows are processed; receives the array of IDs |
confirm |
bool|string |
'' |
Show a confirmation dialog; pass true or a custom message string |
confirmText |
string |
'' |
Body text inside the dialog |
confirmButton |
string |
'' |
Confirm button label |
cancelButton |
string |
'' |
Cancel button label |
requirePassword |
bool|string |
false |
Require the user to enter their password before executing |
Callbacks
each - per-row processing
->bulkAction('Activate', each: fn($user) => $user->update(['active' => true]))
Rows are processed in chunks of 1,000 to avoid memory issues.
before and after - hooks
->bulkAction(
label: 'Export',
before: fn($ids) => logger('Starting export for ' . count($ids) . ' users'),
each: fn($user) => $user->export(),
after: fn($ids) => logger('Export complete'),
)
Confirmation Dialog
->bulkAction(
label: 'Delete',
each: fn($user) => $user->delete(),
confirm: 'Are you sure you want to delete the selected users?',
confirmText: 'This action cannot be undone.',
confirmButton: 'Yes, delete',
cancelButton: 'Cancel',
)
Pass true to use the default translated confirmation message.
Password Confirmation
Require the user to enter their password before the action executes:
->bulkAction(
label: 'Permanently Delete',
each: fn($user) => $user->forceDelete(),
requirePassword: true,
)
Selecting Rows
In the frontend, users can:
- Select individual rows via the row checkbox
- Select all on this page via the header checkbox
- Select all results (across all pages) via the "Select all N results" prompt that appears after selecting the current page
When "all results" is selected, $ids will be ['*'] and the backend re-applies all active filters/search before
processing.
Security
Bulk actions use signed routes (Laravel's URL::signedRoute). The table class name and action index are
base64-encoded in the URL and verified on the server. Authorization is checked via AbstractTable::authorize().
Handling in AbstractTable
When using AbstractTable, override performBulkAction for custom control:
public function performBulkAction(int $key, array $ids): void
{
match ($key) {
0 => User::whereKey($ids)->update(['active' => true]),
1 => User::whereKey($ids)->delete(),
default => throw new \InvalidArgumentException("Unknown action: {$key}"),
};
}
$key is the zero-based index of the action in the order they were registered in configure().
Multiple Bulk Actions
$table
->bulkAction('Activate', each: fn($u) => $u->update(['active' => true]))
->bulkAction('Deactivate', each: fn($u) => $u->update(['active' => false]))
->bulkAction('Delete', each: fn($u) => $u->delete(), confirm: 'Delete selected?');
