Serverside processing with CoideIgniter and Ignited-Datatables - codeigniter

I read many tutorial, I googled but I still can not figure out the problem. Something must be wrong, or I just simply do not understand a part of it.
I have some database tables which has over 10k rows. I want to load only 1 page (50 rows), and I want the processing to happen on paging, searching or at filtering and to not to load all rows from the database.
What am I missing? Thanks!
I am using the lastest version of codeigniter and ignited datatables.
Controller (for table creation):
$tmpl = array('table_open' => '<table id="logs" class="table table-striped table-hover">');
$this->table->set_template($tmpl);
$data['title'] = 'Activity log';
$this->table->set_heading('Time', 'User', 'Activity');
$this->load->view('templates/header', $data);
$this->load->view('templates/sidebar');
$this->load->view('logs/activity');
$this->load->view('templates/footer');
Controller (for data):
$this->datatables->select('id, log_change_id as activity, timestamp, users_id')
->from('log');
echo $this->datatables->generate();
View's content:
$(document).ready(function () {
var oTable = $('#logs').dataTable({
"Processing": true,
"ServerSide": true,
"columns": [
{ "data": "timestamp" },
{ "data": "users_id" },
{ "data": "activity" }
],
"ajax": '<?php echo base_url(); ?>database/activity',
"language": {
'sLoadingRecords': '<div class="text-center"><i class="fa fa-5x fa-refresh fa-spin"></i></div>'
},
});
});

My whole life was a lie. Changed this, to that and its working like charm.
"Processing": true,
"ServerSide": true,
That:
processing: true,
serverSide: true,

Related

My laravel Yajra datatable does not render. It says invalid json response. However I can not read the error since the response is empty

Hello I have the following controller method to return data to my datatable in Laravel,
Controller Method
public function get(Request $request) {
return Datatables::of(AppUser::all())
->addColumn('status', function ($user) {
if ($user->status == 1) {
return '<span class="label label-success">Active</span>';
} else {
return '<span class="label label-danger">Inactive</span>';
}
})
->addColumn('actions', function ($user) {
return view('backend.appuser.actionButton', compact('user'))->render();
})
->make(true);
}
Then in the view I render the datatable, I have the following code.
<table id="users-table" class="table table-condensed table-hover">
<thead>
<tr>
<th>Username</th>
<th>NIC</th>
<th>Mobile</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
</table>
Inside my script tag I have the below code
$(function() {
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: {
url: '{{ route("admin.app-access.user.get") }}',
type: 'get',
data: {status: 1, trashed: false}
},
columns: [
{data: 'email', name: 'email'},
{data: 'nic', name: 'nic'},
{data: 'mobile', name: 'mobile'},
{data: 'status', name: 'status'},
{data: 'actions', name: 'actions'}
],
pageLength:25,
lengthMenu:[[10,25,50,100,-1],[10,25,50,100,"All"]],
order: [ [ 0, "desc" ] ],
dom: "lBfrtip",
buttons:
[
{extend: 'excel', footer: true, title: 'User Details'},
{extend: 'pdf', footer: true, title: 'User Details', orientation: 'landscape', pageSize: 'LEGAL'},
{extend: 'print', footer: true, title: 'User Details', orientation: 'landscape', pageSize: 'LEGAL'}
],
searchDelay: 500
});
});
The Error
When I go to the index page that the datatable is loaded, it says,
DataTables warning: table id=users-table - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
What I tried
I tried making a little syntax error in the above controller method to see if the application crashes. If the application crashes, it means that the request sent from the datatable must have hit my controller method. (App actually crashed, so the request from the datatable is coming to my controller method.)
I went to the network tab in my developer tools and inspected the response for the request sent from the data-table. The response is empty. It just shows three empty lines. Since the response is empty, I can not figure out what the error is.
Below picture shows the response I got.
(I am using Laravel 5.4)
I have added rawColumns before the ->make(true) will you try with this solution once?
It should work I guess so!
So here your will looks like...
public function get(Request $request) {
return Datatables::of(AppUser::all())
->addColumn('status', function ($user) {
if ($user->status == 1) {
return '<span class="label label-success">Active</span>';
} else {
return '<span class="label label-danger">Inactive</span>';
}
})
->addColumn('actions', function ($user) {
return view('backend.appuser.actionButton', compact('user'))->render();
})
->rawColumns(['status', 'actions'])
->make(true);
}

How to get the data for a DataTable from the Controller to View using Ajax

In my main controller, I have a function that gets the data from the database, formats it and output it as JSON. My problem now is how to display this data to the DataTable. Most examples I read have the data saved from a different file from the controller. I would for the data to be from a function in the controller. How do I call that function?
View (SampleView.php)
<table id="example" class="display" width="100%" cellspacing="0">
<thead>
<tr>
<th>EmpID</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
</table>
<script type="text/javascript">
$( document ).ready(function() {
var table = $('#example').DataTable( {
"ajax": "main/getDataFunction",
// "ajax": "getDataFunction",
// "ajax": "<?php echo base_url()."main/getDataFunction"; ?>",
// "ajax": { url: 'main/getDataFunction', type: 'POST' },
"bPaginate":true,
"bProcessing": true,
"pageLength": 10,
"columns": [
{ mData: 'EmpID' } ,
{ mData: 'FirstName' },
{ mData: 'LastName' }
]
});
});
</script>
Controller (Main.php)
function getDataFunction() {
$sampleData = $this->db->getSampleData();
$data = array();
foreach($sampleData as $key) {
array_push($data, array("EmpID" => $key->empID,
"FirstName" => $key->firstName,
"LastName" => $key->lastName));
}
$results = array("sEcho" => 1,
"iTotalRecords" => count($data),
"iTotalDisplayRecords" => count($data),
"aaData"=>$data);
echo json_encode($results);
}
Output of echo json_encode($results)
{"sEcho":1,"iTotalRecords":1,"iTotalDisplayRecords":1,"aaData":[{"EmpID":"1","FirstName":"JOHN","LastName":"DOE"}]}
I am not sure about DataTable but what you can do is you can use eval() to evaluate json data first and then fetch your json response values into view.
Old way which I knew is —
$.ajax(function() {
type : 'get', // or 'post',
data : {key:value},
dataType : 'json',
success : function(response){
var html_data = response.eval(); // this will serialize your data object
$('selector').val(html_data.name);
// $('selector').val(html_data.sEcho); as per your output of the code.
// or
$('selector').html(html_data);
}
});

Unable to populate data in DataTable from Controller in Codeingiter

I am trying to list data with DataTable using server side processing through ajax. I am getting the expected response from the controller when the ajax hits. But the data is still not populated in the dataTable.
Controller
public function get_role_details() {
$this->load_generic_model(array('mst_role_model'));
$draw = intval($this->input->get("draw"));
$start = intval($this->input->get("start"));
$length = intval($this->input->get("length"));
$selected_rol = array('m_role_id','m_role_name');
$condition = array('m_role_status' => 'enable');
$other_configs = array('order_by' => 'm_role_id', 'order_dir' => 'DESC');
// $other_configs
$get_role = $this->mst_role_model->get_where_selected( $selected_rol, $condition, $other_configs);
if( (empty($get_role)) || !($get_role) )
{
echo json_encode(array('status' => 500, 'msg' => 'Server Error, Try again later'));
return false;
}
$data['role'] = $get_role;
$data['role_cnt'] = count($get_role);
$json_data = json_encode(array('status' => 200, 'data' => $data));
echo $json_data;
}
View
<section class="content">
<div class="box">
<div class="box-body">
<table id="logTable1" class="table" width="100%">
<thead>
<th>Role id</th>
<th>Role Name</th>
</thead>
</table>
</div>
</div>
</section>
<script type="text/javascript">
$(document).ready(function() {
$("#logTable1").DataTable({
'processing': false,
'serverSide': true,
'ajax': {
'url':'<?php echo base_url()."role/get_role_details"; ?>',
'type' : 'POST'
},
'columns' : [
{data : 'm_role_id'},
{data : 'm_role_name'}
]
});
});
</script>
I use something similar the following
$( document ).ready(function() { // when document is ready load
$.ajax({ // create an AJAX call...
type: $(this).attr('method'), // GET or POST
url: "<?php echo base_url("controller/function/"); ?>", // the file to call
success: function(response) { // on success..
var dts=JSON.parse(response) // becomes your array
var dataSet =dts.result;
// I specified the results in your case data to just call one filter then create the data table within the success call
$('#table_name').DataTable( {
data: dataSet,
fixedHeader: true,
dom: 'Bfrtip',
buttons: [
'copyHtml5',
'excelHtml5',
'csvHtml5',
'pdfHtml5',
],
columns: [
{ title: "Who",
data: "username",
defaultContent: ""
},
{
title: "Accepted",
data: "accepted_when",
render: function ( data, type, row ) {
var rowgpd = moment(data).format("Do MMM YYYY HH:mm:ss");
return rowgpd;
}},
{ title: "Status",
data: "status",
defaultContent: ""
},
]
} );
}
});
return false; // cancel original event to prevent form submitting
});
I believe it will do exactly as you want.
Its pretty straight forward I think .
So for me I had to parse the response to remove the json encoding and allow me to call the row and columns from the array. I also use moment js to parse the date and display in a better format.
Data array location DataTables requires an array of items to represent
the table's data, where each item in the array is a row. The item is
typically an object or an array (discussed in more detail below) - so
the first thing we need to do is tell DataTables where that array is
in the data source.
https://datatables.net/manual/ajax
Based on your screenshot, your JSON response appears to be this:
{
"data": {
"role": [{
"m_role_id": "47",
"m_role_name": "Aakash"
}, {
"m_role_id": "46",
"m_role_name": "Visiting Doctor"
}]
}
}
This is valid JSON, and it may be what you are expecting. But it is not what DataTables is expecting, when you are using DataTables with 'serverSide': true.
There are two problems:
You need to tell DataTables where the array (containing your row data) is located in your JSON - which in your case is data.role. Normally, you would do this using the dataSrc option:
'ajax': {
'url':'<?php echo base_url()."role/get_role_details"; ?>',
'type' : 'POST',
'dataSrc': 'data.role'
},
Because you are using server-side processing, your JSON response should use the structure shown in the server-side documentation:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [{
"m_role_id": "47",
"m_role_name": "Aakash"
}, {
"m_role_id": "46",
"m_role_name": "Visiting Doctor"
}]
}
Note the following:
The JSON needs to include those extra fields such as recordsTotal, to ensure pagination controls and information are displayed correctly.
The [ ... ] array is now directly attached to data in your JSON. There is no intermediate role object.
You can still keep role if you want to, but then you do still need to use dataSrc, as described above.
I recommend you follow the structure in the documentation, for simplicity.

Laravel Yajra DataTable Column Sorting not proper working

Laravel Yajra DataTable Column Sorting not proper working. If I use ->get() function in Query then DataTable sorting works fine. But I don't want to use get() function because If I have more than 100 000 records then it takes too much time so I don't want to use get() in query
here is my controllers code
$deals = Deal::orderBy('updated_at', 'desc');
$searcharray = array();
parse_str($request->fromValues,$searcharray);
if(isset($searcharray) && !empty($searcharray)){
if($searcharray['filtertype'] !=''){
$deals->where("deal_isApproved",'=',$searcharray['filtertype']);
}
}
$detail_data = $deals;
// print_r($deals);
return Datatables::of($detail_data)
->addColumn('action', function ($data) {
$btn .= '<a class="dropdown-item" href="'.route('admin.deals.edit',$data->id).'" style="color: black;" onmouseover=\'this.style.background="#dee2e6"\' onmouseout=\'this.style.background="none"\'><i class="far fa-edit text-primary"></i> Edit</a>';
$btn .= '<a deal_id="'.$data->id.'" class="dropdown-item deleteDeal" href="#" style="color: black;" onmouseover=\'this.style.background="#dee2e6"\' onmouseout=\'this.style.background="none"\'><i class="far fa-trash-alt text-danger"></i> Delete</a>';
return $btn;
})
->rawColumns(['action'])
->make(true);
here is my datatable initialize in blade file
var dataTable = $('#example_laravel').DataTable({
//lengthMenu: getPageLengthDatatable(),
processing: true,
serverSide: true,
order: [],
searchDelay: 500,
"scrollX": "auto",
// responsive: true,
// // "responsive": true,
// "lengthChange": false,
// "autoWidth": false,
ajax: {
url: '{{ route("admin.deals.filter")}}',
type: 'post',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: function (data) {
data.fromValues = $("#filterdealtype").serialize();
},
},
columns: [
{data: 'SrNo', //try with data: 'SrNo' OR data: 'id',
render: function (data, type, row, meta) {
// return meta.row + meta.settings._iDisplayStart + 1;
return meta.row + 1;
}, searchable: false, sortable: false
},
{data: 'deal_title', name: 'deal_title'},
{data: 'deal_desc',
render: function (data, type, row, meta) {
var data = decodeHTMLEntities(data);
var data = data.replaceAll("href=\"","href=\"http://");
return '<div style="width: 340px; word-wrap: break-word;">'+data+'</div>';
},
},
{data: 'deal_price', name: 'deal_price'},
{data: 'deal_retail_price', name: 'deal_retail_price'},
{data: 'deal_percent_off', name: 'deal_percent_off'},
{data: 'deal_img',
render: function (data, type, row, meta) {
if(data){
return '<img id="myImg" src="{{ asset('') }}'+data+'" height="100px" width="100px">';
}else{
return '';
}
}
},
{data: 'deal_start_date', name: 'deal_start_date'},
{data: 'action', name: 'action', searchable: false, sortable: false},
],
});
output I get be like below image
I solve another problem related to sorting... I share answer of this for helping to other people,
Actually when I define orderby in controller than when I click on Datatable Column for sorting then it was not sorting, because when we click on column than it pass two times different different orderby field so its not works,
Solution of Problem
$deals = Deal::select('*');
if($request->order ==null){
$deals->orderBy('created_at', 'desc');
}
& Another problem about wrong sequence of sorting data issue faced because of wrong datatype in DataBase table...
So, Please also verify Datatype of Database
I hope its helps to you...
& thanks to you #ibrahim-dogan this guy for answer me about wrong Datatype...
thank you

JQuery DataTables: Server-Side Search Function Breaking with SQL Error

I have a simple DataTable that I populate with data from a database, specifically from a single view called 'degree_inventory' as opposed to a traditional table. My application is written with Laravel, so I source my data using a route that pulls all the objects that correspond to a model and import them into my table. An additional level of complexity exists because the table has 'child rows', but those are not present by default.
My table:
<table id="program-table" class="table stripe compact">
<thead>
<tr>
<th>Levels</th>
<th>CIP Code</th>
<th>CIP Title</th>
<th>USF Title</th>
<th>Degree(s)</th>
<!-- <th>Activated Term</th>
<th>Suspended Term</th>
<th>Discontinued Term</th> -->
</tr>
</thead>
<tbody>
</tbody>
</table>
My DT declaration looks like:
$('#program-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('serverSide') }}",
columns: [
{
"className": 'details-control',
"orderable": false,
"data": null,
"width": '8%',
"defaultContent": ''
},
{ data: 'cip', width: '10%'},
{ data: 'cip_title' },
{ data: 'item_name' },
{ data: 'degree_name_list' }
],
pageLength: 25,
searching: true,
paging: true,
fixedHeader: true, //plugin not working
"order": [[ 1, "asc" ]] //by default order by cip code
});
And my 'serverSide' route that gets called looks like:
Route::get('/serverSide', [
'as' => 'serverSide',
'uses' => function () {
$model = \App\Degree::query();
return DataTables::eloquent($model)->make();
}
]);
The 'Degree' model is entirely empty except for defining the corresponding table to be 'degree_inventory'
The table initially populates, expands child rows, and paginates perfectly, but any query into the search bar returns the following error:
Column not found: 1054 unknown column 'degree_inventory' in 'where clause' followed by the raw query that attempts to find matches to entries in each row.
If anyone has any insight I'd be very appreciative. Thank you!
The issue was that I had a column of buttons to expand and collapse child rows.
The solution was to disable to searchable property of the expand/collapse column because the content of the column is exclusively images.
For example:
$('#example').dataTable( {
"columns": [
{ "searchable": false }, //first column is the expand button
null,
null,
null,
null
] } );
} );

Resources