Server side processing - Checkbox not saving stage between pages
Server side processing - Checkbox not saving stage between pages
Hi All,
Im attempting to switch to server side processing bit have spent hours and hours trying to manage the state of my checkbox column between pages.
Any ideas where im going wrong? I have started with the example:
http://datatables.net/examples/server_side/select_rows.html
But that doesnt work as .live isnt supported anymore and it highlights the row not checks a checkbox.
Im using both fnDrawCallback and fnRowCallback.
The current code will save row id's into the array when you click them but when you switch between pages it looks like the fnRowCallback event doesnt get called at all when you switch back to page 1.
Eg. On page 1 click to go to page 2 (It will fire the rowcallback then and loop through elements on page 1)
You click to go back to page 1 and no rowcallback fires?
[code]
var oTable;
var gaiSelected = [];
$(document).ready(function() {
oTable = $('#overview_results').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": 'searchoverview_ajaxdatav3.php?runid='+qs('runid'),
"sPaginationType": "full_numbers",
"iDisplayLength": 50,
"bSortClasses": false,
"fnDrawCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$("input[name=rowchk]").click(function(event){
//Add to array
var iId = event.target.id;
if ( jQuery.inArray(iId, gaiSelected) == -1 )
{
gaiSelected[gaiSelected.length++] = iId;
}
else
{
gaiSelected = jQuery.grep(gaiSelected, function(value) {
return value != iId;
} );
}
console.log("Array: " + gaiSelected);
});
},
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var chkid = $("input[name=rowchk]");
chkid.each( function(index,element)
{
if (jQuery.inArray($(element).attr("id"), gaiSelected) != -1 )
{
console.log("Elements state of ID: " + $(element).attr("id") + " before row callback: "+$(element).prop("checked"));
$(element).prop('checked', true);
console.log("Elements state of ID: " + $(element).attr("id") + " after row callback: "+$(element).prop("checked"));
}
return nRow;
});
},
[/code]
I havent even got to "select all" functionality yet, Feeling like this could be days/weeks of work.
Any help would be much appreciated.
Thanks,
Matt
Im attempting to switch to server side processing bit have spent hours and hours trying to manage the state of my checkbox column between pages.
Any ideas where im going wrong? I have started with the example:
http://datatables.net/examples/server_side/select_rows.html
But that doesnt work as .live isnt supported anymore and it highlights the row not checks a checkbox.
Im using both fnDrawCallback and fnRowCallback.
The current code will save row id's into the array when you click them but when you switch between pages it looks like the fnRowCallback event doesnt get called at all when you switch back to page 1.
Eg. On page 1 click to go to page 2 (It will fire the rowcallback then and loop through elements on page 1)
You click to go back to page 1 and no rowcallback fires?
[code]
var oTable;
var gaiSelected = [];
$(document).ready(function() {
oTable = $('#overview_results').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": 'searchoverview_ajaxdatav3.php?runid='+qs('runid'),
"sPaginationType": "full_numbers",
"iDisplayLength": 50,
"bSortClasses": false,
"fnDrawCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$("input[name=rowchk]").click(function(event){
//Add to array
var iId = event.target.id;
if ( jQuery.inArray(iId, gaiSelected) == -1 )
{
gaiSelected[gaiSelected.length++] = iId;
}
else
{
gaiSelected = jQuery.grep(gaiSelected, function(value) {
return value != iId;
} );
}
console.log("Array: " + gaiSelected);
});
},
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var chkid = $("input[name=rowchk]");
chkid.each( function(index,element)
{
if (jQuery.inArray($(element).attr("id"), gaiSelected) != -1 )
{
console.log("Elements state of ID: " + $(element).attr("id") + " before row callback: "+$(element).prop("checked"));
$(element).prop('checked', true);
console.log("Elements state of ID: " + $(element).attr("id") + " after row callback: "+$(element).prop("checked"));
}
return nRow;
});
},
[/code]
I havent even got to "select all" functionality yet, Feeling like this could be days/weeks of work.
Any help would be much appreciated.
Thanks,
Matt
This discussion has been closed.
Replies
If you are doing it with server-side processing, very possibly! It is exceptionally difficult to do something such as select all when you are holding state at the client, but the server has the data. For example, lets say you select all, then page to another page - they will be automatically selected. Fine. Now deselect one - your 'select all' flag must be cleared at this point, so when you page again - are all other rows selected or not?
Another example is if you select all on the first page and then perform whatever action is needed (delete?). How would you know what the rows on the other pages are - you wouldn't.
This is the problem with mixing client-side processing (your row selection state) with server-side processing. Yes, simple checkboxes can have their state remembered, but fundamentally I would very strongly try to dissuade you from mixing the two. A few hours will be the easy part...
Personally, I'd either switch to client-side processing (Ajax loading with deferred rendering will cope with up to 50'000 rows - is that enough?), or use all server-side processing (scaling will be your issue there if you need select all options).
Allan
Great feedback. I can see exactly what you mean about mixing client / server side processing.
Im looking at tables with upto 200K rows. Im going to have to have a look at the server side option im afraid.
Starting to code now. Thinking about using a table with page name, value and session ID to maintain check state.
On page load ill clear the entries for that particular page/session id.
Thanks again for advice.
Matt
Either way, let us know how you get on.
Allan
OK.. I thought this could be a monsterous piece of work but i have a solution up and running.
In the interests of helping others out, Here are the key pieces:
1) MySQL table that i called "page_session"
I store "value", "session_id", "username"
2) Page structure
I clear all records from page_session on page load that match "username"
3) Datatables / javascript:
Push additional variables
[code]
aoData.push(
{ "name": "chk_add", "value": add_chk_id },
{ "name": "chk_del", "value": del_chk_id },
{ "name": "chk_all_add", "value": add_all_chk },
{ "name": "chk_all_del", "value": del_all_chk }
)
[/code]
Draw callback - Add click listener
[code]
"fnDrawCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$("input[name=rowchk]").click(function(event){
var iId = event.target.id;
var chkbox = $('#'+iId);
//Check if click was a check or a remove
if (chkbox.prop("checked"))
{
//Add to add variable thats passed as server function
add_chk_id = chkbox.val();
} else
{
del_chk_id = chkbox.val();
}
oTable.fnDraw(false);
add_chk_id = "";
del_chk_id = "";
});
[/code]
Column defs - Pass a hidden column that contains the id of checkbox or null if row doesnt have a value in page_session
[code]
"aoColumnDefs": [
{"aTargets": [ 0 ],
"mRender": function ( data, type, full ) {
var returndata;
if (full[7])
{
returndata = '';
} else
{
returndata = '';
}
return returndata;
[/code]
Have a checkall box in header with click event monitor
4) Server side processing script
Take the newly passed variables and either add to page_session or remove (both single or bulk updates)
Its now handling 13K rows with ease. Ill keep on testing as i scape upto the 200K mark.
Matt
Allan