aoColumnDefs, fnRender, $.getJSON combo
aoColumnDefs, fnRender, $.getJSON combo
A little at a time (I'm just getting started with datatables) I've created a working sample of a datatable which pulls JSON data from a text file (I'll eventually move it to server side processing) and displays it properly on the web page. When I try to take it to the next step by adding fnRender functions to the aoColumnDefs in the text file the table doesn't display. There is no javascript error.
Here's my working jquery followed by my working JSON text:
$(document).ready(function() {
$('#dynamic').html('');
$.getJSON("JSONTest.txt", function(data) {
$('#example').dataTable({
"aaSorting": [[0, "desc"]],
"aaData": data.aaData,
"aoColumns": data.aoColumns,
"sScrollX": "100%",
"sScrollXInner": "150%",
"bScrollCollapse": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] },
etc...
{
"fnRender": function(oObj) {
var AccountVal = oObj.aData[2];
var AccountSplit = AccountVal.split(/\|/);
var AccountLast = AccountSplit[AccountSplit.length - 1];
if (AccountLast.length > 26) {
AccountLast = AccountLast.substring(0, 25) + '...';
}
return '' + AccountLast + '';
},
"aTargets": [2]
},
{
"fnRender": function(oObj) {
return '' + oObj.aData[0] + '';
},
"aTargets": [0]
},
{
"fnRender": function(oObj) {
var NoteVal = oObj.aData[12];
if (NoteVal.length > 10) NoteVal = NoteVal.substring(0, 7) + '...';
return '' + NoteVal + '';
},
"aTargets": [12]
}
]
});
});
});
The working JSON text (contents of JSONTest.txt):
{
"sEcho": 3,
"iTotalRecords": 16,
"iTotalDisplayRecords": 10,
"aaData": [
["229889", "2010 Nov 2", "Account Value", "2010", " ", "SO", "SO", "", "$9,293,387,000.00", "F9V", "B5", "t", "blah blah bla some notes n' stuff"],
["229888", "2010 Nov 2", "Account Value", "2010", " ", " ", " ", "", "$38,000.00", "F9V", " ", "", ""],
["229887", "2010 Nov 2", "Account Value", "2010", " ", " ", " ", "", "$0.00", "F9V", " ", "", ""],
["229889", "2010 Nov 2", "Account Value", "2010", " ", "SO", "SO", "", "$9,293,387,000.00", "F9V", "B5", "t", "blah blah bla some notes n' stuff"]
],
"aoColumns": [
{ "sTitle": "ID" },
{ "sTitle": "Field1" },
{ "sTitle": "Field2" },
{ "sTitle": "Field3" },
etc...
],
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] },
etc...
]
}
Now, if I append a simple fnRender to the aoColumnDefs in the JSON text the failure occurs. It fails even if I set aoColumnDefs in my original jQuery instead of setting it from the JSON text.
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
etc...
{
"fnRender": function(oObj) {
etc... }
]
Thanks for your help.
Here's my working jquery followed by my working JSON text:
$(document).ready(function() {
$('#dynamic').html('');
$.getJSON("JSONTest.txt", function(data) {
$('#example').dataTable({
"aaSorting": [[0, "desc"]],
"aaData": data.aaData,
"aoColumns": data.aoColumns,
"sScrollX": "100%",
"sScrollXInner": "150%",
"bScrollCollapse": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] },
etc...
{
"fnRender": function(oObj) {
var AccountVal = oObj.aData[2];
var AccountSplit = AccountVal.split(/\|/);
var AccountLast = AccountSplit[AccountSplit.length - 1];
if (AccountLast.length > 26) {
AccountLast = AccountLast.substring(0, 25) + '...';
}
return '' + AccountLast + '';
},
"aTargets": [2]
},
{
"fnRender": function(oObj) {
return '' + oObj.aData[0] + '';
},
"aTargets": [0]
},
{
"fnRender": function(oObj) {
var NoteVal = oObj.aData[12];
if (NoteVal.length > 10) NoteVal = NoteVal.substring(0, 7) + '...';
return '' + NoteVal + '';
},
"aTargets": [12]
}
]
});
});
});
The working JSON text (contents of JSONTest.txt):
{
"sEcho": 3,
"iTotalRecords": 16,
"iTotalDisplayRecords": 10,
"aaData": [
["229889", "2010 Nov 2", "Account Value", "2010", " ", "SO", "SO", "", "$9,293,387,000.00", "F9V", "B5", "t", "blah blah bla some notes n' stuff"],
["229888", "2010 Nov 2", "Account Value", "2010", " ", " ", " ", "", "$38,000.00", "F9V", " ", "", ""],
["229887", "2010 Nov 2", "Account Value", "2010", " ", " ", " ", "", "$0.00", "F9V", " ", "", ""],
["229889", "2010 Nov 2", "Account Value", "2010", " ", "SO", "SO", "", "$9,293,387,000.00", "F9V", "B5", "t", "blah blah bla some notes n' stuff"]
],
"aoColumns": [
{ "sTitle": "ID" },
{ "sTitle": "Field1" },
{ "sTitle": "Field2" },
{ "sTitle": "Field3" },
etc...
],
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] },
etc...
]
}
Now, if I append a simple fnRender to the aoColumnDefs in the JSON text the failure occurs. It fails even if I set aoColumnDefs in my original jQuery instead of setting it from the JSON text.
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
etc...
{
"fnRender": function(oObj) {
etc... }
]
Thanks for your help.
This discussion has been closed.
Replies
You have aoColumnDefs in your initilastion block of code twice, which I believe is probably the issue. I think that you want only the data.aoColumns part and not the second one which will overwrite the first, since this is not something that JavaScript objects cope with (bugs me that JavaScript engines don't throw an error about this!).
Other than that I would say that the basic code looks good. Let us know if this works!
Regards,
Allan
[code]
$.getJSON("JSONTest.txt", function(data) {
$('#example').dataTable({
"aaSorting": [[0, "desc"]],
"aaData": data.aaData,
"aoColumns": data.aoColumns,
"sScrollX": "100%",
"sScrollXInner": "150%",
"bScrollCollapse": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumnDefs": data.aoColumnDefs
});
});
[/code]
and it all works until I add fnRender to my JSON code. So if I have:
[code]
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
// etc...
[code]
that works but if I make it into:
[code]
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
// etc...
"fnRender": function(oObj) {
return '' + oObj.aData[0] + '';
},
"aTargets": [0]
}
// etc...
[code]
it stops working. No datatable and no error. I know the aoColumnDefs with fnRender works because if I just keep it in my jquery it works fine.
Does the table render when you have the function in the aoColumnDefs string? I'm half wondering if jQuery is not allowing javascript functions in the JSON. I'll try it out...
Allan
This works:
DataTables.htm
[code]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
DataTables Test
@import "css/demo_page.css";
@import "css/demo_table_jui.css";
@import "css/smoothness/jquery-ui-1.8.6.custom.css";
[/code]
DataTables.js
[code]
$(document).ready(function() {
$('#dynamic').html('');
$.getJSON("dtJSON.txt", function(data) {
$('#example').dataTable({
"aaSorting": [[0, "desc"]],
"aaData": data.aaData,
"aoColumns": data.aoColumns,
"bScrollCollapse": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumnDefs": data.aoColumnDefs
});
});
});
[/code]
dtJSON.txt
[code]
{
"sEcho": 1,
"iTotalRecords": 6,
"iTotalDisplayRecords": 10,
"aaData": [
["229889", "2010 Nov 2", "Data1-1", "Data1-1"],
["229890", "2010 Nov 3", "Data1-2", "Data1-1"],
["229891", "2010 Nov 4", "Data1-3", "Data1-1"],
["229892", "2010 Nov 5", "Data1-4", "Data1-1"],
["229893", "2010 Nov 6", "Data1-5", "Data1-1"],
["229894", "2010 Nov 7", "Data1-6", "Data1-1"]
],
"aoColumns": [
{ "sTitle": "ID" },
{ "sTitle": "The Date" },
{ "sTitle": "Data1" },
{ "sTitle": "Data2" }
],
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] }
]
}
[/code]
[code]
{
"sEcho": 1,
"iTotalRecords": 6,
"iTotalDisplayRecords": 10,
"aaData": [
["229889", "2010 Nov 2", "Data1-1", "Data1-1"],
["229890", "2010 Nov 3", "Data1-2", "Data1-1"],
["229891", "2010 Nov 4", "Data1-3", "Data1-1"],
["229892", "2010 Nov 5", "Data1-4", "Data1-1"],
["229893", "2010 Nov 6", "Data1-5", "Data1-1"],
["229894", "2010 Nov 7", "Data1-6", "Data1-1"]
],
"aoColumns": [
{ "sTitle": "ID" },
{ "sTitle": "The Date" },
{ "sTitle": "Data1" },
{ "sTitle": "Data2" }
],
"aoColumnDefs": [
{ "sWidth": "4em", "aTargets": [0] },
{ "sWidth": "6em", "aTargets": [1] },
{ "sWidth": "15em", "aTargets": [2] },
{ "sWidth": "3em", "aTargets": [3] },
{
"fnRender": function(oObj) {
return '' + oObj.aData[0] + '';
},
"aTargets": [0]
}
]
}
[/code]
Maybe it would work if I didn't have to put fnRender in aoColumnDefs but I'm still learning about DataTables and jQuery and I don't know how to do that or if it's possible.
Hey, if you're in the US don't spend holiday time on this ok? It can wait.
Thanks
I'm UK based so no worries on the holiday front :-). I'm am away from my computer atm though and replying on my phone, so forgive me if this isn't a great reply!
I'm almost certain that the issue is with the parsing of the neon by jquery. The jquery documentation nots that getJSON uses $.parseJSON, the documentation for which says "Takes a well-formed JSON string and returns the resulting JavaScript object". The problem you face is that function(){}, is not a valid json value ( http://json.org ), so I think jquery is rejecting it. To test this (I'll try it when I'm back at my computer) I would suggest using $.Ajax and set an error handler. I believe that jquery will be giving an error, but since there is no error handler for getJSON it just disappears.
There are a couple of options to address this I believe. The first is to simply eval() the string the server returns your self, another slightly more complicated one would be you use JSONP. finally you could have the server set a flag for what function it wants the fnRender to be and then have the client side replace that string with an already available function.
I would say that in the case above the easiest thing to do is simply have the server render the link for you and return that as part of the json. If that isn't enough then consider an eval() call.
Regards,
Allan
Thanks
I'll bash together an example using eval() tomorrow morning which should do the job for you (sorry I can't do it right now, probably take me until tomorrow morning on my phone!).
Regards,
Allan
Sorry for the delay in getting back to you about this! Here is an example of how it might be done using eval:
[code]
$(document).ready(function() {
$('#dynamic').html('');
$.ajax( {
"dataType": 'text',
"type": "GET",
"url": "dtJSON.txt",
"success": function (dataStr) {
var data = eval( '('+dataStr+')' );
$('#example').dataTable({
"aaSorting": [[0, "desc"]],
"aaData": data.aaData,
"aoColumns": data.aoColumns,
"bScrollCollapse": true,
"bFilter": false,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumnDefs": data.aoColumnDefs
});
}
} );
});
[/code]
It would be remiss of me not to not to note that eval() should be used with caution! Generally speaking it should be avoided, although can be useful in places like this. There are security issues that should be considered when eval()ing (particularly when using data from a 3rd party!). Something to bare in mind!
Regards,
Allan