Table Dynamic Actions Icons based on Status

2024-10-21

Not every action on a Filament table should be visible at all times. Some should only appear when a specific condition is met. For example - on specific statuses:

Or we can remove the buttons and have just the icons:


To change the visibility of the button, we can use ->visible() on our actions:

Tables\Actions\Action::make('Mark as Paid')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::SENT, InvoiceStatus::PARTIALLY_PAID]))
->icon('heroicon-m-banknotes')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::PAID;
$record->save();
}),

This sets a condition when the button should be visible. In our case, we want to have multiple buttons visible based on the current status of our Invoice:

->actions([
Tables\Actions\Action::make('Mark as Paid')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::SENT, InvoiceStatus::PARTIALLY_PAID]))
->icon('heroicon-m-banknotes')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::PAID;
$record->save();
}),
Tables\Actions\Action::make('Mark as Sent')
->hiddenLabel()
->button()
->visible(fn($record) => $record->invoice_status === InvoiceStatus::OPEN)
->icon('heroicon-o-envelope')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::SENT;
$record->save();
}),
Tables\Actions\Action::make('Refund')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::PAID, InvoiceStatus::PARTIALLY_PAID]))
->icon('heroicon-o-arrow-uturn-left')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::REFUNDED;
$record->save();
}),
Tables\Actions\Action::make('Mark as Cancelled')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::OPEN, InvoiceStatus::SENT]))
->icon('heroicon-o-arrow-uturn-left')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::REFUNDED;
$record->save();
}),
Tables\Actions\Action::make('Mark as Re-sent')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::CANCELLED, InvoiceStatus::REJECTED]))
->icon('heroicon-m-arrow-right-end-on-rectangle')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::SENT;
$record->save();
}),
])

And if we want to only have icons without the button - we can skip the ->button(). That way, we will only have icons in our table.


Hiding Action Buttons

Of course, we can also hide the button based on a condition. To do that, we just change a method and the condition itself:

Tables\Actions\Action::make('Mark as Paid')
->hiddenLabel()
->button()
->visible(fn($record) => in_array($record->invoice_status, [InvoiceStatus::SENT, InvoiceStatus::PARTIALLY_PAID]))
->hidden(fn($record) => !in_array($record->invoice_status, [InvoiceStatus::SENT, InvoiceStatus::PARTIALLY_PAID]))
->icon('heroicon-m-banknotes')
->requiresConfirmation()
->action(function (Invoice $record) {
$record->invoice_status = InvoiceStatus::PAID;
$record->save();
}),

A few of our Premium Examples: