ColReorder - prevent fnServerData call
ColReorder - prevent fnServerData call
keeger
Posts: 9Questions: 1Answers: 0
I am using the ColReorder plugin 1.0.8 with DataTables 1.9.2
My configuration is Server side processing, and I've noticed that when I drag a column to a new place, the fnServerData callback is fired. This results in re-executing the server side search. This is unnecessary, as the data itself is not changing. I tried to listen to the fnReorderCallback but it fires after the fnServerData callback.
I am handling the column-reorder event now to fix this. I was wondering if this behavior could be removed from ColReorder. Data should only be fetched on sorting/filtering/page requests...
I have attached my code here, minus the aoColumnDefs. (it's a 29 column table) As you can see, one thing I do is restrict the amount of data going to the server. 29 columns generates around 3k in the GET body. ouch!
[code]
self.grid_completedForms = $('#searchGridTable').dataTable({
"aoColumnDefs" : null,//omitted for brevity
"bProcessing": false,
"bAutoWidth": true,
"bStateSave": true,
"oLanguage": {
"sEmptyTable": "No results found",
"sZeroRecords": "No records to display"
},
"fnDrawCallback": function (o) {
console.log('drawing grid');
},
"bScrollCollapse": true,
"bScrollAutoCss": false,
"fnServerData": function (sSource, aoData, fnCallback, oSettings) {
if (!self.firstLoad) {
if (self.skipDataFetch) {
var resp = $.parseJSON(oSettings.jqXHR.responseText);
resp.sEcho = oSettings.iDraw;
fnCallback(resp);
self.skipDataFetch = false;
return;
}
self.div_searchGridWrapper.css('visibility', 'visible');
self.isShowingGrid = true;
$(document).on('keydown', self.selectRowOnEnter);
//create a slimmed down version of aodata.
var dataToSend = [];
dataToSend.push({ "name": "sEcho", "value": oSettings.iDraw });
dataToSend.push({ "name": "iDisplayStart", "value": oSettings._iDisplayStart });
dataToSend.push({ "name": "iDisplayLength", "value": oSettings._iDisplayLength });
if (oSettings.oPreviousSearch)
dataToSend.push({ "name": "sSearch", "value": oSettings.oPreviousSearch.sSearch });
if (oSettings.aaSorting.length) {
dataToSend.push({ "name": "sortFieldName", "value": oSettings.aoColumns[oSettings.aaSorting[0][0]].mData });
dataToSend.push({ "name": "sSortDir_0", "value": oSettings.aaSorting[0][1] });
}
//our search terms.
dataToSend.push({ "name": "contractSearch", "value": self.vm_contract.Id() });
dataToSend.push({ "name": "facilitySearch", "value": self.vm_facility.FIDN() });
dataToSend.push({ "name": "incompleteForms", "value": self.input_checkIncompleteForms() });
oSettings.jqXHR = $.ajax({
cache: false,
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": dataToSend,
"success": function (a, b, c) {
//omitted private code
fnCallback(a, b, c);
},
"error": function () {
self.clearCompletedFormsGrid();
}
});
}
},
"sAjaxSource": "private_url/Search?",
"sDom": 'R<"H"lfr>tC<"bottom"ip>',
"aaSorting": [],
"bPaginate": true,
"sPaginationType": "full_numbers",
"sScrollY": "1px",
"sScrollX": "99%",
"iDisplayLength": 50,
"bJQueryUI": true,
"bServerSide": true
}).fnSetFilteringDelay().on({
'column-reorder': function() {
self.skipDataFetch = true;
},
'ColVis_show': function(a) {
//hack to fix the colvis positioning. unsure if there is some kind of
//interference with jquery theme or what. but this works :)
var menu = $('.ColVis_collection');
if (menu.length && !self.ColVisMenuPositioned) {
var nCVis = $('div.ColVis');
menu[0].style.left = nCVis.offset().left - menu.width() + "px";
menu[0].style.top = nCVis.offset().top + "px";
self.ColVisMenuPositioned = true;
}
}
});
[/code]
My configuration is Server side processing, and I've noticed that when I drag a column to a new place, the fnServerData callback is fired. This results in re-executing the server side search. This is unnecessary, as the data itself is not changing. I tried to listen to the fnReorderCallback but it fires after the fnServerData callback.
I am handling the column-reorder event now to fix this. I was wondering if this behavior could be removed from ColReorder. Data should only be fetched on sorting/filtering/page requests...
I have attached my code here, minus the aoColumnDefs. (it's a 29 column table) As you can see, one thing I do is restrict the amount of data going to the server. 29 columns generates around 3k in the GET body. ouch!
[code]
self.grid_completedForms = $('#searchGridTable').dataTable({
"aoColumnDefs" : null,//omitted for brevity
"bProcessing": false,
"bAutoWidth": true,
"bStateSave": true,
"oLanguage": {
"sEmptyTable": "No results found",
"sZeroRecords": "No records to display"
},
"fnDrawCallback": function (o) {
console.log('drawing grid');
},
"bScrollCollapse": true,
"bScrollAutoCss": false,
"fnServerData": function (sSource, aoData, fnCallback, oSettings) {
if (!self.firstLoad) {
if (self.skipDataFetch) {
var resp = $.parseJSON(oSettings.jqXHR.responseText);
resp.sEcho = oSettings.iDraw;
fnCallback(resp);
self.skipDataFetch = false;
return;
}
self.div_searchGridWrapper.css('visibility', 'visible');
self.isShowingGrid = true;
$(document).on('keydown', self.selectRowOnEnter);
//create a slimmed down version of aodata.
var dataToSend = [];
dataToSend.push({ "name": "sEcho", "value": oSettings.iDraw });
dataToSend.push({ "name": "iDisplayStart", "value": oSettings._iDisplayStart });
dataToSend.push({ "name": "iDisplayLength", "value": oSettings._iDisplayLength });
if (oSettings.oPreviousSearch)
dataToSend.push({ "name": "sSearch", "value": oSettings.oPreviousSearch.sSearch });
if (oSettings.aaSorting.length) {
dataToSend.push({ "name": "sortFieldName", "value": oSettings.aoColumns[oSettings.aaSorting[0][0]].mData });
dataToSend.push({ "name": "sSortDir_0", "value": oSettings.aaSorting[0][1] });
}
//our search terms.
dataToSend.push({ "name": "contractSearch", "value": self.vm_contract.Id() });
dataToSend.push({ "name": "facilitySearch", "value": self.vm_facility.FIDN() });
dataToSend.push({ "name": "incompleteForms", "value": self.input_checkIncompleteForms() });
oSettings.jqXHR = $.ajax({
cache: false,
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": dataToSend,
"success": function (a, b, c) {
//omitted private code
fnCallback(a, b, c);
},
"error": function () {
self.clearCompletedFormsGrid();
}
});
}
},
"sAjaxSource": "private_url/Search?",
"sDom": 'R<"H"lfr>tC<"bottom"ip>',
"aaSorting": [],
"bPaginate": true,
"sPaginationType": "full_numbers",
"sScrollY": "1px",
"sScrollX": "99%",
"iDisplayLength": 50,
"bJQueryUI": true,
"bServerSide": true
}).fnSetFilteringDelay().on({
'column-reorder': function() {
self.skipDataFetch = true;
},
'ColVis_show': function(a) {
//hack to fix the colvis positioning. unsure if there is some kind of
//interference with jquery theme or what. but this works :)
var menu = $('.ColVis_collection');
if (menu.length && !self.ColVisMenuPositioned) {
var nCVis = $('div.ColVis');
menu[0].style.left = nCVis.offset().left - menu.width() + "px";
menu[0].style.top = nCVis.offset().top + "px";
self.ColVisMenuPositioned = true;
}
}
});
[/code]
This discussion has been closed.
Replies
One qn - why do you have a first load check?
[code] if (!self.firstLoad) { [/code]
I could avoid all of that by doing a lazy load of the datatables object, but that type of thing I will do when I start optimizing. it works well and simply to use a boolean.