fnRender overwrites the original value

fnRender overwrites the original value

tbtb Posts: 2Questions: 0Answers: 0
edited April 2009 in Bug reports
Hello All,

Following problem I found:

The custom renderer on column 'a' overwrites the original value of this column (in aoData). After that it is not possible anymore to use custom renderer on column 'b' and reference there the original value of column 'a'. Assumption here is that column 'b' follows the column 'a';

**** Test case ****
Column 'a' (indexed with 0) contains text indicating the object type (eg. 'entity')
Column 'b' (indexed with 1) contains text/value of object's id (eg. 10)
Renderer on the first column renders an image instead of text.

JS code:

"aoColumns": [
{ "sWidth": "10px",
"bSearchable": false,
"bSortable": false,
"fnRender": function ( oObj ) {
var icon = "";
if (oObj.aData[0] == 'entity') {
icon = 'images/tree/entity_basic.gif'
} else if (oObj.aData[0] == 'report') {
icon = 'images/tree/report.gif'
} else if (oObj.aData[0] == 'workflow') {
icon = 'images/tree/workflow.gif'
return '';
{ "fnRender": function ( oObj ) {
return oObj.aData[0] + ':' + return oObj.aData[1];

The second rendered as a value of oObj.aData[0] gets the image tag instead of the original value.

**** In jquery.dataTables.js ****

if ( oSettings.aoColumns[iColumn].fnRender !== null )
sRendered = oSettings.aoColumns[iColumn].fnRender( {
"iDataRow": iRow,
"iDataColumn": iColumn,
"aData": oSettings.aoData[iRow]._aData
} );
oSettings.aoData[iRow]._aData[iColumn] = sRendered;

The aoData on given position gets overwritten by the result of the custom fnRender function.

My proposal is to introduce a 'shadow' version of the aData holder (eg. aOrgData) which gets initialized with the same values as aData and then make the same operations on both of them (add, remove, etc.) or refactoring of the aData by introducing there additional object (for each cell) with two fields: value & displayValue.

The workaround I use at the moment is based on hidden columns which are used by renderers, so they do not relay on columns which get rendered with custom renderers :-) Everything works OK, but solution is not really nice.



  • allanallan Posts: 58,914Questions: 1Answers: 9,485 Site admin
    Hi Tomasz,

    You can actually do more or less what you suggest already by making use of the bUseRendered property ( http://datatables.net/usage#bUseRendered ). If you set this to false (it is default true) for your rendered column, then the original data will be left in aoData for sorting and filtering, which the rendered view will be displayed for the end user.

    Hope this helps,
  • tbtb Posts: 2Questions: 0Answers: 0
    Hi Allan,

    Cool, thanks a lot. I will give a try.

    Anyway, I think it would make a sense to give a possibility to access the original and rendered value depending on the scenario. Not that the column itself 'decides' whether to keep the original value or rendered one but that the requesting part decides about that what it wants to get - something in this style: oObj.aData[0].value and oObj.aData[0].renderedValue.

    Best regards,
  • allanallan Posts: 58,914Questions: 1Answers: 9,485 Site admin
    It certainly is an option which I am open to implementing. The only downside is the increased amount of storage memory it will take to do this. Food for though though :-)

  • themitchythemitchy Posts: 8Questions: 0Answers: 0
    I'm glad there's a workaround (sort of) but I can already think of some situations where I'm going to want to sort on the rendered value.

    I'm imagining a column of customer IDs which get rendered as customer names. I want to sort by the customer name but then I lose access to the ID.
  • allanallan Posts: 58,914Questions: 1Answers: 9,485 Site admin
    One option is to have the text in the TD something like this:


    Then use a plug-in like this http://datatables.net/plug-ins/sorting#hidden_title . Or you can do:


    There are a number of options.

This discussion has been closed.