Installation
composer require livecontrol/eloquent-datatable
Add the package to your composer.json and run composer update.
Basic Setup
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
$(document).ready(function() {
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: {
url: '/users/datatable',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}
});
});
First Controller Route Define a route and controller method:
Route::post('/users/datatable', [UserController::class, 'datatable']);
Implement the method:
public function datatable()
{
$users = new \App\Models\User();
$dataTable = new \LiveControl\EloquentDataTable\DataTable($users, ['id', 'name', 'email']);
return $dataTable->make();
}
['id', 'name', 'email'] with the columns you want to display.Model Integration
DataTable:
$dataTable = new DataTable(new \App\Models\Post(), ['title', 'body', 'created_at']);
make() to generate the response:
return $dataTable->make();
Column Customization
$dataTable = new DataTable($users, [
'id',
'name',
function($user) {
return '<a href="/users/'.$user->id.'">View</a>';
}
]);
setColumnFormatters:
$dataTable->setColumnFormatters([
'created_at' => function($value) {
return \Carbon\Carbon::parse($value)->format('M d, Y');
}
]);
Query Scoping
$dataTable = new DataTable($users->where('active', true), ['name', 'email']);
addQuery for runtime conditions:
$dataTable->addQuery(function($query) {
$query->where('status', 'published');
});
Pagination and Sorting
setDefaultSort:
$dataTable->setDefaultSort([['column' => 2, 'dir' => 'desc']]);
API Integration
$request->input():
$draw = $request->input('draw', 1);
$start = $request->input('start', 0);
$length = $request->input('length', 10);
json_encode($dataTable->make()).Relationships
$posts = new \App\Models\Post();
$dataTable = new DataTable($posts, [
'title',
function($post) {
return $post->author->name;
}
]);
$posts->with('author');
Conditional Logic
addQuery for dynamic filtering:
if ($request->has('search')) {
$dataTable->addQuery(function($query) use ($request) {
$query->where('name', 'like', '%'.$request->search.'%');
});
}
Exporting Data
$data = $dataTable->getQuery()->get();
return Excel::download(new UsersExport($data), 'users.xlsx');
Multi-Table Queries
$query = \App\Models\User::query()
->join('posts', 'users.id', '=', 'posts.user_id')
->select('users.*', 'posts.count as post_count');
$dataTable = new DataTable($query, ['name', 'email', 'post_count']);
CSRF Protection
<meta name="csrf-token" content="{{ csrf_token() }}">
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
Column Mismatch
Deprecated DataTables Version
$dataTable->setVersionTransformer(new \LiveControl\EloquentDataTable\VersionTransformers\Version110Transformer());
N+1 Queries
$dataTable = new DataTable($users->with('author'), ['name', 'author.name']);
Case Sensitivity
snake_case consistently or access attributes via getAttribute():
$dataTable->setColumnFormatters([
'user_name' => function($user) {
return $user->getAttribute('name');
}
]);
Inspect Raw Query
\Log::info($dataTable->getQuery()->toSql(), $dataTable->getQuery()->getBindings());
Validate Request Data
\Log::info($request->all());
draw, start, length, columns, order, search.Check JSON Response
{
"draw": 1,
"recordsTotal": 100,
"recordsFiltered": 50,
"data": [...]
}
Custom Transformers
\LiveControl\EloquentDataTable\VersionTransformers\BaseTransformer to support new DataTables versions.Query Modifiers
applyQueryModifiers to add custom logic:
$dataTable->setQueryModifier(function($query, $request) {
// Custom logic here
});
Response Customization
make() method or use a decorator pattern to modify the response:
$response = $dataTable->make();
$response['custom_field'] = 'value';
Integration with Laravel Policies
addQuery:
$dataTable = new DataTable($this->authorize()->users(), ['name', 'email']);
Selective Column Loading
$dataTable = new DataTable($users->select(['id', 'name', 'email']), ['name', 'email']);
Indexing
Schema::table('users', function (Blueprint $table) {
$table->index('email');
});
Caching
How can I help you explore Laravel packages today?