Unable to populate data in DataTable from Controller in Codeingiter - ajax

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.

Related

Highlight colour status of information based on ID in Datatable (Laravel 8)

I have an index table with a user that have an information status of verification based on passed on ID every time user register. Every status has 3 value which is 'Draft','Need Verify','Verified' under DB name status_records based on this picture. I want to make colouring text based on ID. For example, If user under 'Draft', the text status in index datatable will colouring text 'Draft' with blue colour while if user under 'Verified' the colour for text will be green.
I'm using Datatable for showing the index. For value under status column, it only passed the ID and just showing the standard black colour. Refer the picture below,
I'm still new to Datatable and i do not know where to put the logic whether in controller or JS index blade.
But here is my mode user.php for relationship with statusrecord :
public function statusrecord(){
return $this->hasOne(StatusRecord::class, 'id', 'status_record');
}
UserController
public function index(){
$record = User::with('ownership','assetdpa','statusrecord')->where('asset_type_id','=',1)->orderby('id', 'asc')->get();
if(request()->ajax()){
return DataTables()::of($record)
->addIndexColumn()
->addColumn('status', function($record){
if($record->statusrecord){
return '<span class="badge badge-primary" >Active</span>';
}else{
return '<span class="badge badge-danger">Deactive</span>';
}
})
->rawColumns(['action', 'fullOrganisation','fullLocation','fullCategory'])
->make(true);
}
return view('asset.index',compact('record'));
}
index.blade.php
$(document).ready(function(){
$('#item_table').DataTable({
columnDefs: [{data:('statusrecord'),
render: function ( statusrecord, type, row ) {
var color = 'black';
if (id = 1) {
color = 'green';
}
if (id = 2) {
color = 'blue';
}
if (id = 3) {
color = 'red';
}
return '<span style="color:' + color + '">' + data + '</span>';
}
}]
})
})
Instead of rendering the table on the index. Make an Ajax call to the data and have it produce the table.
In web.php create a route -
Route::get ('trailer/list', [TrailersController::class, 'getTrailers'])->name ('trailers.list');
In your controller example (This way you can map the data you want to show in the Table) -
// Tractor list for DataTables
public function getTrailers(Request $request)
{
$trailers= Trailers::latest()->get();
return Datatables::of($trailers)
->addColumn('Actions', function ($trailers) {
return '<button class="btn btn-light btn-active-light-info btn-sm" data-bs-toggle="modal" data-bs-target="#edit-trailers-'.$trailers->id.'" class="menu-link px-3">Edit</button>';
})
->rawColumns(['Actions'])
->make(true);
}
For example - Here is what I have to show a trailer. In the status column all I'm doing is a call stating if status = 'Active' show a green badge. If 'Inactive' show a red badge.
$(function () {
$("#trailer_table").DataTable({
processing: !0,
serverSide: !0,
searching: !1,
order: [[0, "desc"]],
search: { return: !0 },
pageLength: 7,
ajax: '{!! route('trailers.list') !!}',
columns: [
{ data: "status",
render: function(data, type, row, meta){
if(type === 'display'){
if(data === 'Active'){
data = '<span class="badge badge-light-success">Active</span>';
}
else if(data === 'Inactive'){
data = '<span class="badge badge-light-danger">Inactive</span>';
}
return data;
}}},
{ data: "trailer_id", name: "trailer_id" },
{ data: "year", name: "year" },
{ data: "make", name: "make" },
{ data: "model", name: "model" },
{ data: "owned_by", name: "owned_by" },
{ data: "last_inspection", name: "last_inspection" },
{ data: "Actions", name: "Actions", orderable: !1, serachable: !1, sClass: "text-center" },
],
});
});
Hope this helps a little.

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);
}
});

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
] } );
} );

DataTables jquery.dataTables.min.js:181 Uncaught TypeError: Cannot read property 'length' of undefined

I can't specify what/where is the problem, here is my code :
HTML :
<table id="companies" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th class="center">
Id
</th>
<th>RegNo</th>
<th>Name</th>
<th class="hidden-480">Industry</th>
<th class="hidden-phone">
Size
</th>
<th class="hidden-480">LineOfDefence</th>
<th>Address</th>
</tr>
</thead>
</table>
Server side :
var result = new
{
rows = (from company in db.Company.ToList()
select new
{
id = company.CompanyId,
RegNo = company.RegestrationNumber,
Name = company.Name,
Industry = company.IndustryType.Name,
Size = company.CompanySize.Name,
LineOfDefence = company.LineOfDefence.Name,
Address = company.Address
}).ToArray()
};
return Json(result, JsonRequestBehavior.AllowGet);
and here is my Ajax Call :
<script>
$(document).ready(function ()
{
$('#companies').DataTable( {
"ajax": {
url: "/Company/GetCompanyGrid",
type: "GET",
dataType: "json"
}
});
});
</script>
I'm getting this error : "jquery.dataTables.min.js:181 Uncaught TypeError: Cannot read property 'length' of undefined"
note : I'm using jquery-1.12.3.js & DataTables 1.10.12.
Any help would be appreciated .
finally I've figured out the problem :
first : datatables expects specific format, so I changed my server side code like this :
var result = new
{
**draw = 1,
recordsTotal = db.Company.ToList().Count,
recordsFiltered = db.Company.ToList().Count,**
data = (from company in db.Company.ToList()
select new
{
Id = company.CompanyId,
RegNo = company.RegestrationNumber,
Name = company.Name,
Industry = company.IndustryType.Name,
Size = company.CompanySize.Name,
LineOfDefence = company.LineOfDefence.Name,
Address = company.Address,
}).ToArray()
};
return Json(result
, JsonRequestBehavior.AllowGet);
second : I've added these lines to my script
<script>
$(document).ready(function ()
{
$('#companies').DataTable( {
"ajax": {
url: "/Company/GetCompanyGrid",
type: "GET",
dataType: "json"
},"columns": [
{ "data": "Id" },
{ "data": "RegNo" },
{ "data": "Name" },
{ "data": "Industry" },
{ "data": "Size" },
{ "data": "LineOfDefence" },
{ "data": "Address" },
{ "data": "Logo" },
{ "data": null },
]
});
});
</script>
and now it's working perfectly.
Datatables expects the returned json to be in a specific format, as per the documentation - see the 'Returned data' section.
Your json should look something like this:
return Json(new
{
param.draw,
recordsTotal = result.Count,
recordsFiltered = result.Count,
data = result
}, JsonRequestBehavior.AllowGet);
The error is probably a result of datatables looking for a field that isn't present. Note that the draw value is sent in the original GetCompanyGrid() request, you don't need to generate it yourself.

Serverside processing with CoideIgniter and Ignited-Datatables

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,

Resources