I am working on datatables. I have posted 2 questions already related to my this question this and this.
AJAX CALL:
API.call("getBasicCallAnalysisData.json", 'POST', function(data) {
basicData = data;
createTable(basicData);
}, function(error) {
console.log(error);
}, jsonStr);
this my json response from server:
{"msg":null,"code":null,"status":null,"result":[{"aNumber":"3224193861","bNumber":"3217284244","cellID":"410-01-604-30226","dateTime":"2017-06-24 23:08:09.0","duration":801,"imei":"27512671195807","imsi":"35788979525680","operatorId":1,"mscId":"2","fileId":"1"},{"aNumber":"3224193861","bNumber":"3217280585","cellID":"410-01-738-13433","dateTime":"2017-06-24 06:53:13.0","duration":198,"imei":"46341570864238","imsi":"33270572168878","operatorId":2,"mscId":"4","fileId":"2"}],"draw":1,"limit":1000,"recordsFiltered":13442,"recordsTotal":13442}
HTML TABLE :
<table id="table" class="display responsive nowrap" cellspacing="0" width="100%">
<thead style="background-color:#303641;">
<tr>
<th>ANUMBER</th>
<th>BNUMBER</th>
<th>DATETIME</th>
<th>DURATION</th>
<th>IMEI</th>
<th>IMSI</th>
<th>CELLID</th>
<th>OPRID</th>
<th>MSC ID</th>
<th>FILE ID</th>
</tr>
</thead>
</table>
and this is my function to load datatable BUT I am facing two errors:
function createTable(data) {
console.log(data);
$('#table').DataTable({
"processing": true,
"serverSide": true,
"bFilter": false,
"iDisplayLength": configData,
dom: 'Bfrtip',
buttons: ['colvis', 'print', 'csv', 'excel', 'pdf'],
searching: false,
language: {
buttons: {
colvis: 'Show/Hide Columns'
}
},
"aaData": data
});
}
The parameter data is response from server. Errors are :
DataTables warning: table id=table - Requested unknown parameter
'aNumber' for row 0, column 0. For more information about this error,
please see http://datatables.net/tn/4
and
Invalid JSON Response.
any idea, how Can i populate datatable with JSON response ?
There is two possibility to get your json into DataTables...
Use a jQuery Ajax request
Use the DataTables remote preocessing
You use the first one.
There is two main problems to your code:
A superflous DataTables attribute.
A valid JSON, but not structured as DataTables expects it.
#1
The attribute "serverSide": true, basically says that you intend to use the "remote processing". So DataTables expects now an "ajax" attribute holding the PHP address to get the JSON. This missing attribute triggered the "invalid JSON" error.
I hear you shouting loud about unclear error messages now!!! (lol)
#2
DataTables expects the data structured as an array for the whole table...
This array has to hold arrays of "row" values. Example here.
That is not what you actually have.
So I made a function to "re-arrange" the data to satisfy DataTables expectations.
console.clear();
// A function to run trhough your json and restructure the data as an array of array.
function arrangeData(data){
var datatableData = [];
for(i=0;i<data.length;i++){
var row = [
data[i].aNumber,
data[i].bNumber,
data[i].cellID,
data[i].dateTime,
data[i].duration,
data[i].imei,
data[i].imsi,
data[i].operatorId,
data[i].mscId,
data[i].fileId
];
datatableData.push(row);
}
console.log(datatableData);
return datatableData;
}
// Your original function not really changed...
function createTable(data) {
$('#table').DataTable({
"processing": true,
//"serverSide": true, // This works with the "remote preocessing" ajax attribute.
"bFilter": false,
//"iDisplayLength": configData, // I commented this one only because I did not have the "configData" variable.
dom: 'Bfrtip',
buttons: ['colvis', 'print', 'csv', 'excel', 'pdf'],
searching: false,
language: {
buttons: {
colvis: 'Show/Hide Columns'
}
},
"aaData": arrangeData(data) // I'm calling the "arrange" function here.
});
}
// This is to simulate the response you get form jQuery Ajax.
var dataset = {
msg:null,
code:null,
status:null,
result:[
{
"aNumber":"3224193861",
"bNumber":"3217284244",
"cellID":"410-01-604-30226",
"dateTime":"2017-06-24 23:08:09.0",
"duration":801,
"imei":"27512671195807",
"imsi":"35788979525680",
"operatorId":1,
"mscId":"2",
"fileId":"1"
},
{
"aNumber":"3224193861",
"bNumber":"3217280585",
"cellID":"410-01-738-13433",
"dateTime":"2017-06-24 06:53:13.0",
"duration":198,
"imei":"46341570864238",
"imsi":"33270572168878",
"operatorId":2,
"mscId":"4",
"fileId":"2"
}
],
"draw":1,
"limit":1000,
"recordsFiltered":13442,
"recordsTotal":13442
};
// Call the table draw function... Certainly in your ajax success callback.
createTable(dataset.result);
CodePen
Related
I have a jquery datatable in my page which I fill up with data like this:
$(document).ready(function () {
var datatable;
$(document).on("click", ".myBtnClass", function () {
if (datatable != null)
datatable.destroy();
datatable = $('#tableProducts').DataTable({
"pageLength": 50,
"processing": false,
"serverSide": true,
"filter": true,
"bLengthChange": false,
"bSort": false,
"orderMulti": false,
"ajax": {
"url": "/Bulk/LoadData/",
"type": "POST",
"data": {
"username": $(".sellerInput").val(),
"drange": $(".select2").val()
},
"dataSrc": function (data) {
return data.data;
}
}
});
});
});
So as you can see here I'm filling up the datatable with data that my method returns "LoadData" ...
The problem here is in this line:
if (datatable != null)
datatable.destroy();
Every time I destroy the table in order to recreate it with new data, I loose the design of the table, and it becomes deformed and looks ugly after it's destroyed/recreated....
Is there any other way to reload the data into the table without actually calling the destroy() method ?
You could try two different approaches:
1. Destroy/reinstanciate the table
add the option destroy:true in the table's initialization, and remove
if (datatable != null)
datatable.destroy();
This tells datatables to destroy and reinstanciate the table when you call the initalization function on an existing instance.
However, this might still mess up the table's design.
2. Use ajax.reload()
another, perhaps preferable approach, is to reload the data using the url provided in the ajax option:
$('#tableProducts').DataTable().ajax.reload();
Here's more info about the ajax.reload() functionality.
I have a Jquery Datatable which displays some data and it has an external search field.I am trying to implement Server side pagination with the help of Jquery Datatable plugin.But the problem is,it has an external search field,in which user can select a date(basically month and year) and search for the records.So, every time user opt for a search the datatable need to be refreshed.Can anyone help me on this.
Datatable
var LeaveDetailsTable = $('#LvReprtTable').DataTable({
"pageLength": 5,
"processing": true,
"serverSide": true,"searching": false,"bLengthChange": false,
"ajax": {
"url": "GetLeaveDetails",
"type": "POST",
"datatype": "json",
"data": function (d) {
d.EmpId = empId;
d.UserType = userType;
d.Month = "1";
d.year = "2017";
}
},
"columns": [
{ "data": "_fromdate" },
{ "data": "_todate" },
{ "data": "_strLvType" },
{ "data": "_leavedurationtype" },
{ "data": "_leavedurationtype" },
{ "data": "_leavedurationtype" },
],
"columnDefs": [{
"targets": -1,
"data": data,
"defaultContent": "<button>Click!</button>"
}]
,"language":
{
"processing": "<div class='row text-center waitIconDiv' id='LoadIconDiv'><img alt='Progress' src='~/Content/images/wait_icon.gif' width='50' height='50' id='imgProgLvRprt' /></div>"
},
});
Month and year may vary.
You would need to call the ajax.reload() on the datatable instance in whatever event of whatever element you want :
LeaveDetailsTable.ajax.reload();
which will post the state of datatables with your new parameters that got added in data property to the controller action.
You can also take a look at this article (Server Side Advanced Search using JQuery DataTables) which explains how to send custom parameters to controller action with JQuery DataTables.
To achieve this I recommend you to use jquery onchange method. For example:
$('.input-class').on('change', function () {
$table.fnDraw();
});
Here $table refers the name of your Datatable and fnDraw() is a Datatable function to refresh your table.
And obviously you need to add data from search field to the request. For this, I recommend you going through link below:
datatables
For displaying my data in a table, I use the dataTable plugin. As I have a big amount of data, I use the serverside processing. My problem is, that I have some data fields in my obtained JSON, that I would like to change before i display it in the table.
Example: I get values, whether some equipment is available or not. This is written as "", 0 or 1 in datasbase, for displaying it I would like to convert these values to "Yes" or "No" or "N/A".
To initialise the table I use the following code:
table = $('#table').DataTable({
"ajax": "myurl",
"sPaginationType": "full_numbers",
"sAjaxDataProp":"",
"deferRender": true,
columns: [
{data: 'attributes.0.value'},
{data:'attributes.1.value'},
{data:'attributes.2.value'},
{data:'attributes.3.value'},
{data:'attributes.4.value'}],
});
To bind the conerting function directly in the data array doesn't work (like
{data: convert(attributes.0.value)},
There are some parameters for the datatable plugin, which I tried, but I'm not sure, if they can solve my problems. This is an example from the documentation of the plugin:
$('#example').dataTable( {
"ajax": {
"url": "data.json",
"data": function ( d ) {
d.extra_search = $('#extra').val();
}
}
});
Can I use the data parameter to solve my problems (when I tried this, d is always empty) or it there another possibility to change my values before I integrate them in a table?
You could preprocess the JSON in an ajax.dataSrc function, but since you really just need to modify how the values are shown I would go for column rendering :
columns: [
{ data: 'attributes.0.value',
render: function(data, type, row) {
switch(data) {
case '0' : return 'No'; break;
case '1' : return 'Yes'; break;
default : return 'N/A'; break;
}
},
{ data: 'attributes.1.value' },
{ data: 'attributes.2.value' },
{ data: 'attributes.3.value' },
{ data: 'attributes.4.value' }
]
Use the above render method to each of the column values you need to convert.
We use JQuery DataTables extensively. I am now switching all the app tables to AJAX data source to better support search and to render tables faster.
The problem I am having is how to define data rendering inside my table columns. I do not render only data in the column but I need to have some additional markup in some columns (like <span class="label">data</span> or links, etc.).
This can be done via javascript, here is how I did it. The problem is I don't want to have this column definition syntax for every table in my app. Not two tables are identical, and to support all tables/columns like this it would result in bunch of javascript code for every table. I don't see this as a good practice.
$('.data-table').each(function(){
initialize_ajax_data_tables($(this));
});
function initialize_ajax_data_tables(element)
{
var display_rows = element.attr('data-rows') ? parseInt(element.data('rows')) : 25;
var initial_sort = element.attr('data-sort') ? element.data('sort') : [0, 'asc'];
dataTables = element.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
url: base_url+'ajaxprocess/products_data_table.json',
type: 'GET'
},
"columns": [
{ "data": "id" },
{ "data": "product_type_name" },
{ "data": "code" },
{ "data": "name" },
],
"columnDefs": [
{
"render": function ( data, type, row ) {
return '<span class=\"label label-info\">'+ data +'</span>';
},
"targets": 1
},
{
"render": function ( data, type, row ) {
return '<span class=\"label label-success\">'+ data +'</span>';
},
"targets": 2
},
],
"pageLength": display_rows,
"order": initial_sort,
});
dataTables = $.fn.dataTable.fnTables(true);
}
Is there a way to somehow define this column definition/rendering in HTML itself and then pull this in the javascript when initialising DataTables? Or any other way on how to approach this issue?
For sorting rules and pageLength on the DataTables I use data-attributes from the <table> element and that works perfect. This way I define attributes like:
<table id="DataTables_Table_0" class="data-table" data-rows="50" data-sort="[0,"desc"]">
This works fine, but can not use this for columnDefs arrays as render attribute expects function.
I am making some progress and am posting my findings bellow. Maybe some find this useful, but I would still be open to other solutions in case you have a better design.
Currently I have split my code into two three sections:
Main application JS file: common DataTables initialisation code for all the application tables
View: HTML table view generated by the backend and served to the browser. In this view I define table specific properties which are then referenced in in common DataTable init code
Backend AJAX script which serves table data
So to demonstrate this with actual code.
1. Main initialisation code
$('.data-table').each(function(){
initialize_data_tables($(this));
});
function initialize_data_tables(element)
{
if(!(element instanceof jQuery)) element = $(element);
var table_defs = element.attr('data-table-def') ? eval(element.data('table-def')) : [];
dataTables = element.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
url: table_defs.url,
type: 'POST'
},
"columns": table_defs.columns,
"pageLength": table_defs.rows,
"order": table_defs.sort,
});
dataTables = $.fn.dataTable.fnTables(true);
}
2. The HTML view
Here I define specific JS object for table definition, column definition and so on. Every table in app has specific definition. This structure also allows me to have multiple data tables on the view at the same time and reference the right JS object with table properties definition.
<script type="text/javascript">
var tableDef = {
url: "<?= Uri::create('utilities/ajaxprocess/products_data_table.json') ?>",
columns: [
{ "data": "id" },
{ "data": "product_type_name", render: function ( data, type, row ) {
return '<span class=\"label label-info\">'+ data +'</span>';
}
},
{ "data": "code" },
{ "data": "name" },
],
rows: 50,
sort: [ 0, 'desc' ]
};
</script>
<table class="data-table" data-table-def="tableDef”>...</table>
3. The backend
No need to paste my code here. Just functions that query my database and prepare data to be served via AJAX to DataTables.
Following your idea I would say try to define the render methods somewhere and bind them through data attributes.
This solution would be rather easy to test, but I don't think you can work around the columnDefs problematic.
I'm having troubles identify the problem in my code.
I'm doing a searching script, and I'd like to show the results in Datatable. I have a searching form that sends data to my php file and returns a json_encode of my query results, then on ajax success, I build my table passing the results in "data": response.
The query worked just fine when I was doing it without Datatables, but since I need pagination and stuff, I need it to work on Datatables.
HTML for Table:
<div id="results">
<table id="example" class="display compact hover stripe" cellspacing="0" width="100%">
<thead>
<th>Cognome</th>
<th>Nome</th>
<th>Telefono</th>
<th>Provincia</th>
<th>Tipo Cliente</th>
<th>Amministrazione</th>
<th>Stato</th>
<th>Fonte</th>
<th>Data Ricezione</th>
<th></th>
</thead>
</table>
</div>
Javascript for Datatable:
$('#submit_src').on("click", function() {
$.ajax({
data: $("#ricerca").serialize(),
type: $("#ricerca").attr('method'),
url: $("#ricerca").attr('action'),
success: function(response) {
$('#example').dataTable( {
"data": response,
"sPaginationType": "listbox",
"bFilter": false,
"jQueryUI": true,
"processing": true,
'iDisplayLength': 25,
} );
}
});
return false;
});
"submit_src" is my button for submit ofcourse, and "ricerca" is the name of my form.
The json code I get is:
{"sEcho":0,"iTotalRecords":"35036","iTotalDisplayRecords":"1","aaData":[["stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff"]]}
Error:
DataTables warning: table id=example - Requested unknown parameter '1' for row 0.
This link may help with what you are trying to accomplish: http://datatables.net/release-datatables/examples/ajax/objects.html. It explains that DataTables expects arrays for the data; however, in order to use the objects it can be done by using the columns.data option.
I have also used DataTables without <tbody> so that should not be an issue.
Edit:
Try the following, I was able to get the 'stuff' to show in the table:
$('#example').dataTable( {
"data": response.aaData
} );
Edit 2:
jQuery(document).ready(function() {
var response = {
"sEcho":0,"iTotalRecords":"35036","iTotalDisplayRecords":"1",
"aaData": [
["stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff","stuff"]]
};
$('#example').dataTable( {
"data": response.aaData,
//"sPaginationType": "listbox",
"bFilter": false,
"jQueryUI": true,
"processing": true,
'iDisplayLength': 25
} );
});
You are probably missing the option
dataType : "json",
on you code. That might confuse the type of data recieved from the ajax script if not specified.
I believe <tbody></tbody> is required with DataTables so it knows where to put the data returned. Try adding that to your table#example.
<table id="example" class="display compact hover stripe" cellspacing="0" width="100%">
<thead>
<th>Cognome</th>
<th>Nome</th>
<th>Telefono</th>
<th>Provincia</th>
<th>Tipo Cliente</th>
<th>Amministrazione</th>
<th>Stato</th>
<th>Fonte</th>
<th>Data Ricezione</th>
<th></th>
</thead>
<tbody></tbody>
</table>