Having problem with ColumnFilter (type select) and mRender

Having problem with ColumnFilter (type select) and mRender

scrubberscrubber Posts: 2Questions: 0Answers: 0
edited August 2012 in DataTables 1.9
Hello, I am new to using DataTables. Just want to say, I think it's a great plug-in because I can do pretty much everything so far with what our users want :)

I am currently using DataTables 1.9.3 and ColumnFilter 1.4.8. I am using the object based data structure, so I have something looking like [code]
{
"sEcho":1,
"aaData": [
{
"DT_RowClass": "class1 class2",
... ,
"childRecs" : [
{
"field1": "blah blah blah",
"field2": "3"
}
]
},
... ,
]
}
[/code]

And I am calling my table like so
[code]
oTable = $('#example').dataTable( {
"sAjaxSource": "where_my_data_is",
"fnServerData": function(sSource,aoData,fnCallback) {
.... //do stuff ...
},
"fnDrawCallback": function(oSettings) {
.... //do stuff ...
},
"aoColumns": [
{
"mData": "xyz",
},
... ,
{
"mData": "childRecs",
"mRender": "[, ].field2",
"bSortable": false,
"bVisible": false
}
]
} );

oTable.columnFilter( {
"bUseColVis": true,
"aoColumns": [
null,
... ,
{ sSelector:"#MyField2Filter", type:"select" }
]
} );
[/code]

I made the change in ColumnFilter, replacing
[code]
var aData = oTable.fnGetData(iRow);
var sValue = aData[iColumn];
[/code]
with
[code]
var sValue = oTable.fnGetData(iRow, iColumn);
[/code]

The problem I'm having is... if I do not supply the values for the select filter for "field2" of "childRecs" objects, the values are coming back "undefined". When it calls oTable.fnGetData(iRow, iColumn), it's ultimately invoking _fnGetCellData with an empty string for sSpecific. So I hacked the method a little, to pass along a sSpecific I give
[code]
var sValue = oTable.fnGetDraw(iRow, iColumn, 'display');
[/code]
and then it'll correctly grab the concatenated values. My final goal is to get a dynamic, unique list of values for "childRecs" objects' "field2".

Is this OK? Not sure if this is frowned upon or not to get it working. I feel I'm doing it wrong (?) I want to check my understanding, and see if I am doing anything wrong or could do anything better.

Replies

  • allanallan Posts: 64,757Questions: 1Answers: 10,716 Site admin
    > Is this OK?

    Its open source - do as you will ;-)

    However, I would say that when you call fnGetData, you generally expect to get back the original data source for the row / cell, which is what it is doing by passing in an empty string for the 'specific' type parameter. Possibly the fnGetData method should have an option to get data of a specific type?

    v.1.10 of DataTables is going to see a completely new API added (the old API will be proxied to this new one, and thus remain backwards compatible), so I will keep this in mind when creating the new API.

    The other option, and possibly the preferred one, would be that the column filter cal to get the data for the cell should be altered to use

    [code]
    _fnGetCellData( oSettings, iRow, iColumn, 'display' );
    [/code]

    This is a 'private' function for DataTables, but it is exposed in the `oApi` parameter of the DataTables instance, for use by plug-ins. That would probably be my current suggestion.

    Allan
  • benallfreebenallfree Posts: 7Questions: 0Answers: 0
    One caveat: 'display' can return any HTML, not just simple text suitable for an item.

    Is it better to first look for a new mRender mode named 'list'?

    [code]
    var sValue = oTable.oApi._fnGetCellData( oSettings, iRow, iColumn, 'list' ) ||
    oTable.oApi._fnGetCellData( oSettings, iRow, iColumn, 'display' );
    [/code]
  • allanallan Posts: 64,757Questions: 1Answers: 10,716 Site admin
    Yup - that sounds like a very good idea. Plug-ins can pass in a custom option into _fnGetCellData (TableTools could use 'tabletools', the column filter could use 'list' as you suggest etc). I would suggest to plug-in authors that they provide a fallback to 'display' should there be no data from a custom option - or throw an error, but that option is most certainly there.

    Allan
  • benallfreebenallfree Posts: 7Questions: 0Answers: 0
    What do you think about an official 'text' mode in _fnGetCellData? The proposed plugin code pops the "Requested unknown parameter" alert for columns that don't have mRender defined.

    'text' mode might have broad usefulness for plugin authors. Select lists, CSV exports, etc.
  • allanallan Posts: 64,757Questions: 1Answers: 10,716 Site admin
    That is absolutely worth considering. I'd like to keep the number of 'types' down as much as possible, otherwise mRender functions can become very unwieldy, but this certainly could prove useful.

    What I had been thinking about, was that plug-in authors could put DataTables in 'throw' error mode, and do a try/catch when trying to get their own parameter type. If an error is throw (unknown parameter) then fallback to 'display'. A flag should probably be used so only one attempt is made to see if the custom type is supported or not.

    Allan
  • benallfreebenallfree Posts: 7Questions: 0Answers: 0
    edited September 2012
    After working with mRender/mData for a while, I've started wondering if it might make more sense to eliminate mRender and decouple the mData modes, like this:

    [code]
    'mData': {
    'display': function(){ ... },
    'filter': function(){ ... },
    'set': function() { ... },
    }
    [/code]

    This approach would allow a user or plugin any number of custom render modes by simply adding a key to the hash. Selectively overriding existing modes would be easy too. The DataTables core could be configured to gracefully handle missing modes or throw errors.

    Two other useful features to consider, though I'm less sure of these:

    1. Global configuration

    [code]
    $('#example').dataTable( {
    'mData': {
    ... // global modes, supplied once
    }
    }
    [/code]

    2. Yielding to the core handler

    [code]
    'mData': {
    'text': function(...) {
    if(...) {
    // return something special for some conditions
    }
    return; // Will return undefined; same effect as if mode/handler was undefined.
    }
    [/code]
  • allanallan Posts: 64,757Questions: 1Answers: 10,716 Site admin
    I like that first approach. I had originally considered doing something like `mRenderSort` and `mDataSort` etc, but I think that would have ended up fairly horrific. However, having the ability to use mData / mRender as a global handler, or being able to specify options for each of the types as object properties is a really nice idea. It has worked well in Editor where specifying REST interfaces for Ajax, and I think it would work well here as well.

    Noted for 1.10 :-)

    Allan
This discussion has been closed.