Why is rows() on a server-side DataTable not a function? - javascript

Why is rows() not a function on a server-side datatable?
The tables works fine beside that.
I have used rows() on five other client-side datatables before without any problems.
var tableComputerAndDevice = $('#tableComputerAndDevices').dataTable({
searching: true,
processing: true,
serverSide: true,
language: {
"processing": '<div style="background-color:#eee"> <span class="fa fa-spinner fa-pulse fa-5x"> </span> </div>'
},
ajax: {
url: url,
data: data,
type: "POST"
},
columns: [
{ "data": "checkbox", "searchable": false },
{ "data": "ComputerName", "searchable": true },
{ "data": "LastContact", "searchable": true }
]
});
var nodes = tableComputerAndDevice.rows('.selected').nodes();
console.log('nodes: ' + nodes);
Error: TypeError: tableComputerAndDevice.rows is not a function

Yes you judged it correctly. You need to change the dataTable to DataTable
Also to state that there is a difference between dataTable and DataTable.
The difference between the two is that the first will return a jQuery
object, while the second returns a DataTables API instance.

Change dataTable to DataTable. I answer my own question because I spent a hour with this bug, so I hope I can help others.
var tableComputerAndDevice = $('#tableComputerAndDevices').DataTable({

Related

Setting defaultContent globally across all datatables

I just updated my Datatable library from 1.10.12 to 1.11.4.
I use datatables extensively in my web app and after this upgrade I keep getting this error: https://datatables.net/manual/tech-notes/4
I understand that this warning basically wants me to set a "defaultContent": "" to my column definition.
The problem is that I would need to update over 200 tables in the webapp to fix the issue.
Is there a way to set this defaultContent:'' globally ?
I have attempted a few things, but the most recent was to extend the defaults in datatables.js with this code
$.extend(true, $.fn.dataTable.defaults, {
columnDefs: [
{
targets:'_all',
defaultContent: "",
},
]
});
The problem with that, I think, is that in my tables I do this:
let columnCount = 0
let table = $("#someTable").DataTable({
data: [],
paging: false,
responsive: true,
sDom: '<"top"B>rt<"bottom"i><"clear">',
columnDefs: [
{
// Order
render: function (data, type, row) {
return row.sortOrder // If this is null or undefined that error shows up
},
targets: columnCount++
defaultContent: '' // I DO NOT want to add this to every single column in every table.
}
],
});
Which overrides the previous definition of the columnDefs.
Similar to this post: datatables default render function for empty cells
So going back to what I am trying to accomplish:
Is there a way to set this defaultContent:'' globally once and have it applied to all columnDefs?
One solution would be to change:
let columnCount = 0
let table = $("#someTable").DataTable({
data: [],
paging: false,
responsive: true,
sDom: '<"top"B>rt<"bottom"i><"clear">',
columnDefs: [
{
// Order
render: function (data, type, row) {
return row.sortOrder // If this is null or undefined that error shows up
},
targets: columnCount++
defaultContent: '' // I DO NOT want to add this to every single column in every table.
}
],
});
to
let columnCount = 0
let table = $("#someTable").DataTable({
data: [],
paging: false,
responsive: true,
sDom: '<"top"B>rt<"bottom"i><"clear">',
columns: [ <----- NOTE THIS CHANGE and no defaultContent
{
// Order
render: function (data, type, row) {
return row.sortOrder
},
targets: columnCount++
}
],
});
and have
$.extend(true, $.fn.dataTable.defaults, {
columnDefs: [
{
targets:'_all',
defaultContent: "",
},
]
});
This would still involve changing part of the datatables but not every single column definition at least.

jQuery Datatables - add rows in a function that returns a Promise

I have a Single Page Application in which I am trying to populate a JQuery Datatable with the results of an AJAX call. The AJAX call returns a Promise.
The code where I define the table and call the AJAX function to populate it is shown below. The data never appears in the table.
if ( ! $.fn.dataTable.isDataTable( '#clients' ) ) {
table = $('#clients').DataTable({
"order": [],
retrieve: true,
"select": true,
select: {
style: 'single'
},
info: false,
lengthChange: false,
ordering: false,
"columns": [
{"data": "name"},
{"data": "dateofbirth"},
{
"data": "id",
"visible": false
}
]
});
clientMaintenance.getClientsForAccount()
.then(function (data) {
table.clear();
table.rows.add(data).draw();
});
I can see that data in getClientsForAccount.then is a JavaScript array, so I don't understand why the data does not appear in the table.
Consider using columnDefs instead of columns. You can find documentation on how to use columnDefshere.

Adding an element within a td in jQuery datatable

I have a js data table that I have implemented for pagination of data. It uses the jQuery data table. The data is being displayed correctly. However, I want to add an element within the first row of the data table.
Before I added it like this : <td>#Html.ActionLink(item.CarId, "Detail", "Cars", new { id = item.CarId},null)
<span class="dt-expand-btn js-expand-btn">+</span></td>
What I want to add within the td of the js is : <span class="dt-expand-btn js-expand-btn">+</span>
var carsDataTable = $('.js-cars-lists').DataTable({
"ajax": {
"url": "/Cars/CarsPagination",
"processing": true,
"serverSide": true,
"language": {
"paginate": {
"previous": '<i class="material-icons">chevron_left</i>',
"next": '<i class="material-icons">chevron_right</i>'
}
},
"order": [0, "asc"],
"type": "POST",
"datatype": "json"
},
"columns": [
{
"data": "CarId", "name": "CarId", "autowidth": true,
"render": function (data, type, row, meta) {
$(row.CarId).css('color', 'red');
return '' + row.CarId + '';
}
},
{ "data": "CarName", "name": "CarName", "autowidth": true },
Could someone please help me to achieve this ? Also, paginate icons are not appearing. Please help.
jQuery DataTable has a function of render it accepts 4 parameters function(data, type, row) which you can control the rendering of your rows. You can now check the rows of a table and add your element in it.
You can use columnDefs method and then render:
...
columnDefs: [{
"render": function(data, type) {
return '<span class="dt-expand-btn js-expand-btn">+</span>';
},
"targets": 0
}]
...
targets refers to the index of the table column (since you are referring to the 1st column) set it to 0

Make edit link on datatable with multiple column values and global search on single/custom column(s)

How to create an edit link with function having multiple parameter from the data columns returned from ajax.
I read about the render callback but it only gets one column value & I need 2.
I need something like the following pseudo code.
"columnDefs": [ {
"targets": [0,1],
"data": "0,1",
"render": function ( data, type, full, meta ) {
return ``
}
} ]
As I'm disabling global search on all column except one. I cannot use the above code that use targets property. I don't know how to achieve this, please guide.
Edit: Complete code
var datatable = $('#datatable').DataTable({
"ajax": "/get_data/",
"processing": true,
"serverSide": true,
"deferRender": true,
"columnDefs": [
{ "searchable": false, "targets": [ 0,2,3,4,5,6,7,8,9,10,11 ] }
]
});
You can access row data using full variable, for example full[0] or full[1].
However instead of generating links in HTML, I would retrieve row data in a click handler as shown below:
$('#example').DataTable({
"columnDefs": [
{
"targets": [0, 1],
"render": function ( data, type, full, meta ) {
return 'Edit';
}
}
],
// ... other options ...
});
$('#example').on('click', '.btn-edit', function(){
// Get row data
var data = $('#example').DataTable().row($(this).closest('tr')).data();
edit(data[0], data[1]);
});
I needed Edit link on first column, so I followed #Gyrocode.com answer and it works great.
I also wanted to use the global search for searching but only on one column. Datatable ColumnDef Documentation gave me the clue so I ended up doing as follows.
Here The complete code:
var datatable = $('#datatable').DataTable({
"ajax": "/get_data/",
"processing": true,
"serverSide": true,
"deferRender": true,
"columnDefs": [
{
"targets": 0,
"render": function ( data, type, full, meta ) {
return 'Edit';
}
},
{ targets: 1, searchable: true },
{ targets: '_all', searchable: false }
]
});

Datatables Jquery Ajax

I have an issue with the reinitialisation of my datatable. My code below works by pulling in a json from getOrderStatus.php and upon success of this puts all the json data into javascript variables and then from this i can set these variables to div tags and display the data i need on my webpage. However the Datatable cannot be reinititalised once the ajax loop runs and displays the following error message "DataTables warning: table id=mytable - Cannot reinitialise DataTable". I believe i need a way to kill the table and recreate it upon the ajax refresh however i cant seem to find a way to do this ?
$(document).ready(function ajaxLoop(){
$.ajax({
url: 'getOrderStatus.php', // Url of Php file to run sql
data: "",
dataType: 'json', //data format
success: function updateOrder(data) //on reciept of reply
{
var OrdersSubmitted = data.OrderStatus[0].SUBMITTED; //get Orders Submitted Count
var OrdersFulfilled = data.OrderStatus[0].FULFILLED; //get Orders Fulfilled count
var LastTransaction = data.LastTransaction[0]; //get Last Transaction
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#OrdersSubmitted').html(OrdersSubmitted);
$('#OrdersFulfilled').html(OrdersFulfilled); //Set output html divs
$('#mytable').dataTable({
"data": LastTransaction,
"aging": false,
"searching": false,
"columns": [
{ "title": "ORDER_ID" }, // <-- which values to use inside object
{ "title": "STATUS" },
{ "title": "ACC_NUMBER" },
{ "title": "SORT_CODE" }
]
});
setTimeout(ajaxLoop, 2000);
}
});
});
Did you try using "bDestroy": true.
$('#mytable').dataTable({
"data": LastTransaction,
"aging": false,
"searching": false,
"bDestroy": true,
"columns": [
{ "title": "ORDER_ID" }, // <-- which values to use inside object
{ "title": "STATUS" },
{ "title": "ACC_NUMBER" },
{ "title": "SORT_CODE" }
]
});
Another way is if you check if datatable is already init. on your table
var table = $('#mytable');
if ($.fn.DataTable.fnIsDataTable(table)) {
//It's already a datatable
//clear and destroy
table.dataTable().fnClearTable();
table.dataTable().fnDestroy();
}
**It seems your are using latest datatable version:**
then option should be destroy:true (aging should be changed to paging):
$('#mytable').dataTable({
"data": LastTransaction,
"paging": false,
"searching": false,
"destroy": true,
"columns": [
{ "title": "ORDER_ID" }, // <-- which values to use inside object
{ "title": "STATUS" },
{ "title": "ACC_NUMBER" },
{ "title": "SORT_CODE" }
]
});
and check on existing datatable would be:
if($.fn.DataTable.isDataTable("#myTable"))
{
$('#myTable').DataTable().clear().destroy();
}

Categories