dvarilek/filament-table-select

Laravel Filament form component for selecting related records with a table.

v2.0.2 2025-06-10 07:31 UTC

This package is auto-updated.

Last update: 2025-06-10 07:56:45 UTC


README

Latest Version on Packagist Software License Total Downloads

Filament Table Select Banner

Installation

composer require dvarilek/filament-table-select:^2.0

Overview

This package introduces a new Form component that acts as a replacement for the Select field by allowing users to select related records from a full-fledged Filament table through a relationship.

Naturally, using a table for selection provides much greater context and clarity, as users can interact with it like any other Filament table. The table can be fully customizable.

filament-table-select-demo.mp4


Getting Started

Even though TableSelect doesn't extend Select field directly, it borrows some functionality from it.

First, configure the relationship and title attribute using the relationship() method, which works the same way as in Filament's standard Select field. This method sets up a BelongsTo relationship to automatically retrieve options, where the titleAttribute specifies the column used to generate labels for each option.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
    ])

single-select.mp4


Multi Selection

The multiple() method enables to use a belongsToMany() relationship, which allows to select and associate multiple records.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
    ])

multi-select.mp4


Selected Items Validation

You can validate the minimum and maximum number of items that you can select in a multi-select by setting the minItems() and maxItems() methods:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->minItems(1)
            ->maxItems(3)
    ])

Note

If maxItems(1) is set to 1, radio-like selection gets enabled regardless of the relationship type.


Customizing Selected Options

Label Configuration

The TableSelect field enables for customization of selected options and their badges.

To customize the color of selected options, use the optionColor() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->optionColor('success')
    ])
Filament Table Option Color Configuration

To customize the icon of selected options, use the optionIcon() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->optionIcon('heroicon-o-bell')
    ])
Filament Table Select Option Icon Configuration

Even though both optionColor() and optionIcon() methods accept callbacks, they cannot work with the given record instance. This is done for performance reasons, so all selected options are not loaded into memory on each request.

To customize the colors of selected options while being able to access the Eloquent model instance, use the getOptionColorFromRecordUsing() method.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->getOptionColorFromRecordUsing(function (Client $record) {
                return match ($record->status) {
                    'lead' => 'primary',
                    'closed' => 'success',
                    'lost' => 'gray',
                    'active' => 'danger',
                    default => 'primary'
                };
            })
    ])
Filament Table Select Option Color Configuration 2

To customize the icons of selected options while being able to access the Eloquent model instance, use the getOptionIconFromRecordUsing() method.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->getOptionIconFromRecordUsing(function (Client $record) {
                return match ($record->status) {
                    'lead' => 'heroicon-o-light-bulb',     
                    'closed' => 'heroicon-o-check-circle',   
                    'lost' => 'heroicon-o-x-circle',      
                    'active' => 'heroicon-o-bolt',           
                    default  => 'heroicon-o-question-mark-circle', 
                };
            })
    ])
Filament Table Select Option Icon Configuration 2

To customize the labels of selected options while being able to access the Eloquent model instance, use the getOptionLabelFromRecordUsing() method.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->getOptionLabelFromRecordUsing(function (Client $record) {
                 return "{$record->first_name} {$record->last_name} - {$record->status}";
            })
    ])
Filament Table Select Option Label Configuration

Other Configuration Options

To customize the size of selected option badges, use the optionSize() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Support\Enums\ActionSize;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->optionSize(ActionSize::Large)
    ])

To customize the size of selected option badges, use the optionIconSize() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Support\Enums\IconSize;

$form
    ->schema([
        TableSelect::make('clients')
            ->relationship('clients', 'name')
            ->multiple()
            ->optionIconSize(IconSize::Large)
    ])

Selection Table

Selection Table Configuration

You can configure the Selection table by passing a closure into the selectionTable() method, this is where you can add columns, remove actions, modify the table's query etc.

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Tables\Table;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->selectionTable(function (Table $table) {
        return $table
            ->heading('Active Clients') 
            ->actions([]) 
            ->modifyQueryUsing(fn (Builder $query) => $query->where('status', 'active'));
    })

Additionally, If you wish to customize the Selection Table Livewire component, you can access it as the second argument:

use Dvarilek\FilamentTableSelect\Components\Livewire\SelectionTable;
use Filament\Tables\Table;

->selectionTable(function (Table $table, SelectionTable $livewire) {
    // ...
})

To use an already defined table from a Filament Resource, use the tableLocation() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->tableLocation(ClientResource::class)

Selection Action

Selection Action Configuration

The selection action and its modal, where the table is contained, can be configured using the selectionAction() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Forms\Components\Actions\Action;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->selectionAction(function (Action $action) {
        return $action
            ->icon('heroicon-o-user-plus') 
            ->modalHeading('Select Clients') 
            ->slideOver(false);
    })

Selection Action Position

By default, the selection action is displayed in the left bottom corner. To change its position, use the selectionActionAlignment() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Forms\Components\Actions\Action;
use Filament\Support\Enums\Alignment;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->selectionAction(function (Action $action) {
        return $action
            ->icon('heroicon-o-user-plus') 
            ->modalHeading('Select Clients') 
            ->slideOver(false);
    })
    ->selectionActionAlignment(Alignment::End)

Or provide an optional parameter directly in the selectionAction() method:

use Filament\Support\Enums\Alignment;

->selectionAction(alignment: Alignment::Center)

Opening Selection Modal On Click

If you with to hide this action and open the modal by clicking on the Field directly, use the triggerSelectionActionOnInputClick() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Filament\Forms\Components\Actions\Action;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->selectionAction(function (Action $action) {
        return $action
            ->icon('heroicon-o-user-plus') 
            ->modalHeading('Select Clients') 
            ->slideOver(false);
    })
    ->triggerSelectionActionOnInputClick() 

open-on-click.mp4

Or provide an optional parameter directly in the selectionAction() method:

    ->selectionAction(shouldTriggerSelectionActionOnInputClick: true)

Note

Having this feature enabled still requires the selection action itself to be visible, because it needs to get mounted.


Confirmation action

Selection Confirmation

By default, the component's state is automatically updated as records are selected. To require a confirmation of the selection, use the requiresSelectionConfirmation() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->requiresSelectionConfirmation();

This prevents automatic state updates and adds a confirmation action to the modal. Only when this action is clicked will the form component's state get updated.

selection-confirmation.mp4

Important

If you're concerned about performance, especially when updating the state would load a large number of models (e.g., when using one of the getOptionFromRecord methods), consider enabling this feature.


Closing After Selection

After confirmation, the modal closes by default. To keep it open, use the shouldCloseAfterSelection():

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->requiresSelectionConfirmation()
    ->shouldCloseAfterSelection(false);

Or provide an optional parameter directly in the requiresSelectionConfirmation() method:

->requiresSelectionConfirmation(shouldCloseAfterSelection: false)

Note

Obviously, this only takes effect when selection confirmation is enabled.


Selection Action Position

By default, the confirmation action is positioned in the bottom left corner of the modal. To change its position use the confirmationActionPosition() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Dvarilek\FilamentTableSelect\Enums\SelectionModalActionPosition;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->requiresSelectionConfirmation() 
    ->confirmationActionPosition(SelectionModalActionPosition::TOP_LEFT);

Or provide an optional parameter directly in the requiresSelectionConfirmation() method:

use Dvarilek\FilamentTableSelect\Enums\SelectionModalActionPosition;

->requiresSelectionConfirmation(confirmationActionPosition: SelectionModalActionPosition::TOP_LEFT)

Creating New Records

Create Option Action

In a standard Select field, if users can’t find the record they need, they can create and associate a new one on using the createOptionAction(). - Official Filament Documentation

The TableSelect borrows this exact functionality and displays the create option action in the selection modal. To configure this action you can use the following methods:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->createOptionForm(ClientResource::form(...))
    ->createOptionUsing(function (array $data) {
        // Create related record using...
    })
    ->createOptionAction(function () {
        // Configure the action...
    })

create-option.mp4

Important

When a new record is created, it's automatically selected in the table. If this newly created record exceeds the selection limit, the record naturally won't be selected. Obviously, in single-selection mode, the new record will replace the old one.


Create Option Action Position

By default, the create option action is positioned in the top right corner of the modal. To change its position use the createOptionActionPosition() method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;
use Dvarilek\FilamentTableSelect\Enums\SelectionModalActionPosition;
use Filament\Forms\Form;

TableSelect::make('clients')
    ->relationship('clients', 'name')
    ->createOptionForm(fn (Form $form) => ClientResource::form($form))
    ->createOptionActionPosition(SelectionModalActionPosition::TOP_LEFT)

Advanced

To globally configure all TableSelect component instances, use the configureUsing() method in you application's Service Provider boot method:

use Dvarilek\FilamentTableSelect\Components\Form\TableSelect;

public function boot(): void
{
    TableSelect::configureUsing(static function (TableSelect $tableSelect): void {
        $tableSelect->requiresSelectionConfirmation();
    });
}

Testing

composer test

Changelog

Please refer to Package Releases for more information about changes.

License

This package is under the MIT License. Please refer to License File for more information