Custom Table Actions in FilamentPHP: A Step-by-Step Guide

Published on April 30, 2024. Last updated on January 22, 2025.
Custom Table Actions in FilamentPHP: A Step-by-Step Guide

Adding custom actions to tables can be a time-saving feature. In this example, we'll add a custom action to ban users, updating the banned_at and ban_reason fields on users table.

Step 1: Add a basic action skeleton to your table's actions array.

Tables\Actions\Action::make('ban_user')

This will result in the following:

Step 2: Change the color to red and add an icon

use Filament\Support\Colors\Color;

Tables\Actions\Action::make('ban_user')
    ->icon('heroicon-o-no-symbol')
    ->color(Color::Red)

 

Resulting in the following appearance:

Step 3: Make it confirmable and add a 'ban reason' field.

If you don't need a form element, you can remove the form() method.

Tables\Actions\Action::make('ban_user')
    ->icon('heroicon-o-no-symbol')
    ->color(Color::Red)
    ->requiresConfirmation()
    ->modalSubmitActionLabel(__('Ban'))
    ->form([
        Forms\Components\Textarea::make('ban_reason')
            ->nullable()
    ])

 

Now, clicking the 'ban' button will display a confirmation box with a textarea.

Step 4: Add the action to update the user

We will update the user and display a success notification.

use App\Models\User;
use Filament\Notifications\Notification;
use Filament\Support\Colors\Color;

Tables\Actions\Action::make('ban_user')
    ->icon('heroicon-o-no-symbol')
    ->color(Color::Red)
    ->requiresConfirmation()
    ->modalSubmitActionLabel(__('Ban'))
    ->form([
        Forms\Components\Textarea::make('ban_reason')
            ->nullable()
    ])
    ->action(function(User $record, array $data = []){
        $record->update([
            'ban_reason' => $data['ban_reason'] ?? null,
            'banned_at' => now(),
        ]);
        
        // show a success notification
        Notification::make('user_banned')
            ->title(__('User has been banned successfully'))
            ->success()
            ->send();
    })

Step 5 (Extra): Hide the 'Ban' button

To hide the 'Ban' button if the user is already banned, we will use the visible() method.

->visible(fn(User $record) => (bool) ! $record->banned_at)

 

We can extract all of this into an action class to make it reusable. An article detailing this process will be written later.