Server-Side DataTables Rendering in Laravel
Source: Dev.to
⚠️ Collection Error: Content refinement error: Error: 429 “you (bkperio) have reached your weekly usage limit, upgrade for higher limits: https://ollama.com/upgrade (ref: 82afb66f-8455-4771-8df0-cea9051e57a2)”
Aside from doing indexes, and use join() instead of with(). This example uses the DataTables library.
Route::post(‘/data’, [App\Http\Controllers\MyController::class, ‘datatable’])->name(‘mydata.datatable’);
Date input, datatable, and button.
Start Date
End Date
Show
INVOICE
AMOUNT
$(‘#btnTampilkan’).on(‘click’, function() { _loadMyData(); });
let table; function _loadMyData() { var start = $(‘#start_date’).val(); var end = $(‘#end_date’).val(); if (table) table.destroy(); if (!start || !end) return Swal.fire(‘Warning’, ‘Start & End date is required!’, ‘warning’); table = $(‘#tableMyData’).DataTable({ processing: true, autoWidth: false, serverSide: true, pagingType: ‘full_numbers’, lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], pageLength: 10, destroy: true, ajax: { url: ”{{ route(‘mydata.datatable’) }}”, type: ‘POST’, data: { start_date: start, end_date: end, _token: ”{{ csrf_token() }}” } }, language: { emptyTable: “No data found” }, order: [[1, ‘desc’]], columnDefs: [ { orderable: false, targets: 0, width: ‘3%’ }, ], columns: [ { data: null, render: (data) => “ }, { data: ‘invoice’ }, { data: ‘amount’ }, ], // search delay initComplete() { const api = this.api(); let typingTimer; $(‘#tableMyData_filter input’).off().on(‘keyup’, function (e) { clearTimeout(typingTimer); const value = this.value; if (e.which === 13) { api.search(value).draw(); } else { typingTimer = setTimeout(() => api.search(value).draw(), 500); } }); } }); }
use Illuminate\Http\Request;
public function datatable(Request $request) { $query = … ->whereBetween(‘order_date’, [$request->start, $request->end]);
$maxLimit = 100000;
$columns = [null, 'invoice', 'amount'];
$recordsTotal = min((clone $query)->count(), $maxLimit);
// SEARCH
if ($search = $request->input('search.value')) {
$normalized = str_replace(['.', ','], '', $search);
$query->where(function($q) use ($search, $normalized) {
$q->where('invoice', 'LIKE', "%{$search}%")
->orWhere('amount', 'LIKE', "%{$search}%");
});
}
$recordsFiltered = min((clone $query)->count(), $maxLimit);
// ORDERING
$order = $request->input('order', []);
if ($order && ($col = $columns[$order[0]['column']] ?? null)) {
$query->orderBy($col, $order[0]['dir'] ?? 'ASC');
} else {
$query->orderBy('order_date', 'ASC');
}
// PAGINATION
$start = $request->input('start');
$results = $start >= $maxLimit
? collect()
: $query->offset($start)
->limit(min($request->input('length'), $maxLimit - $start))
->get();
return response()->json([
'draw' => intval($request->draw),
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $results->map(fn($r) => [
'invoice' => $r->invoice,
'amount' => $r->amount,
])
]);
}
Need help building your app? I’m available for freelance web & Android development — raflizocky.netlify.app ☕ Support my writing: paypal.me/raflizocky · saweria.co/raflizocky