I have a table at which I am using jQuery Datatable. The table is being updated every 15 seconds with new data. I am using the latest version of Datatable.
How can I re-initialise the Datatable with new data without using clear method, which impacts the UI?
My Code:
jQuery.ajax({
type: 'POST',
url: /list_tasks',
data: ajaxData,
spinner: true,
success: function (response) {
$('#task_table').html(response.html)
if ( $.fn.DataTable.isDataTable('#task_table')) {
$('#task_table').DataTable().destroy();
}
var dataTable=$('#task_table').DataTable({
deferRender:true,
destroy: true,
scrollCollapse: true,
scroller: true,
scrollY: "200px",
bFilter:false,
bInfo: false,
bLengthChange:false,
initComplete: function(settings, json) {
},
fnDrawCallback:function(){
}
});
}
});
Instead of reinventing the wheel you should rely on dataTables built in ajax feature. If you do that, you can update the table very easy by using ajax.reload() :
var dataTable =$('#task_table').DataTable( {
ajax: {
url: '/list_tasks',
data: ajaxData
},
deferRender:true,
scrollCollapse: true,
scroller: true,
scrollY: "200px",
bFilter:false,
bInfo: false,
bLengthChange:false,
initComplete: function(settings, json) {
},
fnDrawCallback:function(){
}
});
setInterval(function() {
dataTable.ajax.reload()
}, 15000);
Update. You will never be able to prevent flickering or impact on the UI if you repeately inject and remove a table to the DOM, and instantiate it as a dataTable afterwards. Another approach could be to separate your table code in a different PHP script and place it inside an iframe :
<iframe src="table.php" id="table"></iframe>
Then update the iframe itself each 15 secs :
setInterval(function() {
$('#table')[0].contentWindow.location.reload(true);
}, 15000);
Related
I am trying to load the jQuery DataTable from an AJAX call as in the code below. However I need to know if there is a callback for the DataTable to check if the AJAX call returned successfully or failed before the table is loaded.
$(function() {
$('#data-table').DataTable({
destroy: true,
responsive: true,
serverSide: false,
autoWidth: false,
paging: true,
filter: true,
searching: true,
stateSave: true,
scrollX: true,
lengthMenu: [5, 10, 25, 50, 75, 100],
ajax: {
url: 'https://jsonplaceholder.typicode.com/todos',
type: 'GET',
dataSrc: ''
},
columns: [{
title: 'Zone',
data: 'LastKnownZone',
}, {
title: 'HiƩrarchie Map',
data: 'MapInfo.mapHierarchyString',
}, {
title: 'Addresse MAC',
data: 'macAddress',
}],
initComplete: function(json) {
let returned_data = json;
//..Do something with data returned
}
});
});
Appreciate any help.
Just adding something to #Fawaz Ibrahim's answer, it's also better to add error option in Ajax call in order to check if you face any error or problem , because in case of error, dataSrc callback won't run, so you won't have any successful returned data.
ajax: {
...
dataSrc: function ( receivedData ) {
console.log('The data has arrived'); // Here you can know that the data has been received
return receivedData;
},
error: function (xhr, error, thrown) {
console.log('here you can track the error');
}
}
As it is mentioned on their official site:
For completeness of our Ajax loading discussion, it is worth stating
that at this time DataTables unfortunately does not support
configuration via Ajax. This is something that will be reviewed in
future
But you can use the idea of datasrc, like this:
$(function() {
$('#data-table').DataTable({
...
ajax: {
...
dataSrc: function ( receivedData ) {
console.log('The data has arrived'); // Here you can know that the data has been received
return receivedData;
}
},
...
});
});
I'm trying to add <tr/> tags dynamically to a DataTable, but I didn't find actual good documentation on how the "adding TR process" is supposed to work. I have this as my DataTables setup:
$("#Grid").DataTable({
stateSave: true,
fixedHeader: true,
rowReorder: true,
.
.
columnDefs: [
{ orderable: false, className: "seq-cell", targets: 0 },
{ orderable: false, targets: "_all" }
]
})
.on("row-reordered", function (e, diff, edit) {
for (var i = 0; i < diff.length; i++)
{
..
}
});
I'm getting the definition of the item in the grid from an MVC action method as an HTML string, via a jQuery AJAX statement:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
var $body = $("#Grid tbody");
$body.append(d);
}
});
The "d" parameter is the HTML for a row; I'm appending it to the body. That adds correctly and but doesn't have the row reorder functionality enabled then. What is the proper way to append to a DataTable, then re-enable whatever functionality?
Use row.add() API method to add a new row instead of appending to the table body.
If d contains string in the following format <tr>...</tr>, you could just use $("#Grid").DataTable().row.add($(d).get(0)) to add a new row.
For example:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
$("#Grid").DataTable().row.add($(d).get(0)).draw();
}
});
See this example for code and demonstration.
The best option is to use Datatables API's to add rows to the table. As indicated in the previous response you can use either row.add() or rows.add(). The data needs to be in a data structure that matches your Datatables data structure config, ie, arrays or objects.
However it looks like you are receiving HTML structured data and appending directly to the table. In this case Datatables is not aware of the added data. You will need destroy (destroy()) the Datatables table, append your data then re-init Datatables. For example:
$.ajax({
type: "post",
url: "AddItem",
data: $("#newitemform").find(":input[name]").serialize(),
success: function (d) {
$("#Grid").DataTable().destroy();
var $body = $("#Grid tbody");
$body.append(d);
$("#Grid").DataTable({
stateSave: true,
fixedHeader: true,
rowReorder: true,
.
.
columnDefs: [
{ orderable: false, className: "seq-cell", targets: 0 },
{ orderable: false, targets: "_all" }
]
})
}
});
I am working with jQuery datatable with state save: true having pagination with 10 records per page. I have 31 records, so on 4th page there is only 1 record.
If I am deleting this record it shows no record found on page, ideally it should move to previous page or first page.
Please help me fixing this.
below is the code
dataTable = $('.tab-pane.active').find('#' + table).DataTable({
"lengthMenu": [[10, 25, 50, 100, 250, 500, '-1'], [10, 25, 50, 100, 250, 500, 'All']],
"processing": true,
"serverSide": true,
"responsive": true,
"scrollX": true,
"autoWidth": false,
"stateSave": true,
"stateSaveParams": function (settings, data) {
data.search.search = "";
},
"aoColumnDefs": [
{'bSortable': false, 'aTargets': [-2, -1]}
],
"initComplete": function ( ) {
$('.overlay').fadeOut();
},
"ajax": {
url: MY_URL,
type: "POST", // method , by default get
data: postObj
}
}).on('preXhr.dt', function (e, settings, data) {
if (settings.jqXHR)
settings.jqXHR.abort();
});
And action to delete is
academic_master.deleteMaster = function (currentClick)
{
var id = currentClick.attr('data-id');
var delete_id = currentClick.attr('delete-id');
var action = currentClick.attr('action');
var data = 'id=' + id + '&delete_id=' + delete_id + '&action=' + action;
$.ajax({
type: 'POST',
url: DELETE_URL,
data: data,
datatype: 'json',
async: false,
success: function (response) {
if (response != '-1' && response != '-20')
{
dataTable.ajax.reload(null, false);
}
});
}
I used to call this above function to delete record, and on success it reloads the table but on same page either if there is no record on that page.
As per the documentation, pagination doesn't reset in your approach.
// user paging is not reset on reload
dataTable.ajax.reload( null, false );
if you use below the line, your pagination would reset. But it would not move to the previous page.
dataTable.ajax.reload();
Suggestion: You would be able to improve the functionality/usability if you follow this approach
https://datatables.net/examples/api/select_single_row.html
//create data table object
var dataTable = $('#tableView').DataTable();
//add class "selected" to the row selected
dataTable.$('tr.selected').addClass('selected');
//I have a button in one of the td of the row. onclicking the button, I assign the class "selected" to the row
$(ths).parents('tr').addClass('selected');
//to delete or remove the row, call the below code
dataTable.row('.selected').remove().draw( false );
I work with jqGrid on my project and I have a problem that can not seem to solve even after reading the forums on the same subject.
I would reload the grid when a user clicks a button after selecting a date. I want the data recharge correspodent to choose the date.
I use the following code:
var loadfacture = false;
$('#btn-facture').click(function(){
if(!loadfacture){
$("#factures").jqGrid({
url:'loadfactureencours.json',
datatype: "json",
autowidth: true,
height:250,
colNames:['#','Numero','Date', 'Client','Serveur','Prix Total','Avance','Regler','Notes'],
colModel:[
{name:'idfac',index:'idfac', width:45,align:"center"},
{name:'numfac',index:'numfac', width:80,align:"center"},
{name:'datefac',index:'datefac', width:150,align:"center"},
{name:'client',index:'client', width:145,align:"center"},
{name:'utilisateur',index:'utilisateur', width:125,align:"center"},
{name:'montant',index:'montant', width:70,align:"center"},
{name:'avance',index:'avance', width:60,align:"center"},
{name:'regler',index:'regler', width:50,align:"center"},
{name:'description',index:'description', width:150, sortable:false}
],
rowNum:10,
rowTotal: 2000,
rowList : [10,20,30,40,50,60],
loadonce:true,
mtype: "GET",
postData: {
day: function () {
return $('#daySelect').val();
}
},
rownumbers: false,
rownumWidth: 40,
gridview: true,
pager: '#paging',
sortname: 'idfac',
viewrecords: true,
sortorder: "desc",
caption: "",
ondblClickRow: function(rowid,iRow,iCol,e){
var rowData = jQuery(this).getRowData(rowid);
console.log(rowData);
window.location = "ecrancommandebar.html?num="+rowData.numfac;
}
});
$("#factures").jqGrid('navGrid','#paging',{del:false,add:false,edit:false});
loadfacture = true;
}else{
var grid = $("#factures");
grid.trigger("reloadGrid",[{current:true}]);
}
});
I built this piece of code by reading the forum on the same subject but the grid load the first time then when I click on the button after changing the date nothing happens.
What is wrong with you? Thank you for your feedback.
You use loadonce:true option which changes datatype from initial "json" to "local" after the first loading of the data from the server. It allows to support local sorting, paging and filtering of data. So you should understand that grid.trigger("reloadGrid",[{current:true}]); will just reload the data from previously saved previous response. So no reloading from the server will take place till you reset the value of datatype parameter to "json". In other words you should rewrite else part to about the following
...
} else {
$("#factures").jqGrid("setGridParam", {datatype: "json"})
.trigger("reloadGrid", [{current: true, page: 1}]);
}
You can try with this:
}else{
var grid = $("#factures");
$.ajax({
url: "loadfactureencours.json",
dataType: "json",
success: function(data){
grid.trigger("reloadGrid",[{current:true}]);
},
error: function(){}
});
}
I'm currently using datatables with ajax data and I want do adjust the column width.
So I found this function fnAdjustColumnSizing and I try to use it :
oTable = $('.datatable').dataTable( {
"sScrollX": "100%",
"sScrollXInner": "200%",
"bScrollCollapse": true,
"bDestroy" : true,
"sAjaxSource": "xhr.php",
"bFilter": false,
"bSort": false,
"bLengthChange": false,
"bPaginate": false,
"bInfo": false,
"fnServerData": function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": "webservice.php",
"data": 'id=' + quotation_id + '&customer_id=' + id + '&action=true',
"success": function(msg){
fnCallback(msg);
}
});
},
"fnInitComplete": function() {
this.fnAdjustColumnSizing();
}
});
The function haven't any effect but if I use it inside another event such like this :
$('#target').click(function() {
oTable.fnAdjustColumnSizing();
});
It work well, any idea ?
Have you tried doing
"fnInitComplete": function() {
oTable.fnAdjustColumnSizing();
}
Because i'm not sure that this points to table object
I find a solution by using a function inside the "success" callback of my ajax query :
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": "webservice.php",
"data": 'edit_quotation=true&action=true' + data,
"success": function(msg){
fnCallback(msg);
$('.overlay').hide();
adjustTable();
}
});
function adjustTable(){
oTable.fnAdjustColumnSizing();
}
And it work like a charm but I don't know why. Someone can explain ?
I had a similar problem in Internet Explorer 8 (not in Firefox): I was getting my headers unaligned with respect to the table body.
The table is initialized inside a 'modal' dialog (twitter bootstrap), AFTER it is shown.
Finally, to make it work with Internet Explorer 8, after creating the table I'm making this call:
var t = setTimeout(function () { myTableObject.fnAdjustColumnSizing(false);}, 300);
This refreshes the table without making another unnecessary Ajax call, but it waits 300 ms before doing it, to 'let internet explorer do its thing' before readjusting. If you set lower values i.e. 10 ms) this doesn't work.
I hope it helps,
Roger