K
KoreUI

Filtros

DataTable

8 tipos de filtro reutilizables con 4 layouts y query personalizada.

Demo en vivo

DataTable con TextFilter, SelectFilter, BooleanFilter, NumberRangeFilter y DateRangeFilter en layout slide-down.

Por página
AirPods Max Audio $549.00 28 active
AirPods Pro 3 Audio $249.00 40 draft
AirTag 4-Pack Accesorios $99.00 100 active
Apple Pencil Pro Accesorios $129.00 60 active
Apple TV 4K Streaming $129.00 35 active
Apple Watch Ultra Wearables $899.00 15 active
Beats Solo 4 Audio $199.00 30 active
HomePod mini Audio $99.00 72 active
Mac Mini M4 Desktops $699.00 20 draft
Mac Pro M4 Ultra Desktops $6,999.00 2 archived
Mac Studio M4 Ultra Desktops $3,999.00 6 draft
MacBook Air 13" Laptops $1,099.00 38 active
MacBook Pro 14" Laptops $1,999.00 22 active
MacBook Pro 16" Laptops $2,499.00 12 active
MagSafe Charger Accesorios $39.00 200 active
Magic Keyboard Accesorios $299.00 50 active
Magic Mouse Accesorios $99.00 45 active
Pro Display XDR Monitores $4,999.00 3 archived
Studio Display Monitores $1,599.00 8 active
Vision Pro Wearables $3,499.00 5 active
iPad Air M2 Tablets $799.00 33 active
iPad Pro 13" M4 Tablets $1,299.00 18 active
iPad mini 7 Tablets $499.00 25 active
iPhone 15 Pro Smartphones $1,199.00 45 active
iPhone SE 4 Smartphones $429.00 55 active

Definir filtros

Los filtros se definen en el método filters() de tu DataTable.

Método filters()
public function filters(): array
{
    return [
        TextFilter::make('Nombre', 'name')
            ->placeholder('Buscar por nombre...'),

        SelectFilter::make('Ciudad', 'city')
            ->options($cities)
            ->placeholder('Todas'),

        BooleanFilter::make('Activo', 'is_active'),

        NumberRangeFilter::make('Rango precio', 'price'),

        DateRangeFilter::make('Fecha', 'created_at'),
    ];
}
public function filters(): array
{
    return [
        TextFilter::make('Nombre', 'name')
            ->placeholder('Buscar por nombre...'),

        SelectFilter::make('Ciudad', 'city')
            ->options($cities)
            ->placeholder('Todas'),

        BooleanFilter::make('Activo', 'is_active'),

        NumberRangeFilter::make('Rango precio', 'price'),

        DateRangeFilter::make('Fecha', 'created_at'),
    ];
}

Tipos de filtro

Cada tipo genera una query SQL diferente y usa un componente kore-ui específico.

Filtro SQL generado Componente UI
TextFilterWHERE col LIKE %val%<x-kore::input>
SelectFilterWHERE col = val<x-kore::select>
MultiSelectFilterWHERE col IN (...)<x-kore::select multiple>
BooleanFilterWHERE col = bool<x-kore::select> (Todos/Sí/No)
NumberFilterWHERE col {op} val<x-kore::number>
NumberRangeFilterWHERE col >= min AND col <= maxDos <x-kore::number>
DateFilterwhereDate(col, val)<x-kore::datepicker>
DateRangeFilterwhereDate BETWEEN<x-kore::datepicker mode="range">

TextFilter

Búsqueda LIKE por campo de texto.

TextFilter
TextFilter::make('Nombre', 'name')
    ->placeholder('Buscar...')
    ->debounce(300)
TextFilter::make('Nombre', 'name')
    ->placeholder('Buscar...')
    ->debounce(300)

SelectFilter

Selector con opciones estáticas o dinámicas.

SelectFilter
// Opciones estáticas
SelectFilter::make('Estado', 'status')
    ->options([
        ['label' => 'Activo', 'value' => 'active'],
        ['label' => 'Inactivo', 'value' => 'inactive'],
    ])
    ->optionLabel('label')
    ->optionValue('value')
    ->placeholder('Todos')
    ->searchable()

// Opciones dinámicas desde DB
SelectFilter::make('Categoría', 'category')
    ->options(
        Product::distinct()->pluck('category')
            ->map(fn ($c) => ['label' => $c, 'value' => $c])
            ->toArray()
    )
    ->optionLabel('label')
    ->optionValue('value')
// Opciones estáticas
SelectFilter::make('Estado', 'status')
    ->options([
        ['label' => 'Activo', 'value' => 'active'],
        ['label' => 'Inactivo', 'value' => 'inactive'],
    ])
    ->optionLabel('label')
    ->optionValue('value')
    ->placeholder('Todos')
    ->searchable()

// Opciones dinámicas desde DB
SelectFilter::make('Categoría', 'category')
    ->options(
        Product::distinct()->pluck('category')
            ->map(fn ($c) => ['label' => $c, 'value' => $c])
            ->toArray()
    )
    ->optionLabel('label')
    ->optionValue('value')

BooleanFilter

Filtro de tres estados: todos, sí, no.

BooleanFilter
BooleanFilter::make('Activo', 'is_active')
    ->trueLabel('Activos')
    ->falseLabel('Inactivos')
    ->allLabel('Todos')
BooleanFilter::make('Activo', 'is_active')
    ->trueLabel('Activos')
    ->falseLabel('Inactivos')
    ->allLabel('Todos')

NumberRangeFilter

Rango numérico con min y max.

NumberRangeFilter
NumberRangeFilter::make('Rango de precio', 'price')
    ->key('price_range')
    ->min(0)
    ->max(10000)
    ->step(100)
NumberRangeFilter::make('Rango de precio', 'price')
    ->key('price_range')
    ->min(0)
    ->max(10000)
    ->step(100)

DateRangeFilter

Rango de fechas con datepicker.

DateRangeFilter
DateRangeFilter::make('Fecha de creación', 'created_at')
    ->minDate('2024-01-01')
    ->maxDate(now()->format('Y-m-d'))
DateRangeFilter::make('Fecha de creación', 'created_at')
    ->minDate('2024-01-01')
    ->maxDate(now()->format('Y-m-d'))

Layouts de filtro

Cuatro layouts para mostrar los filtros.

Configurar layout
public function configure(): void
{
    // Popover (default) — botón que abre un popover por filtro
    $this->setFilterLayout('popover');

    // Slide Down — panel colapsable debajo del toolbar
    $this->setFilterLayout('slide-down');

    // Inline — filtros siempre visibles. Ideal para pocos filtros
    $this->setFilterLayout('inline');

    // Drawer — panel lateral deslizable. Ideal para muchos filtros
    $this->setFilterLayout('drawer');
}
public function configure(): void
{
    // Popover (default) — botón que abre un popover por filtro
    $this->setFilterLayout('popover');

    // Slide Down — panel colapsable debajo del toolbar
    $this->setFilterLayout('slide-down');

    // Inline — filtros siempre visibles. Ideal para pocos filtros
    $this->setFilterLayout('inline');

    // Drawer — panel lateral deslizable. Ideal para muchos filtros
    $this->setFilterLayout('drawer');
}

Filter pills: Cuando hay filtros activos, se muestran automáticamente como pills debajo del toolbar con botón X individual y link "Limpiar filtros".

Query personalizada

Usa callback() para aplicar lógica custom al filtrar.

Filtro con callback personalizado
SelectFilter::make('Estado', 'status')
    ->callback(function (Builder $query, $value) {
        $query->where('status', $value)
              ->where('verified', true);
    }),
SelectFilter::make('Estado', 'status')
    ->callback(function (Builder $query, $value) {
        $query->where('status', $value)
              ->where('verified', true);
    }),