Filtering ...

Filtering ...

mimicmimic Posts: 43Questions: 0Answers: 0
edited March 2009 in Bug reports
I am using fnRender to render a column from two data columns, one contains data I filter on (and I leave it visible, sortable and filterable) and the other contains HTML data with links for manipulating this data (and that column I hide, disable sorting and filtering). In fnRender I combine them into one column. The problem is that when then I want to filter on the first column it is filtering on rendered column content and not on the original data column. This is regression from at least 1.3.

(On 1.4.2.)

Replies

  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Hi mimic,

    This change was actually intentional (and as a result of your comments on fnRender ;-) ). The reason for the change in 1.4.2 was that filtering (I felt) should occur on the data that is visible to the end user (i.e. the rendered data), not some data that they cannot see and aren't aware of.

    Having said that, it is still possible to filter on data which cannot be seen, just have a hidden column which is filterable. Can you just change which column is filterable and which one isn't?

    Allan
  • mimicmimic Posts: 43Questions: 0Answers: 0
    I thought my comments about fnRender would only change the way data is displayed. I do not really see any real use case where there would be a need to filter on fnRendered data - if that is a case then you could change data in the table in the first place. So you are using fnRender just because you would like to change the way it is showed to user but that underlying data is different so that you can sort/filter on that. If you want both underlying and visible data to be the same then you change underlying data and you do not use fnRender. Of course developer should not misuse that to make visible data for sorting and filtering so different from real data to be unintuitive. But sometimes you need some controls and such in a column you do not want to be sorted and filtered on (and from context user knows that it is not controls by which table is sorted and filtered).

    The workaround is not really possible as I would like to do per-column filtering and sorting so I need to be able to sort and filter on columns which are visible (but which can have maybe something else displayed via fnRender).
  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    I see your point - what I can probably do is provide a switch for each column which will allow the developer to select if they want the rendered data to be filtered on or the original data.

    When I update getting 1.4 together I did wonder what the usage of fnRender would actually be since I figured that the information would be read from the DOM most of the time. Of course with the server-side processing and increased Ajax usage that is falling by the way side.

    The use case for filtering on the rendered data was such that the end user could filter on what was actually visible. This is a daft example but if you used fnRender to increase a number in a column by one, then when filtering you would expect to filter on what you can see. (ie. if there was an entry with "7" I wouldn't expect that to disappear when I typed "7" into the filter).

    Either way, this switch would allow the developer to choose. I'll have a look at this for the next release.

    Allan
  • mimicmimic Posts: 43Questions: 0Answers: 0
    Hm. With introduction of bUseRendered function fnUpdate does not really work as expected (or at least as I would expect). Initial table works - filtering and sorting is done on rendered or on original data, as specified by bUseRendered. But fnUpdate on a column with bUseRendered set to false does not call fnRender anymore. This does not really allow using data for sorting and filtering and display some transformation of this data through fnRender.

    My idea is something like I have described above/before. Table data which is sorted, filtered is read from initial table. Then if there is fnRender function defined for a column it is called when this column has to be displayed. If the bUseRendered is set to true the returning value of fnRender is stored back into table data. If it is false then fnRender is called every time this data has to be rendered (it can also be cached somewhere).
  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    I'm a complete donkey... That was my intention - I just got it wrong in the code. Here is the updated function (it should just drop into 1.4). This will will be in the next 1.5 beta.

    [code]
    /*
    * Function: fnUpdate
    * Purpose: Update a table cell or row
    * Returns: int: 0 okay, 1 error
    * Inputs: array string 'or' string:mData - data to update the cell/row with
    * int:iRow - the row (from aoData) to update
    * int:iColumn - the column to update
    * bool:bRedraw - redraw the table or not - default true
    */
    this.fnUpdate = function( mData, iRow, iColumn, bRedraw )
    {
    var oSettings = _fnSettingsFromNode( this[0] );
    var iVisibleColumn;
    var sDisplay;
    if ( typeof bRedraw == 'undefined' )
    {
    bRedraw = true;
    }

    if ( typeof mData != 'object' )
    {
    sDisplay = mData;
    oSettings.aoData[iRow]._aData[iColumn] = sDisplay;

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

    if ( oSettings.aoColumns[iColumn].bUseRendered )
    {
    oSettings.aoData[iRow]._aData[iColumn] = sDisplay;
    }
    }

    iVisibleColumn = _fnColumnIndexToVisible( oSettings, iColumn );
    if ( iVisibleColumn !== null )
    {
    oSettings.aoData[iRow].nTr.getElementsByTagName('td')[iVisibleColumn].innerHTML =
    sDisplay;
    }
    }
    else
    {
    if ( mData.length != oSettings.aoColumns.length )
    {
    alert( 'Warning: An array passed to fnUpdate must have the same number of columns as '+
    'the table in question - in this case '+oSettings.aoColumns.length );
    return 1;
    }

    for ( var i=0 ; i
  • mimicmimic Posts: 43Questions: 0Answers: 0
    Thanks, this works! :-)
This discussion has been closed.