Skip to main content

Introduction

The select column allows you to render a select field inside the table for inline editing:
use Filament\Tables\Columns\SelectColumn;

SelectColumn::make('status')
    ->options([
        'draft' => 'Draft',
        'reviewing' => 'Reviewing',
        'published' => 'Published',
    ])

Select type

By default, Filament uses the native HTML5 select. Enable a JavaScript select:
SelectColumn::make('status')
    ->options([
        'draft' => 'Draft',
        'reviewing' => 'Reviewing',
        'published' => 'Published',
    ])
    ->native(false)
condition
bool | Closure
default:"true"
Whether to use the native select.

Searchable options

Enable searching through options:
SelectColumn::make('author_id')
    ->label('Author')
    ->options(User::query()->pluck('name', 'id'))
    ->searchableOptions()
condition
bool | array | Closure
default:"true"
Whether options are searchable. Pass an array of column names to search specific columns.

Custom search results

Provide custom search results for large datasets:
SelectColumn::make('author_id')
    ->searchableOptions()
    ->getOptionsSearchResultsUsing(fn (string $search): array => User::query()
        ->where('name', 'like', "%{$search}%")
        ->limit(50)
        ->pluck('name', 'id')
        ->all())
    ->getOptionLabelUsing(fn ($value): ?string => User::find($value)?->name)
callback
Closure
A closure that returns search results as a $key => $value array.

Search messages

Customize the search experience:
SelectColumn::make('author_id')
    ->optionsLoadingMessage('Loading authors...')

Search debounce

Customize the search delay:
SelectColumn::make('author_id')
    ->searchableOptions()
    ->optionsSearchDebounce(500)
debounce
int | Closure
default:"1000"
The debounce time in milliseconds.

Relationship integration

Integrate with Eloquent relationships:
SelectColumn::make('author_id')
    ->optionsRelationship(name: 'author', titleAttribute: 'name')
name
string | Closure
required
The relationship name.
titleAttribute
string | Closure
The column to use for option labels.
modifyQueryUsing
Closure
A closure to modify the relationship query.

Searching relationships

Search across multiple columns:
SelectColumn::make('author_id')
    ->optionsRelationship(name: 'author', titleAttribute: 'name')
    ->searchableOptions(['name', 'email'])

Preloading options

Load options immediately instead of on search:
SelectColumn::make('author_id')
    ->optionsRelationship(name: 'author', titleAttribute: 'name')
    ->searchableOptions()
    ->preloadOptions()
condition
bool | Closure
default:"true"
Whether to preload all options.

Custom relationship query

Modify the relationship query:
use Illuminate\Database\Eloquent\Builder;

SelectColumn::make('author_id')
    ->optionsRelationship(
        name: 'author',
        titleAttribute: 'name',
        modifyQueryUsing: fn (Builder $query) => $query->withTrashed(),
    )

Custom option labels

Customize option labels from records:
use Illuminate\Database\Eloquent\Model;

SelectColumn::make('author_id')
    ->optionsRelationship(
        name: 'author',
        modifyQueryUsing: fn (Builder $query) => $query->orderBy('first_name')->orderBy('last_name'),
    )
    ->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}")
    ->searchableOptions(['first_name', 'last_name'])

Remembering options

By default, options are cached per page. Disable for record-specific options:
SelectColumn::make('author_id')
    ->optionsRelationship(name: 'author', titleAttribute: 'name')
    ->rememberOptions(false)
condition
bool | Closure
default:"true"
Whether to remember options.

HTML in option labels

Allow HTML in option labels:
SelectColumn::make('technology')
    ->options([
        'tailwind' => '<span class="text-blue-500">Tailwind</span>',
        'laravel' => '<span class="text-red-500">Laravel</span>',
    ])
    ->searchableOptions()
    ->allowOptionsHtml()
Ensure HTML is safe to prevent XSS attacks.
condition
bool | Closure
default:"false"
Whether to allow HTML in option labels.

Wrapping option labels

Control label wrapping in the JavaScript select:
SelectColumn::make('description')
    ->wrapOptionLabels(false)
condition
bool | Closure
default:"true"
Whether to wrap option labels.

Placeholder selection

Disable null option selection:
SelectColumn::make('status')
    ->options([
        'draft' => 'Draft',
        'published' => 'Published',
    ])
    ->selectablePlaceholder(false)
condition
bool | Closure
default:"true"
Whether the placeholder can be selected.

Disabling options

Disable specific options:
SelectColumn::make('status')
    ->options([
        'draft' => 'Draft',
        'reviewing' => 'Reviewing',
        'published' => 'Published',
    ])
    ->disableOptionWhen(fn (string $value): bool => $value === 'published')
callback
Closure
required
A closure that returns whether an option should be disabled.

Options limit

Limit displayed options:
SelectColumn::make('author_id')
    ->optionsRelationship(name: 'author', titleAttribute: 'name')
    ->searchableOptions()
    ->optionsLimit(20)
limit
int | Closure
default:"50"
The maximum number of options to display.

Validation

Add validation rules:
SelectColumn::make('status')
    ->options([
        'draft' => 'Draft',
        'published' => 'Published',
    ])
    ->rules(['required'])

Lifecycle hooks

Execute code before and after updates:
SelectColumn::make('status')
    ->beforeStateUpdated(function ($record, $state) {
        // Runs before the state is saved
    })
    ->afterStateUpdated(function ($record, $state) {
        // Runs after the state is saved
    })

Build docs developers (and LLMs) love