Switching fnRowCallback to fnRender -- not understanding fnRender
Switching fnRowCallback to fnRender -- not understanding fnRender
Hey all,
I had a relatively heavy function in fnRowCallback that would take information from other "source" columns-- some hidden, some not-- and then modify a target row.
As a simplified example, let's imagine that I had only 3 rows: a product name, a product type, and a link to more information externally:
[code]
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var productType = aData[1];
var productLink = aData[2];
var tdObject = $('td:eq(0)', nRow); // the visible TD that gets modified
tdObject.addClass(productType); // product type becomes CSS class
tdObject.addClass('clickable').click(function() {
window.open(productLink, 'Some Title', 'width=1000, height=700');
}
}
[/code]
My understanding from another thread is that I might be doing this inefficiently... perhaps fnRender is the way to go. But my understanding is that fnRender is really only used to modify the data itself. So for example, instead of binding a click to the TD element, I could modify the data to have an anchor tag:
[code]
"fnRender": function (oObj) {
var productLink = aData[2];
return ''+oObj.aData[0]+'';
}
[/code]
I would prefer to make the whole TD clickable, but in the interest of performance I could be convinced to make the tradeoff. However, the classes do need to be added to the TD. The real question is: am I barking up the wrong tree for fnRender? Am I doing it right all along and am after a red herring?
The sample code for fnRender uses aData[x], but I can't find any sample code showing how I might use iDataRow and iDataColumn in a meaningful way. Using fnRender, the candidate for modification is a piece of data (string, typically) rather than an object; so I don't think I can do anything with .parent() to apply the classes. Or can I?
Cheers,
Greg
I had a relatively heavy function in fnRowCallback that would take information from other "source" columns-- some hidden, some not-- and then modify a target row.
As a simplified example, let's imagine that I had only 3 rows: a product name, a product type, and a link to more information externally:
[code]
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var productType = aData[1];
var productLink = aData[2];
var tdObject = $('td:eq(0)', nRow); // the visible TD that gets modified
tdObject.addClass(productType); // product type becomes CSS class
tdObject.addClass('clickable').click(function() {
window.open(productLink, 'Some Title', 'width=1000, height=700');
}
}
[/code]
My understanding from another thread is that I might be doing this inefficiently... perhaps fnRender is the way to go. But my understanding is that fnRender is really only used to modify the data itself. So for example, instead of binding a click to the TD element, I could modify the data to have an anchor tag:
[code]
"fnRender": function (oObj) {
var productLink = aData[2];
return ''+oObj.aData[0]+'';
}
[/code]
I would prefer to make the whole TD clickable, but in the interest of performance I could be convinced to make the tradeoff. However, the classes do need to be added to the TD. The real question is: am I barking up the wrong tree for fnRender? Am I doing it right all along and am after a red herring?
The sample code for fnRender uses aData[x], but I can't find any sample code showing how I might use iDataRow and iDataColumn in a meaningful way. Using fnRender, the candidate for modification is a piece of data (string, typically) rather than an object; so I don't think I can do anything with .parent() to apply the classes. Or can I?
Cheers,
Greg
This discussion has been closed.
Replies
I think you basically have the correct understanding here - fnRender is string manipulation of the data. This can be useful for presentation of the data bring different from the source (hence the 'render' name), and also possibly used for altering the sorting and filtering results.
However - it is not suitable for adding event handlers since you don't have access to the DOM element at the time fnRender is called (particularly in 1.8 if using deferred rendering!).
I would say that fnRender is the right thing to use for string modification, particularly if you want the sort and filter to be affected (although bUseRendered:false can used to override that) - while fnRowCallback / fnDrawCallback can be used to add event handlers. They can also be used to effectively 'post process' the DOM. The node is on the page when those functions are called (although they are called so fast any manipulation you do with them will be seen immediately).
What I would tend to recommend, rather than adding event handlers with the callback functions is to use a live event. More memory efficient for this kind of thing and you don't need to rebind them all the time.
iDataColumn - useful for when you have the same rendering function applied to multiple columns (using aoColumDefs)
iDataRow - unlikely to be useful in fairness - although possibly if you want to access the internal data store...
Hope this helps!
Allan
I'm actually not sure why I provided the sample code I did; in another version of the same file I'm already doing something similar to your on-the-money suggestion of using .live. In my case, however, I'm using .delegate, which is purported to be more efficient than .live.
You certainly cleared up my main concern, though!
Greg