Filtros
DataTable8 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.
- No options found
-
- No options found
-
- No options found
-
| 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.
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 |
|---|---|---|
TextFilter | WHERE col LIKE %val% | <x-kore::input> |
SelectFilter | WHERE col = val | <x-kore::select> |
MultiSelectFilter | WHERE col IN (...) | <x-kore::select multiple> |
BooleanFilter | WHERE col = bool | <x-kore::select> (Todos/Sí/No) |
NumberFilter | WHERE col {op} val | <x-kore::number> |
NumberRangeFilter | WHERE col >= min AND col <= max | Dos <x-kore::number> |
DateFilter | whereDate(col, val) | <x-kore::datepicker> |
DateRangeFilter | whereDate BETWEEN | <x-kore::datepicker mode="range"> |
TextFilter
Búsqueda LIKE por campo de texto.
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.
// 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::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::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::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.
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.
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);
}),