Aside from doing indexes, and use join() instead of with(). This example uses the DataTables library.
<link rel="stylesheet" href="https://cdn.datatables.net/2.3.7/css/dataTables.dataTables.css" />
<script src="https://cdn.datatables.net/2.3.7/js/dataTables.js"></script>
1. Route
Route::post('/data', [App\Http\Controllers\MyController::class, 'datatable'])->name('mydata.datatable');
2. View
Date input, datatable, and button.
<div class="mb-4 form-group col-lg-4">
<label class="form-label">Start Date</label>
<input type="text" name="start_date" id="start_date" class="form-control" required>
</div>
<div class="mb-4 form-group col-lg-4">
<label class="form-label">End Date</label>
<input type="text" name="end_date" id="end_date" class="form-control" required>
</div>
<div class="mb-4 form-group col-lg-4">
<button class="btn btn-sm btn-light-primary font-weight-bold" id="btnShow">Show</button>
</div>
<table class="table table-hover table-bordered table-vertical-center" id="tableMyData">
<thead class="table-success font-weight-bold">
<tr>
<th class='text-left'>INVOICE</th>
<th class='text-left'>AMOUNT</th>
</tr>
</thead>
<tbody style="white-space: nowrap;"></tbody>
</table>
<script>
$('#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) => `<input type="checkbox" class="row-checkbox" data-nosep="${data.nosep}">`
},
{ 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);
}
});
}
});
}
</script>
3. Controller
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
Top comments (0)