Having problem with ColumnFilter (type select) and mRender
Having problem with ColumnFilter (type select) and mRender

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.
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.
This discussion has been closed.
Replies
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
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]
Allan
'text' mode might have broad usefulness for plugin authors. Select lists, CSV exports, etc.
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
[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]
Noted for 1.10 :-)
Allan