Avanzado
DataTableFilter presets, inline editing, column select, responsive modes, slots y configuración global.
Demo en vivo
DataTable con filter presets, inline editing, column select y modo responsive card.
- No options found
-
| Progreso | |||||
|---|---|---|---|---|---|
|
AirPods Max
|
Audio | $549.00 | 28 |
active
|
100%
|
|
AirPods Pro 3
|
Audio | $249.00 | 40 |
draft
|
55%
|
|
AirTag 4-Pack
|
Accesorios | $99.00 | 100 |
active
|
100%
|
|
Apple Pencil Pro
|
Accesorios | $129.00 | 60 |
active
|
100%
|
|
Apple TV 4K
|
Streaming | $129.00 | 35 |
active
|
100%
|
|
Apple Watch Ultra
|
Wearables | $899.00 | 15 |
active
|
72%
|
|
Beats Solo 4
|
Audio | $199.00 | 30 |
active
|
100%
|
|
HomePod mini
|
Audio | $99.00 | 72 |
active
|
100%
|
|
Mac Mini M4
|
Desktops | $699.00 | 20 |
draft
|
45%
|
|
Mac Pro M4 Ultra
|
Desktops | $6,999.00 | 2 |
archived
|
100%
|
|
Mac Studio M4 Ultra
|
Desktops | $3,999.00 | 6 |
draft
|
25%
|
|
MacBook Air 13"
|
Laptops | $1,099.00 | 38 |
active
|
90%
|
|
MacBook Pro 14"
|
Laptops | $1,999.00 | 22 |
active
|
85%
|
|
MacBook Pro 16"
|
Laptops | $2,499.00 | 12 |
active
|
100%
|
|
MagSafe Charger
|
Accesorios | $39.00 | 200 |
active
|
100%
|
|
Magic Keyboard
|
Accesorios | $299.00 | 50 |
active
|
100%
|
|
Magic Mouse
|
Accesorios | $99.00 | 45 |
active
|
100%
|
|
Pro Display XDR
|
Monitores | $4,999.00 | 3 |
archived
|
100%
|
|
Studio Display
|
Monitores | $1,599.00 | 8 |
active
|
60%
|
|
Vision Pro
|
Wearables | $3,499.00 | 5 |
active
|
30%
|
|
iPad Air M2
|
Tablets | $799.00 | 33 |
active
|
88%
|
|
iPad Pro 13" M4
|
Tablets | $1,299.00 | 18 |
active
|
70%
|
|
iPad mini 7
|
Tablets | $499.00 | 25 |
active
|
65%
|
|
iPhone 15 Pro
|
Smartphones | $1,199.00 | 45 |
active
|
95%
|
|
iPhone SE 4
|
Smartphones | $429.00 | 55 |
active
|
80%
|
| Total: $34,405.00 | Productos: 25 |
Filter Presets
Tabs predefinidos que aplican combinaciones de filtros, sorts y búsqueda.
use KoreUi\DataTable\Presets\FilterPreset;
public function filterPresets(): array
{
return [
FilterPreset::make('all', 'Todos')
->icon('layers')
->default(),
FilterPreset::make('active', 'Activos')
->icon('check-circle')
->filters(['status' => 'active'])
->count(fn () => Product::where('status', 'active')->count()),
FilterPreset::make('draft', 'Borradores')
->icon('pencil')
->filters(['status' => 'draft'])
->sorts(['updated_at' => 'desc']),
];
}use KoreUi\DataTable\Presets\FilterPreset;
public function filterPresets(): array
{
return [
FilterPreset::make('all', 'Todos')
->icon('layers')
->default(),
FilterPreset::make('active', 'Activos')
->icon('check-circle')
->filters(['status' => 'active'])
->count(fn () => Product::where('status', 'active')->count()),
FilterPreset::make('draft', 'Borradores')
->icon('pencil')
->filters(['status' => 'draft'])
->sorts(['updated_at' => 'desc']),
];
}Inline Editing
Edita celdas directamente en la tabla con validación.
Column::make('Nombre', 'name')
->editable()
->editableRules(['required', 'min:3', 'max:255'])
// BadgeColumn con select editable
BadgeColumn::make('Estado', 'status')
->editable()
->editableOptions([
'active' => 'Activo',
'draft' => 'Borrador',
'archived' => 'Archivado',
])
// BooleanColumn con toggle
BooleanColumn::make('Activo', 'is_active')
->editable() // Auto-toggle al clickColumn::make('Nombre', 'name')
->editable()
->editableRules(['required', 'min:3', 'max:255'])
// BadgeColumn con select editable
BadgeColumn::make('Estado', 'status')
->editable()
->editableOptions([
'active' => 'Activo',
'draft' => 'Borrador',
'archived' => 'Archivado',
])
// BooleanColumn con toggle
BooleanColumn::make('Activo', 'is_active')
->editable() // Auto-toggle al clickColumn Select
Toggle de visibilidad de columnas con persistencia en sesión.
public function configure(): void
{
$this->setColumnSelectEnabled(); // Activa el toggle
}
// Desactivar globalmente en config/kore-ui.php
'datatable' => [
'column_select' => false,
]public function configure(): void
{
$this->setColumnSelectEnabled(); // Activa el toggle
}
// Desactivar globalmente en config/kore-ui.php
'datatable' => [
'column_select' => false,
]Responsive
Tres modos de visualización responsive.
public function configure(): void
{
// scroll (default) — Scroll horizontal
// card — Cada fila como card vertical
// collapse — Columnas colapsables con expand
$this->setResponsiveMode('card');
$this->setResponsiveBreakpoint(640); // default: 768
}
// Marcar columnas colapsables (modo collapse)
Column::make('Email', 'email')->collapseOnMobile();
Column::make('Ciudad', 'city')->collapseOnTablet();public function configure(): void
{
// scroll (default) — Scroll horizontal
// card — Cada fila como card vertical
// collapse — Columnas colapsables con expand
$this->setResponsiveMode('card');
$this->setResponsiveBreakpoint(640); // default: 768
}
// Marcar columnas colapsables (modo collapse)
Column::make('Email', 'email')->collapseOnMobile();
Column::make('Ciudad', 'city')->collapseOnTablet();Sorting avanzado
Sort multi-columna con tiebreaker y campos personalizados.
public function configure(): void
{
// Sort con tiebreaker
$this->setDefaultSort('status', 'desc')
->addDefaultSort('id', 'asc');
// Genera: ORDER BY status DESC, id ASC
}
// Sort con campo personalizado (útil en joins)
Column::make('Nombre completo', 'name')
->sortableAs('users.name')public function configure(): void
{
// Sort con tiebreaker
$this->setDefaultSort('status', 'desc')
->addDefaultSort('id', 'asc');
// Genera: ORDER BY status DESC, id ASC
}
// Sort con campo personalizado (útil en joins)
Column::make('Nombre completo', 'name')
->sortableAs('users.name')Búsqueda avanzada
Búsqueda en relaciones y callbacks personalizados.
// Búsqueda en relaciones (dot notation)
// Genera: whereHas('company', fn($q) => $q->where('name', 'like', '%term%'))
Column::make('Empresa', 'company.name')->searchable(),
// Búsqueda personalizada
Column::make('Nombre', 'name')
->searchCallback(function (Builder $query, string $term) {
$query->where('first_name', 'like', "%{$term}%")
->orWhere('last_name', 'like', "%{$term}%");
}),// Búsqueda en relaciones (dot notation)
// Genera: whereHas('company', fn($q) => $q->where('name', 'like', '%term%'))
Column::make('Empresa', 'company.name')->searchable(),
// Búsqueda personalizada
Column::make('Nombre', 'name')
->searchCallback(function (Builder $query, string $term) {
$query->where('first_name', 'like', "%{$term}%")
->orWhere('last_name', 'like', "%{$term}%");
}),Paginación
Tres tipos de paginación según tus necesidades.
public function configure(): void
{
$this->setPaginationType('standard'); // Con total y números
$this->setPaginationType('simple'); // Solo anterior/siguiente
$this->setPaginationType('cursor'); // Eficiente para datasets grandes
}public function configure(): void
{
$this->setPaginationType('standard'); // Con total y números
$this->setPaginationType('simple'); // Solo anterior/siguiente
$this->setPaginationType('cursor'); // Eficiente para datasets grandes
}Slots
Inyecta vistas Blade en puntos del layout.
public function configure(): void
{
$this->setSlot('before-toolbar', 'partials.table-header');
$this->setSlot('toolbar-right-end', 'partials.table-actions', [
'createRoute' => route('products.create'),
]);
}public function configure(): void
{
$this->setSlot('before-toolbar', 'partials.table-header');
$this->setSlot('toolbar-right-end', 'partials.table-actions', [
'createRoute' => route('products.create'),
]);
}| Área | Posición |
|---|---|
before-toolbar | Encima del toolbar |
after-toolbar | Debajo del toolbar |
toolbar-right-end | Extremo derecho del toolbar |
after-table | Después de la paginación |
Ejemplo completo
DataTable con todas las funcionalidades combinadas.
<?php
namespace App\Livewire;
use App\Models\Product;
use Illuminate\Database\Eloquent\Builder;
use KoreUi\DataTable\Actions\BulkAction;
use KoreUi\DataTable\Actions\RowAction;
use KoreUi\DataTable\Columns\ActionColumn;
use KoreUi\DataTable\Columns\BadgeColumn;
use KoreUi\DataTable\Columns\Column;
use KoreUi\DataTable\Columns\DateColumn;
use KoreUi\DataTable\Columns\NumberColumn;
use KoreUi\DataTable\Filters\SelectFilter;
use KoreUi\DataTable\KoreDataTable;
use KoreUi\DataTable\Presets\FilterPreset;
class ProductsTable extends KoreDataTable
{
public function configure(): void
{
$this->setDefaultSort('created_at', 'desc');
$this->setFilterLayout('slide-down');
$this->setColumnSelectEnabled();
$this->setResponsiveMode('card');
}
public function query(): Builder
{
return Product::query();
}
public function columns(): array
{
return [
Column::make('Producto', 'name')
->sortable()
->searchable()
->editable()
->editableRules(['required', 'min:3']),
NumberColumn::make('Precio', 'price')
->sortable()
->money('USD', 'en_US')
->sum('Total'),
BadgeColumn::make('Estado', 'status')
->sortable()
->colors([
'active' => 'success',
'inactive' => 'muted',
'draft' => 'warning',
])
->editable()
->editableOptions([
'active' => 'Activo',
'inactive' => 'Inactivo',
'draft' => 'Borrador',
]),
DateColumn::make('Creado', 'created_at')
->sortable()
->dateFormat('d M Y')
->collapseOnMobile(),
ActionColumn::make()
->actions([
RowAction::make('edit', 'Editar')
->icon('pencil')
->openOverlay('edit-product', fn ($row) => ['id' => $row->id]),
RowAction::make('delete', 'Eliminar')
->icon('trash')
->color('destructive')
->wireMethod('deleteProduct')
->confirm('¿Eliminar este producto?')
->separator(),
]),
];
}
public function filters(): array
{
return [
SelectFilter::make('Estado', 'status')
->options([
['label' => 'Activo', 'value' => 'active'],
['label' => 'Borrador', 'value' => 'draft'],
])
->optionLabel('label')
->optionValue('value')
->placeholder('Todos'),
];
}
public function bulkActions(): array
{
return [
BulkAction::make('delete', 'Eliminar seleccionados')
->icon('trash')
->color('destructive')
->confirm('¿Eliminar :count producto(s)?'),
];
}
public function filterPresets(): array
{
return [
FilterPreset::make('all', 'Todos')->default(),
FilterPreset::make('active', 'Activos')
->filters(['status' => 'active']),
];
}
}<?php
namespace App\Livewire;
use App\Models\Product;
use Illuminate\Database\Eloquent\Builder;
use KoreUi\DataTable\Actions\BulkAction;
use KoreUi\DataTable\Actions\RowAction;
use KoreUi\DataTable\Columns\ActionColumn;
use KoreUi\DataTable\Columns\BadgeColumn;
use KoreUi\DataTable\Columns\Column;
use KoreUi\DataTable\Columns\DateColumn;
use KoreUi\DataTable\Columns\NumberColumn;
use KoreUi\DataTable\Filters\SelectFilter;
use KoreUi\DataTable\KoreDataTable;
use KoreUi\DataTable\Presets\FilterPreset;
class ProductsTable extends KoreDataTable
{
public function configure(): void
{
$this->setDefaultSort('created_at', 'desc');
$this->setFilterLayout('slide-down');
$this->setColumnSelectEnabled();
$this->setResponsiveMode('card');
}
public function query(): Builder
{
return Product::query();
}
public function columns(): array
{
return [
Column::make('Producto', 'name')
->sortable()
->searchable()
->editable()
->editableRules(['required', 'min:3']),
NumberColumn::make('Precio', 'price')
->sortable()
->money('USD', 'en_US')
->sum('Total'),
BadgeColumn::make('Estado', 'status')
->sortable()
->colors([
'active' => 'success',
'inactive' => 'muted',
'draft' => 'warning',
])
->editable()
->editableOptions([
'active' => 'Activo',
'inactive' => 'Inactivo',
'draft' => 'Borrador',
]),
DateColumn::make('Creado', 'created_at')
->sortable()
->dateFormat('d M Y')
->collapseOnMobile(),
ActionColumn::make()
->actions([
RowAction::make('edit', 'Editar')
->icon('pencil')
->openOverlay('edit-product', fn ($row) => ['id' => $row->id]),
RowAction::make('delete', 'Eliminar')
->icon('trash')
->color('destructive')
->wireMethod('deleteProduct')
->confirm('¿Eliminar este producto?')
->separator(),
]),
];
}
public function filters(): array
{
return [
SelectFilter::make('Estado', 'status')
->options([
['label' => 'Activo', 'value' => 'active'],
['label' => 'Borrador', 'value' => 'draft'],
])
->optionLabel('label')
->optionValue('value')
->placeholder('Todos'),
];
}
public function bulkActions(): array
{
return [
BulkAction::make('delete', 'Eliminar seleccionados')
->icon('trash')
->color('destructive')
->confirm('¿Eliminar :count producto(s)?'),
];
}
public function filterPresets(): array
{
return [
FilterPreset::make('all', 'Todos')->default(),
FilterPreset::make('active', 'Activos')
->filters(['status' => 'active']),
];
}
}Configuración global
Defaults globales en config/kore-ui.php.
'datatable' => [
'per_page' => 25,
'per_page_options' => [10, 25, 50, 100],
'density' => 'normal',
'pagination_type' => 'standard',
'search_debounce' => 300,
'filter_layout' => 'popover',
'column_select' => true,
'responsive_mode' => 'scroll',
'responsive_breakpoint' => 768,
'empty_text' => 'No se encontraron resultados',
'empty_icon' => 'inbox',
'translations' => [
'search' => 'Buscar...',
'per_page' => 'Por página',
'showing' => 'Mostrando :from a :to de :total resultados',
'no_results' => 'No se encontraron resultados',
],
],'datatable' => [
'per_page' => 25,
'per_page_options' => [10, 25, 50, 100],
'density' => 'normal',
'pagination_type' => 'standard',
'search_debounce' => 300,
'filter_layout' => 'popover',
'column_select' => true,
'responsive_mode' => 'scroll',
'responsive_breakpoint' => 768,
'empty_text' => 'No se encontraron resultados',
'empty_icon' => 'inbox',
'translations' => [
'search' => 'Buscar...',
'per_page' => 'Por página',
'showing' => 'Mostrando :from a :to de :total resultados',
'no_results' => 'No se encontraron resultados',
],
],