Reputation: 961
i am using yajra data tables for server side data-tables my controller is this
public static function alleventsData(Request $request)
{
$limit = intVal($request->input('length'));
$start = $request->input('start');
$meta = EventsRepository::showMeta();
$totalRecords = $meta[1][1]['Value'];
$offset = intVal($start);
$allEvents = EventsRepository::allEvents($offset, $limit);
return Datatables::collection($allEvents)
->addColumn(
'parent',
function ($allEvents) {
return $allEvents['category_name'];
}
)
->addColumn(
'venueName',
function ($allEvents) {
return $allEvents['venue_name'];
}
)
->addColumn(
'venueLocation',
function ($allEvents) {
return $allEvents['location'];
}
)
->addColumn(
'occurs_at',
function ($allEvents) {
return $allEvents['occurs_at'];
}
)
->addColumn(
'hot_popular_main',
function ($allEvents) {
return '<input type="checkbox" name="hot_popular_main" class= "updatePopertyEvent" attr="hot_popular_main" id="'.$allEvents['id'].'" value="'.$allEvents['hot_popular_main'].'" '.($allEvents['hot_popular_main']==1?'checked="checked"':'').'/>';
}
)
->addColumn(
'synchronize',
function ($allEvents) {
return '<button value="'.$allEvents['id'].'" class="btn btn-info synchronize" >Synchronize</button>';
}
)
->addColumn(
'status',
function ($allEvents) {
$status = $allEvents['status']==1?"Active":"Deactive";
return '<button value="'.$allEvents['id'].'" class="btn btn-info status" data-attr="'.$allEvents['status'].'">'.$status.'</button>';
}
)
->with(['recordsTotal'=>$totalRecords, 'recordsFiltered'=>$totalRecords])
->make(true);
}
and my js is this
$(function() {
$('.eventTableAll').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('datatables.alleventsData') !!}',
columns: [
{ data: 'event_name', name: 'event_name' },
{ data: 'parent', name: 'parent', searchable: true },
{ data: 'venueName', name: 'venueName', searchable: true },
{ data: 'venueLocation', name: 'venueLocation', searchable: true },
{ data: 'occurs_at', name: 'occurs_at', searchable: true },
{ data: 'hot_popular_main', name: 'hot_popular_main' },
{ data: 'synchronize', name: 'synchronize' },
{ data: 'status', name: 'status' }
]
});
});
but problem is when i move to next page like on second it does not get any data , i have seen console that it is getting data but not embedded in data-tables data index .
Upvotes: 2
Views: 3754
Reputation: 81
I faced the exact same issue 2 days ago. Here you are fetching records with limit & offset manually and using Datatables::collection().
First if you have enabled csrf for forms in laravel settings:
\App\Http\Middleware\VerifyCsrfToken::class
in Kernel.phpOr set csrf in ajax header before the datatable js function
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
If this is done. And still not working then proceed further.
Solution 1: Just before you pass the fetched data to Datatables::collection() use this:
$allEvents = collect(array_pad($allEvents->toArray(), -($iDisplayStart + count($allEvents->toArray())), 0));
This line gives you data in response of Datatables::collection() something like this: For page 1: data = [ 0=>[event_0], 1=>[event_1], ... limit=>[event_limit] ];
For page n: data = [ 0=>[], 1=>[], ... offset-1=?[], offset=>[event_0], offset+1=>[event_1], ... offset+limit-1=>[event_limit] ];
Nothing but creating empty indexes before the offset in the collection. This is because the collection() or of() [or any other prebuilt functions] consider the $iDisplayStart and looks for data in the collection starting from where index=$iDisplayStart.
And finally
return Datatable::of($allEvents)
->with(['recordsTotal' => $allEventsCount, 'recordsFiltered' => $allEventsCount, 'start' => $iDisplayStart])
->make();
Solution 2: Instead of manually implementing pagination use prebuilt functions of yajra:
return Datatables::of($allEvents)
->filter(function ($allEvents) use ($request, $iDisplayLength, $iDisplayOffset) {
$allEvents->skip(($iDisplayOffset) * $iDisplayLength)
->take($iDisplayLength);
return $allEvents;
})
->with(['recordsTotal' => $allEventsCount, 'recordsFiltered' => $allEventsCount, 'start' => $iDisplayStart])
->make();
Refer: https://datatables.yajrabox.com/eloquent/post-column-search
NOTE: If the above solutions doesn't work, take care of all these things :
$allEventsCount
is the count of all records in database. You need to get it manually using ->count()
Solution 3:
If the above solutions donot work, The last solution would be to drop Yajra and use client side datatables and code for pagination using datatables.js. This doesn't give you performance drop but you will need to do more client side coding. Caching is also available for client-side datatables.
Refer: https://datatables.net/examples/server_side/pipeline.html
datatables.net/examples/data_sources/server_side.html
Upvotes: 3