fnRowCallback vs. aoColumns/fnRender
fnRowCallback vs. aoColumns/fnRender
zenbitz
Posts: 10Questions: 0Answers: 0
So I have some JSON tables stored on disk and I am displaying them in datatables. I am inflating some cells based on content (typically creating a link). The first way I did this I used fnRowCallback... and it mostly worked, although turns out I want to use bUseRendered: false... which lead me to doing this in aoColumns instead.
Just got me thinking (not necessarily for this project) - if you are inflating/bloating a cell, do you use fnRowCallback or aoColumns, or "depends".
Just got me thinking (not necessarily for this project) - if you are inflating/bloating a cell, do you use fnRowCallback or aoColumns, or "depends".
This discussion has been closed.
Replies
There are three ways of manipulating data for display in the table:
- fnRender .
- fnRowCallback / fnDrawCallback / fnCreatedCell / fnCreatedRow .
- mDataProp .
By far the most flexible is mDataProp as a function (which I plan to write a blog post about soon). fnRowCallback and friends are mainly used to manipulate the DOM (add event listeners, attributes to nodes etc) - you could use them to manipulate the display, but if you want to do that fnRender is probably the way to go ( bUseRendered is an option to extend fnRender's capabilities, but without doubt mDataProp as a function is what I would recommend over bUseRendered now - it does make the code a little bit more complex though, since you need to write a get/set function for the columns which you want to use it on.
So as I say, it depends a bit on what you want to do.
> aoColumnsDef / aoColumns
Again it depends. aoColumnDefs is a lot more flexible since you don't need to specify the exact number of columns, but at times it can be useful to do exactly that, when using aoColumns would make sense.
There are no hard and fast rules to either answer and the best and optimal method will depend upon the application that is required!
Allan
Not getting bUseRendered to work, but probably did something dopey.
Allan
[code]
var dtParams = {"bDeferRender":1,"bJQueryUI":"true","sAjaxSource":"\/tmp\/results\/regulome.762dcca774dad9f036e3c1856bedb47b019b7de2.raw.json","bProcessing":"true","bFilter":0,"aaSorting":[[2,"asc"],[0,"asc"]],"aoColumns":[{"sClass":"aligncenter","sTitle":"Coordinate (0-based)","sWidth":"14em"},{"sClass":"aligncenter","sTitle":"dbSNP ID"},{"sClass":"aligncenter","sTitle":"Regulome DB Score (click to see data)","sWidth":"12em"},{"sClass":"aligncenter","sTitle":"Other Resources","sWidth":"17em"}]};
// aoColumnDefs is added later
dtParams['aoColumnDefs'] = [
{ "fnRender": function ( oObj ) {
if (oObj.aData[2] == 7) {
return 'No Data';
} else {
var snp = oObj.aData[0].split(':');
return ''+oObj.aData[2]+'';
}
},
"bUseRendered": false,
"aTargets": [ 2 ]
},
{ "fnRender": function ( oObj ) {
var content = [];
_.each(externalURL, function(url,db) {
if (db == 'dbSNP' ) {
var rsid = oObj.aData[1];
if (rsid.match('^rs') ) content.push(''+db+'');
} else if (db != 'dbSNP') {
content.push(''+db+'');
}
});
return content.sort().join(" | ");
},
"aTargets": [ 3 ]
}
];
var table = $('#snp_analysis').dataTable(dtParams);
[/code]
The html inflating is working fine, but it's not sorting right at all... I took out the bDeferRender: 1 but that make no difference
"Raw" column to is just from the set of [ 7,6,5,4,3b, 3a, 2c,2b,2a, 1f,1e,1d,1c,1b,1a]
Sorting works fine in an older version (that did not support huge JSON tables, and the HTML rendering was not done via call back)
[code]
$('#snp_analysis').dataTable({"bDeferRender":1,"bJQueryUI":"true","aaData":[["chr11:5246957","rs33914668","2a<\/a>","UCSC<\/a> | ENSEMBL<\/a> | dbSNP<\/a>"],["chr11:5248049","rs35004220","4<\/a>","UCSC<\/a> | ENSEMBL<\/a> | dbSNP<\/a>"],["chr14:100741725","rs78077282","4<\/a>","UCSC<\/a> | ENSEMBL<\/a> | dbSNP<\/a>"],["chrX:53101683","rs7881236","2c<\/a>","UCSC<\/a> | ENSEMBL<\/a> | dbSNP<\/a>"]],"bFilter":0,"aaSorting":[[2,"asc"],[0,"asc"]],"aoColumns":[{"sClass":"aligncenter","sTitle":"Coordinate (0-based)","sWidth":"14em"},{"sClass":"aligncenter","sTitle":"dbSNP ID"},{"sClass":"aligncenter","sTitle":"<\/span><\/a>Regulome DB Score","sWidth":"14em"},{"sClass":"aligncenter","sTitle":"Other Resources","sWidth":"18em"}]});
[/code]
Allan
dev version (incorrect sorting) is http://regulome.stanford.edu:8080 - at least I hope that port is open to the outside world.
Click on any of the examples (highlighted above the input box). This is actually even the simpler version (the submit file uses sAjaxSource) but has the same sorting error.
Thanks for taking the time to look at this... at this point I hope it's a DT bug not some dumb hash key typo on my part.
Thanks,
Allan
What's really odd is that unless you have it backwards above, I would expect setting it to "string" would WORK, and "html" to not!
So, I guess you fixed it! Although sType: "html" is more than a little counter intuitive.
> BUT if I set both sType: html AND bUseRendered: false it throws an error: Object 4 has no method "replace" ("line" 30) in the minimized script.
Sounds like it will be trying to work on something that is a number or a primitive that is not a string. If you force the sType like this, then pass in non-string data, then this is expected (since indeed, replace is not a method of a string :-) ).
Allan
[code]
{ "fnRender": function ( oObj ) {
if (oObj.aData[2] == 7) {
return 'No Data';
} else {
var snp = oObj.aData[0].split(':');
return ''+oObj.aData[2]+'';
}
},
"bUseRendered": false,
"aTargets": [ 2 ]
}
[/code]
That does not appear to be present in the production version, and this is what is causing the type to be detected as "string". Because you have "bUseRendered": false, it is using the raw data for the type detection - which is 5, 4, "2a" etc, thus finding it as a string, rather than type html.
At this point a bug in DataTables 1.9.0 comes into play... When sorting non-string data on a string basis, DataTables 1.9.0 will automatically replace the data with an empty string, resulting in unexpected ordering. The fix is for the sorting to check for a 'toString' method for the data, and if present us that - that means that numeric data will be converted property to a string and then used as such.
I've just committed the fix for this issue and it is available in the 1.9.1.dev nightly ( http://datatables.net/download ). I've also added unit tests to make sure it doesn't happen again :-).
Thanks for flagging this up!!
Regards,
Allan
Sounds be okay now. I think DataTables should be flexible enough to cope with this!
> when I return a string that looks like html i,e '' does that get recognized as HTML or should I use some DOM manipulation instead?
If you use bUseRendered:false then the type detection will be based on the original data. If you use bUseRendered:true (or remove it, since true is the default) then the type detection will be based on what is returned.
Allan