Skip to main content

Overview

The SelectFilter class provides a dropdown filter with customizable options. It supports single or multiple selection, searchable dropdowns, and parent-child dependencies for cascading filters.

Creating a SelectFilter

make
static method
required
Creates a new SelectFilter instance.
field
string
required
The database column name to filter on
SelectFilter::make('status')

Available Methods

setOptions

setOptions
method
required
Sets the available options for the dropdown.
options
array<string, string>
required
An associative array where keys are values and values are labels
SelectFilter::make('role')
    ->setOptions([
        'admin'  => 'Administrator',
        'editor' => 'Editor',
        'viewer' => 'Viewer',
    ])

label

label
method
Sets the display label for the filter.
label
string
required
The label text to display
SelectFilter::make('status')
    ->label('User Status')

placeholder

placeholder
method
Sets placeholder text for the select dropdown.
text
string
required
The placeholder text
SelectFilter::make('category')
    ->placeholder('Select a category...')

multiple

multiple
method
Enables multiple selection mode (uses whereIn query).
SelectFilter::make('tags')
    ->setOptions($tagOptions)
    ->multiple()

searchable

searchable
method
Renders an Alpine-powered dropdown with text search instead of a native select element.
SelectFilter::make('country')
    ->setOptions($countries)
    ->searchable()
The searchable() method is not supported on filters with parent() dependency. Dependent filters use a native select that updates automatically when the parent value changes.

parent

parent
method
Sets a parent filter dependency for cascading filters.
field
string
required
The key of the parent filter
SelectFilter::make('city')
    ->parent('country')

parentFilter

parentFilter
method
Defines the callback that generates options based on the parent filter’s value.
callback
Closure
required
A closure that receives the parent’s value and returns an options array
SelectFilter::make('city')
    ->parent('country')
    ->parentFilter(function (mixed $countryId) {
        return City::where('country_id', $countryId)
            ->pluck('name', 'id')
            ->toArray();
    })

filter

filter
method
Provides a custom query callback to override the default filter behavior.
callback
Closure
required
A closure that receives Builder $query and mixed $value and returns the modified Builder
SelectFilter::make('date_range')
    ->setOptions([
        'today'     => 'Today',
        'this_week' => 'This Week',
        'this_month' => 'This Month',
    ])
    ->filter(function (Builder $query, mixed $value) {
        return match($value) {
            'today'      => $query->whereDate('created_at', today()),
            'this_week'  => $query->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]),
            'this_month' => $query->whereMonth('created_at', now()->month),
            default      => $query,
        };
    })

key

key
method
Overrides the internal key used for the filter.
key
string
required
Custom key identifier

initialValue

initialValue
method
Sets an initial value that is pre-applied when the table first loads.
value
mixed
required
The initial value (or array of values for multiple selection)
SelectFilter::make('status')
    ->setOptions(['active' => 'Active', 'inactive' => 'Inactive'])
    ->initialValue('active')

groupClass / labelClass / inputClass

groupClass
method
Sets CSS classes for the filter wrapper, label, or input element.
SelectFilter::make('status')
    ->groupClass('col-md-6')
    ->labelClass('font-semibold')
    ->inputClass('form-select-lg')

Default Behavior

Single selection:
$query->where($fieldName, $value)
Multiple selection:
$query->whereIn($fieldName, $values)

Dependent Filters Example

Create cascading filters where child options depend on parent selection:
use Livewire\Tables\Filters\SelectFilter;

public function filters(): array
{
    return [
        SelectFilter::make('country')
            ->label('Country')
            ->setOptions([
                'us' => 'United States',
                'ca' => 'Canada',
                'mx' => 'Mexico',
            ]),

        SelectFilter::make('city')
            ->label('City')
            ->parent('country')
            ->parentFilter(function (mixed $countryId) {
                return City::where('country_id', $countryId)
                    ->pluck('name', 'id')
                    ->toArray();
            }),
    ];
}
When the parent filter changes:
  1. The child filter is automatically reset
  2. New options are loaded via parentFilter callback
  3. The child dropdown updates reactively

Multi-Level Dependencies

Chain multiple levels of dependent filters:
public function filters(): array
{
    return [
        SelectFilter::make('country')
            ->label('Country')
            ->setOptions($countries),

        SelectFilter::make('state')
            ->label('State')
            ->parent('country')
            ->parentFilter(fn($countryId) => 
                State::where('country_id', $countryId)->pluck('name', 'id')->toArray()
            ),

        SelectFilter::make('city')
            ->label('City')
            ->parent('state')
            ->parentFilter(fn($stateId) => 
                City::where('state_id', $stateId)->pluck('name', 'id')->toArray()
            ),
    ];
}

Complete Example

use Livewire\Tables\Filters\SelectFilter;
use Illuminate\Database\Eloquent\Builder;

public function filters(): array
{
    return [
        // Basic select filter
        SelectFilter::make('status')
            ->label('Status')
            ->setOptions([
                'active'   => 'Active',
                'inactive' => 'Inactive',
                'pending'  => 'Pending',
            ])
            ->placeholder('All Statuses'),

        // Multiple selection
        SelectFilter::make('tags')
            ->label('Tags')
            ->setOptions(Tag::pluck('name', 'id')->toArray())
            ->multiple(),

        // Searchable dropdown
        SelectFilter::make('country')
            ->label('Country')
            ->setOptions($countries)
            ->searchable(),

        // Searchable + multiple
        SelectFilter::make('categories')
            ->label('Categories')
            ->setOptions($categories)
            ->multiple()
            ->searchable(),

        // Custom filter logic
        SelectFilter::make('created')
            ->label('Created')
            ->setOptions([
                'today'      => 'Today',
                'this_week'  => 'This Week',
                'this_month' => 'This Month',
            ])
            ->filter(function (Builder $query, mixed $value) {
                return match($value) {
                    'today'      => $query->whereDate('created_at', today()),
                    'this_week'  => $query->whereBetween('created_at', [now()->startOfWeek(), now()->endOfWeek()]),
                    'this_month' => $query->whereMonth('created_at', now()->month),
                    default      => $query,
                };
            }),
    ];
}

Build docs developers (and LLMs) love