Scroller Extra w/ server-side processing
Scroller Extra w/ server-side processing
I've been using "infinite scrolling" for my program that can potentially return large data sets of 30,000+ using server side processing. Works great, other than I'd like a little better performance. From what I understand the Scroller extra is supposed to be a superior replacement for infinite scrolling. Is that true? On the demo, it loads a server-side dataset of 10,000 items very quickly, but I don't know how much processing goes into that ajax file for the demo. Mine will be dynamically generated, so there may be some extra overhead. If there is a perfomance boost with Scroller, I'll continue to look into that option. In my attempts to try it, I've been having a little trouble getting the program to work properly. I think I've disabled all the infinite scrolling option, so as to not have conflicts. I'm a little unclear if there are any changes that need to be made to my server-side script as far as limiting with Scroller vs infinite scrolling. What do I need to change when converting infinite scrolling to Scroller? The following is my datatable initialization (sorry, I have a lot of plugins and things):
[code]
oTable = $('#claimTable').dataTable({
"fnDrawCallback": function ( oSettings ) {
applyEditableText($('.editable_text'));
applyEditableSelect($('.editable_select'));
applyEditableDate($('.editable_date'));
if($('input[name="claim_id[]"]').length > 0)
{
$('.select_all').removeAttr('disabled');
$('.deselect_all').removeAttr('disabled');
$('.export').removeAttr('disabled');
}
else
{
$('.select_all').attr('disabled', 'disabled');
$('.deselect_all').attr('disabled', 'disabled');
$('.export').attr('disabled', 'disabled');
}
get_checked_count();
$('input[name="claim_id[]"]').click(function(){
get_checked_count();
});
},
"fnInitComplete": function(){
var oSettings = this.fnSettings();
$('tfoot input:visible').each(function(){
var index = $("tfoot input").index(this);
$(this).val(oSettings.aoPreSearchCols[index].sSearch);
if(this.value == "")
{
this.className = "search_init";
this.value = asInitVals[$("tfoot input").index(this)];
}
});
new FixedColumns(oTable);
},
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0 ] },
{ "sSortDataType": "dom-text", "aTargets": [ '_all' ] }
],
"bProcessing": false,
"bStateSave": false,
"bServerSide": true,
"sAjaxSource": "/members/get_claim_data.php",
/*"fnServerData": fnDataTablesPipeline,*/
"oScroller": {
"loadingIndicator": true
},
"sDom": 'rT<"clear">itS',
"oTableTools": {
"sSwfPath": "js/swf/copy_cvs_xls.swf",
"aButtons":[
{
"sExtends": "text",
"sButtonText": "Select All",
"fnClick": function(nButton, oConfig, nRow){
$('.checkbox').prop('checked', true);
get_checked_count();
},
"fnInit": function(nButton){
$(nButton).addClass('select_all');
}
},
{
"sExtends": "text",
"sButtonText": "Unselect All",
"fnClick": function(nButton, oConfig, nRow){
$('.checkbox').prop('checked', false);
get_checked_count();
},
"fnInit": function(nButton){
$(nButton).addClass('deselect_all');
}
},
{
"sExtends": "download",
"sButtonText": "Export",
"sUrl": "/members/get_claim_data.php?type=csv"
},
{
"sExtends": "text",
"sButtonText": "Duplicate Selected",
"fnClick": function(nButton, oConfig, nRow){
$('input:checked').each(function(){
row_copy_num = $(this).parent().find('.row_num').html();
var qty = prompt("How many times to copy row #" + row_copy_num + "?", "1");
qty = Number(qty);
if(qty > 0)
window.open('/members/copy_claim_rows.php?claim=' + $(this).val() + '&qty=' + qty, '_blank', 'width=800,height=400,resizable=1');
});
},
"fnInit": function(nButton){
$(nButton).addClass('copy');
}
},
{
"sExtends": "text",
"sButtonText": "Process Selected",
"fnClick": function(nButton, oConfig, nRow){
var claim_ids = $('input[name="claim_id[]"]:checked').serialize();
var row_nums = $('input[name="claim_id[]"]:checked').parent().find('input[name="row_num[]"]').serialize();
$('#error_section').html('');
$.ajax({
type: 'POST',
url: '/members/claims2.php',
data: { claim_ids: claim_ids, row_nums: row_nums },
dataType: "json",
success: function(data){
$('#error_section').append('
[code]
oTable = $('#claimTable').dataTable({
"fnDrawCallback": function ( oSettings ) {
applyEditableText($('.editable_text'));
applyEditableSelect($('.editable_select'));
applyEditableDate($('.editable_date'));
if($('input[name="claim_id[]"]').length > 0)
{
$('.select_all').removeAttr('disabled');
$('.deselect_all').removeAttr('disabled');
$('.export').removeAttr('disabled');
}
else
{
$('.select_all').attr('disabled', 'disabled');
$('.deselect_all').attr('disabled', 'disabled');
$('.export').attr('disabled', 'disabled');
}
get_checked_count();
$('input[name="claim_id[]"]').click(function(){
get_checked_count();
});
},
"fnInitComplete": function(){
var oSettings = this.fnSettings();
$('tfoot input:visible').each(function(){
var index = $("tfoot input").index(this);
$(this).val(oSettings.aoPreSearchCols[index].sSearch);
if(this.value == "")
{
this.className = "search_init";
this.value = asInitVals[$("tfoot input").index(this)];
}
});
new FixedColumns(oTable);
},
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0 ] },
{ "sSortDataType": "dom-text", "aTargets": [ '_all' ] }
],
"bProcessing": false,
"bStateSave": false,
"bServerSide": true,
"sAjaxSource": "/members/get_claim_data.php",
/*"fnServerData": fnDataTablesPipeline,*/
"oScroller": {
"loadingIndicator": true
},
"sDom": 'rT<"clear">itS',
"oTableTools": {
"sSwfPath": "js/swf/copy_cvs_xls.swf",
"aButtons":[
{
"sExtends": "text",
"sButtonText": "Select All",
"fnClick": function(nButton, oConfig, nRow){
$('.checkbox').prop('checked', true);
get_checked_count();
},
"fnInit": function(nButton){
$(nButton).addClass('select_all');
}
},
{
"sExtends": "text",
"sButtonText": "Unselect All",
"fnClick": function(nButton, oConfig, nRow){
$('.checkbox').prop('checked', false);
get_checked_count();
},
"fnInit": function(nButton){
$(nButton).addClass('deselect_all');
}
},
{
"sExtends": "download",
"sButtonText": "Export",
"sUrl": "/members/get_claim_data.php?type=csv"
},
{
"sExtends": "text",
"sButtonText": "Duplicate Selected",
"fnClick": function(nButton, oConfig, nRow){
$('input:checked').each(function(){
row_copy_num = $(this).parent().find('.row_num').html();
var qty = prompt("How many times to copy row #" + row_copy_num + "?", "1");
qty = Number(qty);
if(qty > 0)
window.open('/members/copy_claim_rows.php?claim=' + $(this).val() + '&qty=' + qty, '_blank', 'width=800,height=400,resizable=1');
});
},
"fnInit": function(nButton){
$(nButton).addClass('copy');
}
},
{
"sExtends": "text",
"sButtonText": "Process Selected",
"fnClick": function(nButton, oConfig, nRow){
var claim_ids = $('input[name="claim_id[]"]:checked').serialize();
var row_nums = $('input[name="claim_id[]"]:checked').parent().find('input[name="row_num[]"]').serialize();
$('#error_section').html('');
$.ajax({
type: 'POST',
url: '/members/claims2.php',
data: { claim_ids: claim_ids, row_nums: row_nums },
dataType: "json",
success: function(data){
$('#error_section').append('
This discussion has been closed.
Replies
Correct :-)
> On the demo, it loads a server-side dataset of 10,000 items very quickly, but I don't know how much processing goes into that ajax file for the demo.
Try using the Webkit Inspector tools - the Network tab for example will show much much time a server takes to respond.
> I'm a little unclear if there are any changes that need to be made to my server-side script as far as limiting with Scroller vs infinite scrolling.
In theory - no there should be no changes needed, other than to disable infinite scrolling and enable Scroller. Having said that, you are using FixedColumns which is not currently supported by Scroller (indeed, it isn't supported in infinite scrolling mode, but it might just work - I haven't actually tried that!).
Allan
I might have a dive into it myself soon, I need to fix both the left and right most columns of my table while using scroller...
http://www.mtncom.net/members/test.html
Is this how everything's supposed to perform? It just seems kinda flakey with how it displays the 1st column. Sometimes it removes it and refreshes properly, other times, it just leaves the column, then when it displays the data, it removes the first column.
I'm pretty sure this is the kind of stuff he meant by it not working correctly.
I'd forgotten about that (too much coding going on around here ;-) ). Yes, that looks like it probably does address the compatibility issue.
Personally I wouldn't use infinite scrolling in a project myself (with the sole exception of infinite data such as Twitter) - I'd always suggest Scroller over infinite scrolling. Indeed, I'm actively thinking of taking infinite scrolling out of DataTables. It will probably be deprecated in v1.10 and possibly removed in v1.11.
Allan
The real problem with infinite scrolling is that DataTabels doesn't really track the rows that have gone before - it appends more and more rows on each draw (basically a normal draw, but without doing a clear).
> With scroller, it's constantly refreshing the data displayed, so if they scroll, it loses its check
If you are using server-side processing, unfortunately yes that is the case. You would need to keep track of what is checked and recheck it on a draw callback. This is true of any DataTable which uses server-side processing.
Allan
Very likely not all row heights in your table are the same height. Scroller makes the assumption that all rows are the same height (it can't know the height or rows which aren't draw).
> Also, how it displays the data isn't very accurate (even on the demo)
Even in this demo: http://datatables.net/extras/scroller/ ? Seems to work as expected for me. What browser / OS are you using?
Allan