Datatables fnAdjustColumnSizing doesn't work after ajax processing - javascript

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

Related

How to check if the ajax call for jQuery DataTable has returned data

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

Refresh Datatable with new data

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

Get to customize Jquery datatables GET request parameters that will be sent to the server

I'm using Jquery datatables and i would like when loading a page that it sends a customized GET request to the server not the default GEt request it sends. This is the JS section where it sends the request on load
$(document).ready(function() {
oTable=$('#ip_data').dataTable({
"bProcessing": true,
"bServerSide": true,
"bPaginate": true,
"bScrollCollpase": true,
"sScrollY": "200px",
"sAjaxSource": "/url"
});
});
where #ip_data is the html table id now with onload it works perfectly and this is the request headers it sends
http://domain.com/getdata?sEcho=1&iColumns=5&sColumns=%2C%2C%2C%2C&iDisplayStart=0&iDisplayLength=10&mDataProp_0=0&sSe arch_0=&bRegex_0=false&bSearchable_0=true&bSortable_0=true&mDataProp_1=1&sSearch_1=&bRegex_1=false&bSearchable_1=true&bSortable_1=true&mDataProp_2=2&sSearch_2=&bRegex_2=false&bSearchable_2=true&bSortable_2=true&mDataProp_3=3&sSearch_3=&bRegex_3=false&bSearchable_3=true&bSortable_3=true&mDataProp_4=4&sSearch_4=&bRegex_4=false&bSearchable_4=true&bSortable_4=true&sSearch=&bRegex=false&iSortCol_0=0&sSortDir_0=asc&iSortingCols=1&_=1402738395413
Now the server i'm working with is Rpc and it must get a method and params and id keys with the params part carrying the big chunk of data i.e to make the one shown above to something like this below which i have manually used and it has worked. the differences include
1 the addition of method=method
2 separation of method ,params and id by use of ';'
3 params={...} which is valid json
4 id=1
http://domain.com:5000/?method=datatables;params={"sEcho":"1", "iColumns":"5", "sColumns":",,,,", "iDisplayStart":"0", "iDisplayLength":"10", "mDataProp_0":"0", "sSearch_0":"", "bRegex_0":"false", "bSearchable_0":"true", "bSortable_0":"true", "mDataProp_1":"1", "sSearch_1":"", "bRegex_1":"false", "bSearchable_1":"true", "bSortable_1":"true", "mDataProp_2":"2", "sSearch_2":"", "bRegex_2":"false", "bSearchable_2":"true", "bSortable_2":"true", "mDataProp_3":"3", "sSearch_3":"", "bRegex_3":"false", "bSearchable_3":"true", "bSortable_3":"true", "mDataProp_4":"4", "sSearch_4":"", "bRegex_4":"false", "bSearchable_4":"true", "bSortable_4":"true", "sSearch":"", "bRegex":"false", "iSortCol_0":"0", "sSortDir_0":"asc", "iSortingCols":"1" };id=1
I know js and jquery can do the above but i haven't been succesful with jquery datatables since i can't get where to make a customized request to te server to what i want. Help apreciated.
In order to customize the request you need to add fnServerData in datatable initialization parameter with the function having customized ajax call as shown below. you can access the source, default data in aoData, callback function and settings, now you can add your own customized data like this,
aoData["MyCustomValue"] = 123;
or you can simply overwrite aoData object, its up to you
I have made a post request here.
$(document).ready(function() {
oTable=$('#ip_data').dataTable({
"bProcessing": true,
"bServerSide": true,
"bPaginate": true,
"bScrollCollpase": true,
"sScrollY": "200px",
"sAjaxSource": "/url",
"fnServerData": function (sSource, aoData, fnCallback, oSettings) {
aoData["MyCustomValue"] = 123;
oSettings.jqXHR = $.post(sSource, aoData, fnCallback, "json");
}
});
});
You should be able to use the following method to add id=1 and method=datatables.
var oTable = $('#ip_data').DataTable( {
"serverSide": true,
"ajax": {
"url": "/url",
"data": {
"method": "datatables",
"id": "1",
}
},
});
In everything I've read, nothing supports construction of query strings using semi-colon instead of ampersands as separators. For that you'd have to roll your own function, see the last example here https://datatables.net/reference/option/ajax.data
Also, passing raw json is a bit nasty. My advice would be to just let datatables automatically send the params. Datatables does this automagically if you are using the 'serverSide: true,' option.
in my case . i am sending with following code
$('#transactions_table').DataTable( {
"processing": true,
"bLengthChange": false,
"pageLength": 3,
"bFilter" : false,
"serverSide": true,
"headers": {'Content-Type':'application/x-www-form-urlencoded'},
"ajax":{
data:{currency:currency_code,date_from:date_from,date_to:date_to,is_zero_fee:is_zero_fee},
url :"http://ischool.pk",
type: "GET"
},"columns": [
{ "data": "transaction_id" },
{ "data": "currency" },
{ "data": "side" },
{ "data": "transaction_detail" },
{ "data": "insert_date" },
{ "data": "transaction_fee" },
{ "data": "amount" },
{ "data": "user_id" }
]
});

JqGrid don'i reload after click on the button

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

Concrete example for refreshing my jQuery dataTable?

I have the following jQuery dataTable:
$("#my-datatable").dataTable( {
"bProcessing" : true,
"bPaginate": false,
"bLengthChange": false,
"bFilter": true,
"bSort": false,
"bInfo": false,
"bAutoWidth": false,
"sAjaxSource" : "/myServer/getAllWidgets",
"sAjaxDataProp" : "",
"bDestroy" : true,
"fnServerData" : function(sSource, aoData, fnCallback) {
aoData.push({
"name" : "widgetName",
"value" : wName
});
request = $.ajax({
"dataType" : "json",
"type" : "GET",
"url" : sSource,
"data" : aoData,
"success" : fnCallback
});
},
"aoColumns" : [
{
"mDataProp" : "widgetType"
},
{
"mDataProp" : "widgetValue"
},
{
"mDataProp" : "widgetFactor"
}
]
});
This successfully hits my web server at /myServer/getAllWidgets and populates a 3-column dataTable (column headers are: Type, Value and Factor) on my UI. So far so good.
The problem is, the widgets MySQL table backing this dataTable changes frequently, and I would like to add a button to my UI such that when the user clicks the button, the dataTable is refreshed, meaning that /myServer/getAllWidgets runs again and displays the correct records/values to the user.
I've tried getting it to work for the past day, and everything I'm trying fails. Personally, I don't care how I get this "refresh" functionality, and don't care if the solution doesn't even involve fnReloadAjax at all (which is what I've been trying to get to work). I just need something that works:
<div id="refresh-button-div">
<input type="button" id="refreshButton" onclick="refreshData"/>
</div>
// In JS
$("#refreshButton").click(function() {
// ???
});
Thanks in advance.
You can use the fnDraw function to redraw the table. Try this:
var $dataTable = $("#my-datatable").dataTable({ /* setup */ });
$("#refreshButton").click(function() {
$dataTable.fnDraw();
});
Have a read of the fnDraw entry in the documentation.
I use the fnReloadAjax(); to reload table data from its ajax source
$("#refreshButton").click(function() {
oTable.fnReloadAjax();
});
just change
$("#my-datatable").dataTable( {...
into
oTable = $("#my-datatable").dataTable( {...//make oTable a global var in your js
You can take this datatables plugin source from here fnReloadAjax , drop it in some js file and include it in your page...

Categories