Invalid JSON format Datatable - javascript

I'm trying to implement sever side datatable, but it throws Invalid JSON format error.
CDN
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
HTML
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>EmployeeCode</th>
<th>EmployeeName</th>
<th>ManagerName</th>
<th>DesignationName</th>
</tr>
</thead>
</table>
JS
<script>
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "/api/url",
"columns": [
{ data: "EmployeeCode" },
{ data: "EmployeeName" },
{ data: "ManagerName" },
{ data: "DesignationName" }
],
} );
} );
</script>
JSON
{
"Results":[{"EmployeeCode": "12345"}], // This is just a sample of data
"CurrentPage": 1,
"PageCount": 42,
"PageSize": 10,
"RecordCount": 417
}

it is clear what the issue is, looking at the JSON returned by the XHR/Ajax call to the server. It should just contain the expected data like this:
[
{'EmployeeCode':12345,EmployeeName:'abcde',...},
{'EmployeeCode':12346,EmployeeName:'fghij',...},
...
]
Rather your JSON contains other properties and the data is nested under the "Results" property. Also looking at the documentation, I think you need to format the JSON to contain a data property:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
"12345",
"John Smith",
"Adam James",
"Manager",
],
...
}
So as a simple fix use the 'dataSrc':'Results' property as suggested by Ankush in your datatable configuration.

Use dataSrc attribute to let datatable know from where to collect data:
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "/api/url",
"dataSrc": function (json) {
debugger;
return json.data;
},
"columns": [
{ data: "EmployeeCode" },
{ data: "EmployeeName" },
{ data: "ManagerName" },
{ data: "DesignationName" }
],
} );
} );
More detail about dataSrc can found here.

Related

How can i display on a datatable array data using Ajax?

I'm using a MongoDB database to store some data. I now want to display this data on a HTML Datatable.
The data i'm trying to use is stored in arrays, here is how it is structured:
data: [[1848, 84857], [4944, 4949], [34, 65], [3566, 78], .... ]
$(document).ready(function() {
var table = $('#mytable').DataTable({
"serverSide": true,
"ajax": "/endpoint/?format=datatables",
"columns": [
{"data": 'data'},
]
});
setInterval( function () {
table.ajax.reload();
}, 10000 );
});
The problem with my actual code is that it will display the datatable like this:
DATA:
[[1848, 84857], [4944, 4949], [34, 65], [3566, 78], .... ]
While i would like it like this:
DATA:
1848, 84857
4944, 949
36, 65 and so on
How can i fix this issue? I was thinkin with a foor loop, but i don't really know how to do that, since i'm calling the data straight in the table variable.
The json response is something like this:
{"data":"[[11756.53, 2.419583] .....
You are using array of array data, just use index key to map your columns:
"columns": [
{"data":0},
{"data":1}
]
Awesome Example below:
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
$.mockjax({
url: "/endpoint/?format=datatables",
response: function(settings) {
this.responseText = {
"draw": settings.data.draw,
"recordsTotal": 4,
"recordsFiltered": 4,
"data": [
[randomIntFromInterval(400, 8000), 84857],
[4944, 4949],
[34, 65],
[3566, 78]
]
}
}
});
var editable=false;
$(document).ready(function() {
var table = $('#mytable').DataTable({
"serverSide": true,
"ajax": "/endpoint/?format=datatables",
"columns": [
{"data":0},
{"data":1}
]
});
setInterval( function () {
table.ajax.reload();
}, 10000 );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.6.2/jquery.mockjax.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="mytable" class="display nowrap" width="100%">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</tfoot>
</table>

Store selected rows id

I have a datatable loaded from a query from my database. (+/- 10000 records)
The idea is that the user should be able to select multiple records to be later processed
First i thought to add a column with checkbox for the selection then when user is done with all his selection the application keep track of all selected rows then progress to the next step with "Next Button" some where on the page, but after 12 hours of trying i couldn't do it.
Then i thought to make it simpler by adding a button in each row so that every time the user clicks on this button the application save the selected id in a session variable.
<div class="panel-body">
<table id="userTable" class="table display compact order-column">
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>City</th>
<th>Phone</th>
<th>Zipcode</th>
</tr>
</thead>
</table>
#section Scripts {
#Scripts.Render("~/bundles/datatable")
<script type="text/javascript">
$(document).ready(function () {
var ids;
var mytable = $('#userTable').DataTable({
"sDom": 'ltipr',
"bServerSide": true,
"ajax": {
"beforeSend": AjaxBegin,
"type": "POST",
"url": '/LocationModifier/UserHistory',
"contentType": 'application/json; charset=utf-8',
'data': function (data) { return data = JSON.stringify(data); },
'complete': AjaxComplete
},
"bProcessing": false,
"orderMulti": false,
"scrollX": true,
"deferRender": true,
"searchDelay": 7000,
"fixedHeader": {
"header": true,
"footer": true
},
"columnDefs": [
{ "defaultContent": "-", "targets": "_all" },
{ "className": "text-center custom-middle-align", "targets": [0, 1, 2, 3, 4, ] },
],
"colReorder": true,
"lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]],
"columns": [
{
"title": "Select",
"data": "ID",
"searchable": false,
"sortable": false,
"render": function (data, type, full, meta) {
return '<span class="glyphicon glyphicon-pencil btn-sm btn-info"></span>';
}
},
{ "data": "Name", "orderable": false },
{ "data": "City", "orderable": true },
{ "data": "Phone", "orderable": true },
{ "data": "Zipcode", "orderable": false },
],
"order": []
});
});
</script>
}
public ActionResult AddToCache(int id)
{
GetRecordAndAddeToCache(id);
// what should i return here, the page should not be refreshed????
}
There's no problem to implement your initial approach:
use some global set that will store selected row id's, like var rowsSelected = new Set();
add/delete id of the row being checked to that global variable upon clicking selection checkbox:
$('.markSelected').on('click', function () {
const selectedRowId = dataTable.row($(this).closest('tr')).data().id;
$(this).prop('checked') ? rowsSelected.add(selectedRow) : rowsSelected.delete(selectedRow);
});
upon table re-rendering append checkboxes to the first column and set those checked if rendered row id is present within rowsSelected:
render: function (data) {
return `<input type="checkbox" ${rowsSelected.has(data.id) ? 'checked' : ''}></input>`;
}
The complete demo, implementing that concept:
//table source
const srcData = [
{id: 1, item: 'apple', cat: 'fruit'},
{id: 2, item: 'pear', cat: 'fruit'},
{id: 3, item: 'carrot', cat: 'vegie'},
{id: 4, item: 'tomato', cat: 'vegie'},
{id: 5, item: 'cucumber', cat: 'vegie'}
];
//global variable that stores selected item id's
const selectedRows = new Set();
//datatables initialization
const dataTable = $('#mytable').DataTable({
dom: 't',
data: srcData,
columns: [
{data: null, render: function(data){
return `<input class="markSelected" type="checkbox" ${selectedRows.has(data.id) ? 'checked' : ''}></input>`;
}},
{data: 'item', title: 'item'},
{data: 'cat', title: 'cat'}
]
});
//selection checkboxes click handler
$('#mytable').click('.markSelected', function(){
const selectedRowId = dataTable.row($(event.target).closest('tr')).data().id;
$(event.target).prop('checked') ? selectedRows.add(selectedRowId) : selectedRows.delete(selectedRowId);
});
//proceed to the next step with selected row id's
$('#nextStep').on('click', function(){
console.log([...selectedRows]);
});
<!doctype html>
<html>
<head>
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
<table id="mytable"></table>
<button id="nextStep">Next Step</button>
</body>
</html>
You can use datatable's Row selection feature to achieve what you are trying to do.
$(document).ready(function() {
var table = $('#userTable').DataTable();
$('#userTable tbody').on( 'click', 'tr', function () {
$(this).toggleClass('selected');
} );
$('#submitButtonId').click( function () {
alert( table.rows('.selected').data().length +' row(s) selected' );
// You can use table.rows('.selected').data() to get all the selected Data
} );
} );
Reference

Jquery datatables does not display the column headers

This is linked to the question here. However, my case is a bit different. I would like to implement the same datatables example from the other question which is here. As you can see you have to pass the column names to be able to initialize the table headers like below
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
The problem is that I would not know the header names beforehand as they will change. I've tried initializing the column names when I get the data from ajax like below using a 3rd variable (see where it says 'pay attention to this line' but this doesn't work.
//PAY ATTENTION TO THIS LINE
var columnsHeaders = [];
var ab = $('#dynamicScenarioTable').DataTable({
"bDestroy": true,
"dom": 'T<"clear">lfrtip',
"ajax": {
"type": "POST",
"url": "dynamicScenario.htm",
"data": tags,
"dataType": "json",
"dataSrc": function(json){
//PAY ATTENTION TO THIS LINE
columnsHeaders.push({"data": json.header });
return json.vals;
},
"error": function(exception)
{
displayMessageOnError();
}
},
//PAY ATTENTION TO THIS LINE
"columns": [columnsHeaders],
tableTools: tableDefaultS.tableTools
});
Any ideas?
You can add a data-source attribute to the TH tags that are built on your table header. You can then have jQuery read those and construct the array to send into the DataTable constructor.
<tr>
<th data-source="name">Name</th>
<th data-source="position">Postion</th>
<th data-source="start_date">Start Date</th>
</tr>
Then in your JavaScript do something like this to construct the array
var columnsHeaders = [];
$("#dynamicScenarioTable thead th").each(function() {
colmnsHeaders.push(
{
data : $(this).data("source")
}
);
});
// construct your DataTable after this

Create table if data from ajax not empty

First I have HTML:
<div class="showTable" style="display: none;">
<table id="example" class="table table-responsitive" cellspacing="0" width="100%" style="margin-top:30px;">
<thead>
<tr>
<th>ID</th>
<th>Broj računa</th>
<th>Kupac</th>
<th>Datum izdavanja</th>
<th>Rok za plaćanje</th>
<th>Status</th>
<th></th>
</tr>
</thead>
</table>
</div>
<div class="showInfo" style="display: none">
</div>
After that I write JS:
$(document).ready(function() {
drawVisualization();
});
function drawVisualization() {
console.log('proba');
$.ajax({
url: "getracuni.php",
type: "POST",
async: true,
dataType: "html",
success: function(json) {
console.log(json);
if (!json.data){
json.data = [];
$('.showInfo').show();
} else {
var podaci = json.data;
$('.showTable').show();
showTable(podaci);
}
},
error: function(data) {
console.log(data);
}
});
};
so here I try to make this:
1. IF data from ajax is not empty then to create datatable with function showTable(podaci);
2. IF data from ajax is empty then just want to show div class 'showInfo'.
My showTable(podaci) function is:
function showTable(podaci) {
$('#example').dataTable({
data: podaci.data,
paging: false,
"dom":' <"search"f><"top"l>rt<"bottom"ip><"clear">',
bfilter: false,
"oLanguage": {
"sInfo": 'Ukupno _END_ računa.',
"sInfoEmpty": 'Nema podataka o računima',
"sEmptyTable": "Nemate račune, dodajte klikom na dugme ispod.",
},
// end ,
"columns": [{
"data": "ID"
}, {
"data": "br"
},
{
"data": "kupac"
},
{
"data": "datum"
},
{
"data": "rok"
},
{
"data": "status"
},
{
"data": "akcija"
}
],
"columnDefs": [
{
"targets": 6,
"data": "akcija",
"render": function(data, type, full, meta) {
// return data;
return '<div style="float:right;"><div class="btn-group">Izmeni <span class="caret"></span><ul class="dropdown-menu"><li>Izmeni</li><li>Pošalji</li><li>Opomeni</li><li>Plaćeno</li><li>Stoniraj</li><li>Kopiraj</li><li>Obriši</li></ul></div> <i data-toggle="modal" data-target="#delete" class="fa fa-times"></i></div>';
}
},
{
"targets": 0,
"visible":false
}
]
});
}
Also I get data from ajax in this JSON format:
{"data":[{"ID":1,"br":"1-2015","kupac":"ADAkolor","datum":"2015-05-19","rok":"2015-05-21","status":"placeno"},{"ID":2,"br":"2-2015","kupac":"Milenk","datum":"2015-05-27","rok":"2015-05-28","status":""}]}
I think that I write everything fine but when I try to run this code I just get blank screen. SO anything wont to show there...
Change your condition
if (!json.data) to if (json.data!=null)

JS dataTable plugin: handling json format other than standard datatable format

I am new to Datatables and trying to figure out this problem.
I have a server which oupts json in certain format(see below).I cant change that on server side.
**Note: I am using link http://www.json-generator.com/j/cftupHnpbC?indent=4 to emulate my server response just for checking.
I have 2 problems
Since My json response doesn't have aaData: thing required by dataTable, I cant seem to initiliaze it.
Even if I add aaData: by hand to json just for checking, dataTable cant count total records.How I can set that manually ?Since I cant change output from server.
JSBIN LINK:
http://live.datatables.net/dasuyaf/1/edit
HTML:
<table id="example" class="display" width="100%">
<thead>
<tr>
<th> </th>
<th>ID</th>
<th>Name</th>
<th>Text</th>
</tr>
</thead>
<tbody></tbody>
</table>
JS:
$(document).ready( function () {
var table = $('#example').dataTable({
"sAjaxSource": "http://www.json-generator.com/j/cftupHnpbC?indent=4",
"aoColumns": [{
"mData": "id",
"mRender": function (data, type, full) {
return '<input type="checkbox" name="chkids[]" value="' + data + '">';
}
}, {
"mData": "id"
}, {
"mData": "name"
}, {
"mData": "text"
}],
"bProcessing": true,
"bServerSide": true,
"sServerMethod": "GET",
"aoColumnDefs": [{
'bSortable': false,
'aTargets': [0]
}],
"fnDrawCallback": function (oSettings) {
console.log(this.fnSettings().fnRecordsTotal());
}
});
});
My Server Output: (cant change this)
[
{
"text": "Some text",
"name": "somedata",
"id": "89"
},
{
"text": "Some text",
"name": "somedata",
"id": "2"
},
{
"text": "Some text",
"name": "somedata",
"id": "12"
}
]
I suppose you could just request that JSON yourself, make an object out of it and pass it to your dataTable.
var aaData;
var table;
$(document).ready( function () {
$.ajax({
url: 'http://www.json-generator.com/j/cftupHnpbC?indent=4'
}).done(function(data){
aaData = data;
table = $('#example').dataTable({
"aaData": aaData,
"aoColumns": [{
"mData": "id",
"mRender": function (data, type, full) {
return '<input type="checkbox" name="chkids[]" value="' + data + '">';
}
}, {
"mData": "id"
}, {
"mData": "name"
}, {
"mData": "text"
}],
"bProcessing": true,
"aoColumnDefs": [{
'bSortable': false,
'aTargets': [0]
}],
"fnDrawCallback": function (oSettings) {
console.log(this.fnSettings().fnRecordsTotal());
}
});
});
} );
I removed bServerSide - I don't think there's any way you can make use of it if you can't change your server response. Also removed sServerMethod.

Categories