Installation
Run composer require arkhas/livewire-datatable and publish optional config/views:
php artisan vendor:publish --tag=livewire-datatable-config
php artisan vendor:publish --tag=livewire-datatable-views
Generate a Datatable Component Use the Artisan command:
php artisan make:datatable TasksTable
This creates a scaffold with WithDatatable trait and basic setup.
Define Columns and Query
In TasksTable.php, configure columns and query:
public function setup(): void
{
$this->table = new EloquentTable(Task::query());
$this->table->addColumn(new Column('id', 'ID'));
$this->table->addColumn(new Column('title', 'Title'));
$this->table->addColumn(new ActionColumn('actions', 'Actions'));
}
Render the Component Add to a Blade view:
<livewire:tasks-table />
EloquentTable for Eloquent models.addColumn() (e.g., Column, CheckboxColumn).ActionColumn for edit/delete buttons).$this->table->addColumn(new ActionColumn('actions', 'Actions'))
->addAction(new TableAction('Edit', 'edit', 'edit-task', 'primary'))
->addAction(new TableAction('Delete', 'delete', 'delete-task', 'danger'));
Data Binding
WithDatatable trait to auto-bind table data to Livewire properties.getQuery():
public function getQuery()
{
return Task::query()->where('user_id', auth()->id());
}
Column Customization
Column for simple fields.CheckboxColumn.ActionColumn or ColumnActionGroup.render() in a column class:
$this->table->addColumn(new Column('status', 'Status'))
->render(function ($value) {
return $value === 'completed' ? '✅' : '⏳';
});
Filtering
Filter for text/number inputs.FilterOption for select boxes.DateFilter or RangeFilter.$this->table->addFilter(new Filter('title', 'Title'))
->addFilterOption(new FilterOption('status', 'Status', ['completed', 'pending']));
Exporting
config/livewire-datatable.php):
'exports' => [
'enabled' => true,
'formats' => ['csv', 'excel', 'pdf'],
],
$this->table->addExportButton();
Pagination and Sorting
EloquentTable. Customize in getQuery():
public function getQuery()
{
return Task::query()->orderBy($this->sortField, $this->sortDirection);
}
mount() for initialization logic:
public function mount()
{
$this->table->setPerPage(10); // Default items per page
}
if (auth()->user()->isAdmin()) {
$this->table->addColumn(new Column('created_at', 'Created At'));
}
class BaseTable extends Component
{
use WithDatatable;
public function setup()
{
$this->table->setPerPage(20);
$this->table->addExportButton();
}
}
Query Overrides
getQuery() can break filtering/sorting.getQuery():
public function getQuery()
{
return Task::query()->where(...); // Return the query!
}
Column Naming Conflicts
id).$this->table->addColumn(new Column('id', 'ID', 'task_id'));
Filter Persistence
WithDatatable is used and filters are properly defined:
$this->table->addFilter(new Filter('search', 'Search'))->debounce(500);
Performance with Large Datasets
select() to limit columns:
$this->table->getQuery()->select(['id', 'title', 'status']);
Flux Pro Dependency
flux:alert).composer require flux/flux-pro
Default Per-Page Setting
setup():
$this->table->setPerPage(50);
'default_per_page' => 25,
Export Formats
spatie/laravel-data-export for CSV/Excel/PDF:
composer require spatie/laravel-data-export
Custom Views
php artisan vendor:publish --tag=livewire-datatable-views --force
resources/views/vendor/livewire-datatable/....Custom Columns
Column class for complex rendering:
class ProgressColumn extends Column
{
public function render($value)
{
return view('custom.progress', ['value' => $value]);
}
}
Custom Actions
TableAction or ColumnAction for custom logic:
class CustomAction extends TableAction
{
public function handle()
{
// Custom logic (e.g., API call)
}
}
Event Listeners
$this->table->listen('rowSelected', function ($row) {
$this->emit('rowSelected', $row);
});
API Integration
getTableData() to fetch data via API:
public function getTableData()
{
return Task::api()->get();
}
How can I help you explore Laravel packages today?