fnDraw forgetting clickable icon state...
fnDraw forgetting clickable icon state...
nickschurch
Posts: 18Questions: 0Answers: 0
I'm hoping somone will be able to give me some pointers on solving an annoying small issue I'm having...
I have a datatable with rows that have an icon for expanding the row and displaying some additional information. The expanding row is done using slideUp, fnOpen and fnClose as per the example. The routine looks something like:
[code] function expandRow() {
/* this function defines what to do for this page when the expand icon is clicked */
$(".expandIcon",window.mainTableElement).live('click', function () {
var thisRow = this.parentNode.parentNode;
if ( this.src.match('collapse') )
{
/* This row is already open - close it */
this.src = "../media/images/expand.png";
this.title = "show more details"
$('div.innerDetails', $(thisRow).next()[0]).slideUp(function(){window.mainTable.fnClose(thisRow);});
} else {
/* Open this row */
this.src = "../media/images/collapse.png";
this.title = "close details panel"
var thisSubTable = window.mainTable.fnOpen(thisRow, 'Retrieving information from the database...', 'details');
$('div.innerDetails', thisSubTable).slideDown();
/* hit up the db with an ajax query */
getDetails(window.mainTable, thisRow, thisSubTable)
}
});
}
[/code]
This works beautifully and everything is hunkydory, right up until the point that the same page of the table gets redrawn with fnDraw (i.e., the user moves to page 2 in the table, and then comes back to page 1). You see the expand row icons are inserted dynamically into the table with fnRowCallback in their initial state. So, when the page gets redrawn, the open rows persist, but the row icon now changes back to the initial 'click to expand' state.
Is there a good way to make the table 'remember' the state of these icons? I guess I could hardcode the icon into the initial json that is returned to the ajax call, but that feels a bit unelegant. Maybe I could but the DT_rowId values for expanded rows into a global array and then check on fnRowCallback to see if the row exists in that array? but that also feels a bit hacky. Any better ideas?
I have a datatable with rows that have an icon for expanding the row and displaying some additional information. The expanding row is done using slideUp, fnOpen and fnClose as per the example. The routine looks something like:
[code] function expandRow() {
/* this function defines what to do for this page when the expand icon is clicked */
$(".expandIcon",window.mainTableElement).live('click', function () {
var thisRow = this.parentNode.parentNode;
if ( this.src.match('collapse') )
{
/* This row is already open - close it */
this.src = "../media/images/expand.png";
this.title = "show more details"
$('div.innerDetails', $(thisRow).next()[0]).slideUp(function(){window.mainTable.fnClose(thisRow);});
} else {
/* Open this row */
this.src = "../media/images/collapse.png";
this.title = "close details panel"
var thisSubTable = window.mainTable.fnOpen(thisRow, 'Retrieving information from the database...', 'details');
$('div.innerDetails', thisSubTable).slideDown();
/* hit up the db with an ajax query */
getDetails(window.mainTable, thisRow, thisSubTable)
}
});
}
[/code]
This works beautifully and everything is hunkydory, right up until the point that the same page of the table gets redrawn with fnDraw (i.e., the user moves to page 2 in the table, and then comes back to page 1). You see the expand row icons are inserted dynamically into the table with fnRowCallback in their initial state. So, when the page gets redrawn, the open rows persist, but the row icon now changes back to the initial 'click to expand' state.
Is there a good way to make the table 'remember' the state of these icons? I guess I could hardcode the icon into the initial json that is returned to the ajax call, but that feels a bit unelegant. Maybe I could but the DT_rowId values for expanded rows into a global array and then check on fnRowCallback to see if the row exists in that array? but that also feels a bit hacky. Any better ideas?
This discussion has been closed.
Replies
Using fnRowCallback or fnDrawCallback and a unique identifier is who I would approach this - something like this: http://datatables.net/release-datatables/examples/server_side/select_rows.html (this is row selection, but as you will see the rows remain selected regardless of paging). My open/close server-side example doesn't do this at the moment (note made to update it!).
Regards,
Allan
[code]
var tableDefaults = {
"sScrollY": "600px",
"bInfo": true,
"bLengthChange": true,
"iDisplayLength": 50,
"aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
"bProcessing": true,
"bsort": true,
"bJQueryUI": false,
"bDeferRender": true,
"bStateSave":true,
"sDom": '<"#showRows"l><"#searchBox"f><"#mainTable"rt><"#tableInfo"i><"#tablePagination"p>',
"oTableTools": {
"sSwfPath": "http://pathtomystuff/static/swf/copy_cvs_xls_pdf.swf"
},
"aaSorting": [[1, 'asc']],
"sPaginationType": "full_numbers",
"oLanguage": {
"sProcessing": ' Retrieving information from the database...',
"sLoadingRecords": ""
}
}
[/code]
Could it be that bDeferRender is forcing a re-draw of each row as I switch between pagination pages?
I do force a table redraw with fnDraw after a custom filter is changed, but I don't think thats the problem, because the issue happend just switching pagination pages.
lol - scratch my last post then :-)
> Could it be that bDeferRender is forcing a re-draw of each row as I switch between pagination pages?
No - bDeferRender will leave rows alone once they have been created, rather than burning clock cycles with creating the rows again (and also losing DOM information as I was talking about earlier).
How are you putting the images into the table? Is it part of the DOM source (are you using DOM sourced data, or Ajax source or something else)?
Allan
[code]
experimentTableData["fnRowCallback"] = function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var rowCells = $("td",nRow);
rowCells[0].innerHTML = '';
return nRow;
}
[/code]
The data for the table are sourced from are sourced from an ajax query using the sAjaxSource property of the datatable.
Originally I wanted it to dynamically insert a new column to the table, but that turns out to be a bit tricky, so instead the json returned from the Ajax call just contains an empty column at the start that I can do what I want with. In this case, it adds an image.
I tried server-side processing but the two-second delay in hitting the database each time I change a filtering slider was just too long compared to loading all the data into the table to begin with (which incurs a load delay) and doing the filtering client-side.
So there are a couple of options:
1. Use fnCreatedRow callback, which is much like fnRowCallback, but will only be called once.
2. Use sDefaultContent for the column to set your image.
Regards,
Allan
Will fnCreatedRow add the image to all the rows in the table, even if they are not drawn? I.e., if I have a table with 3000 rows, but the filtering removes 200 of them, will it still spend time adding the image to each of the excluded rows?
sDefaultContent works nicely though!