fnDrawCallback
fnDrawCallback
zygimantas
Posts: 33Questions: 0Answers: 0
What is the point of fnDrawCallback function, when it takes no parameters and returns void?
The documentation says: "This function is called on every 'draw' event, and allows you to dynamically modify any aspect you want about the created DOM".
How can we access oTable inside this callback? Am I missing something here?
The documentation says: "This function is called on every 'draw' event, and allows you to dynamically modify any aspect you want about the created DOM".
How can we access oTable inside this callback? Am I missing something here?
This discussion has been closed.
Replies
You are right, it doesn't take any parameters or return anything (what would it return, given that the table has already been drawn). Perhaps it would be an idea to pass the settings object, and I'll include this in 1.5.
Allan
The only trick there might be that the oTable object isn't fully initialised when you then want to call it... Sorry it's not tested. I'll have a further look tomorrow.
Okay, there are two possibilities for you:
[code]
$(document).ready(function() {
oTable = $('#example').dataTable( {
"fnDrawCallback": function () {
if ( typeof oTable != 'undefined' ) {
oTable.fnGetColumnData();
}
}
} );
oTable.fnGetColumnData();
} );
$(document).ready(function() {
oTable = $('#example').dataTable( {
"fnDrawCallback": function () {
setTimeout( function () {
oTable.fnGetColumnData();
}, 0 );
}
} );
} );
[/code]
The first one will get the column data after the object has been fully inited and then on each draw callback, while the second one (which it rather a hack...) uses a settimeout to interrupt the execution thread, allowing the object to fully initialise...
Allan
I also used fnDrawCallback to reattach some event handling that was lost; but I guess this is no longer needed.
Check out http://www.datatables.net/examples/server_side/row_details.html
I've been putzing around with this for a bit and I realized that in the following function:
[code]
var oTable;
function fnOpenClose ( oSettings )
{
$('td img', oTable.fnGetNodes() ).each( function () {
$(this).click( function () {
...
} );
} );
}
...
$(document).ready(function() {
oTable = $('#example').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "../examples_support/server_processing_details_col.php",
...
"fnDrawCallback": fnOpenClose
} );
} );
[/code]
Line 4 is exactly what you are describing here isn't it?
If it is.. do you have an alternative?
I'll continue to work on tis problem till I find a work around... if I do, I'll give you a heads up.
The reason my example works is that fnDrawCallback isn't called until the first draw - which is done asynchronously due to the Ajax call. So oTable should be initialised by the time fnDrawCallback is called. So what is the specific problem you are having?
Allan
trigger_report_table is undefined
code/allanc/pages/email2/js/trigger_activity_report.js
Line 15
my exact code is this:
[code]
var trigger_report_table;
function fnFormatDetails ( nTr )
{
var aData = trigger_report_table.fnGetData( nTr );
var sOut = '';
sOut += 'Rendering engine:'+aData[2]+' '+aData[5]+'';
sOut += 'Link to source:Could provide a link here';
sOut += 'Extra info:And any further details here (images etc)';
sOut += '';
return sOut;
}
function fnOpenClose ( oSettings )
{
jQuery('td img', trigger_report_table.fnGetNodes() ).each( function () {
$(this).click( function () {
var nTr = this.parentNode.parentNode;
if ( this.src.match('small_minus') )
{
/* This row is already open - close it */
this.src = "http://mailcenterdev.newmediagateway.com/code/global/images/icons/small_plus.gif";
/* fnClose doesn't do anything for server-side processing - do it ourselves :-) */
var nRemove = jQuery(nTr).next()[0];
nRemove.parentNode.removeChild( nRemove );
}
else
{
/* Open this row */
this.src = "http://mailcenterdev.newmediagateway.com/code/global/images/icons/small_minus.gif";
trigger_report_table.fnOpen( nTr, fnFormatDetails(nTr), 'details' );
}
} );
} );
}
jQuery(document).ready(function() {
url = 'index.php?p=email2.trigger_activity_report&page_action=getData';
trigger_report_table = jQuery("#trigger_report").dataTable({
bJQueryUI: true,
bProcessing: true,
sDom: '<"template-box"lfri><><"ui-widget ui-widget-content ui-helper-clearfix ui-corner-all template-box" t><"template-box"<"template-box toolbar" >p>',
sAjaxSource: url,
bStateSave: true,
bPaginate: false,
sPaginationType: "full_numbers",
bAutoWidth: true,
"fnDrawCallback": fnOpenClose
});
});
[/code]
This is why I assume that this is a simular issue.
Allan
Kinda like when you find that semicolon that was causing IE to iexplode.
Thanks from one Allan to another Allan,
Allan Chappell
This just bite me, I'd consider it a bug. I tried to port the `row detail` example to my static datatables -- exactly like talkitivewizard. @Allan, examples shouldn't be written in such a way that you can describe their function as "a trick" that relies on a side effect of using the server side functionality.
This example does not work for me, even with the modifications.
Allan
This is how i tried it:
[code]
"fnDrawCallback": function () {
if ( typeof oTable != 'undefined' ) {
fnOpenClose;
};
},
[/code]
Are you also using server-side processing?
If so, I suspect the only thing you need to do is actually call fnOpenClose (rather than the line you've got at the moment which won't actually do anything!):
[code]
"fnDrawCallback": function () {
if ( typeof oTable != 'undefined' ) {
fnOpenClose();
};
},
[/code]
Regards,
Allan
Instead, when i try it on the second page and go back to the first page, i see open details at the first page... ^^
[code]
jQuery('td img', oTable.fnGetNodes() ).each( function () {
[/code]
for example. With that, it should work regardless of what page it is on. However, it should probably work anyway with server-side processing... Could you post your initialisation code please? Or even better, a link!
Allan
var oTable;
/* Formating function for row details */
function fnFormatDetails ( nTr )
{
var aData = oTable.fnGetData( nTr );
var sOut = '';
sOut += '';
return sOut;
}
/* Event handler function */
function fnOpenClose ( oSettings )
{
$('td img', oTable.fnGetNodes() ).each( function () {
$(this).click( function () {
var nTr = this.parentNode.parentNode;
if ( this.src.match('details_close') )
{
/* This row is already open - close it */
this.src = "img/datatable/details_open.png";
/* fnClose doesn't do anything for server-side processing - do it ourselves :-) */
var nRemove = $(nTr).next()[0];
nRemove.parentNode.removeChild( nRemove );
}
else
{
/* Open this row */
this.src = "img/datatable/details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(nTr), 'details' );
}
} );
} );
}
$(document).ready(function() {
oTable = $('#datatable').dataTable( {
"sAjaxSource": 'rpc.php?action=doclist',
"sPaginationType": 'full_numbers',
"bAutoWidth": false,
"aaSorting": [[1, 'desc']],
"fnDrawCallback": function () {
if ( typeof oTable != 'undefined' ) {
fnOpenClose();
};
},
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
var id = aData[5];
$(nRow).attr("id",id);
return nRow;
},
"aoColumns" : [
{ "sClass": "center", "bSortable": false },
{ "fnRender": function ( oObj ) {
//var id = "test";
//$(oObj).attr("id",id);
return "" + oObj.aData[1] + "";
} },
null,
null,
null,
null,
{ "fnRender": function ( oObj ) {
return "";
} }
]
} );
} );
[/code]
[code]
"fnDrawCallback": function () {
if ( typeof oTable != 'undefined' ) {
fnOpenClose();
};
},
[/code]
To this:
[code]
"fnInitComplete": function () {
fnOpenClose();
},
[/code]
And let me know how you get on.
Allan
Just create a column classed as .moreInfo. + , etc -- I think I'd nest in an tag for old IE's but this works great for me.
Also, feel free to move the $tr element above the call to .dataTable if you want to cache the jQuery object and then just .clone() it or something of that sort.
[code]
$(document).ready( function () {
oTable = $("table").dataTable({
bJQueryUI: true
, bPaginate: true
, bAutoWidth: false
, fnRowCallback: function( nRow, aData, iDisplayIndex ) {
var $tr = $('').append(
$('', {
'colspan': $(nRow).children('td').length
, 'text': 'HALLO WIN'
} )
)
// we must unbind because nRow will be the same on next page
var ins = false
$(nRow).children('.moreInfo').unbind().toggle(
function () {
if ( ins ) {
$tr.show()
}
else {
ins = true
$(nRow).after( $tr )
}
}
, function () {
$tr.hide()
}
)
return $(nRow).get(0)
}
})
} )
[/code]
Feel free to use it, please give feedback.
Any suggestions?
@EvanCarroll: i will try to adapt to your example also...
@allan, I'd be curious to know what you think of this implementation vs. the one currently in the example?
Allan
[code]
"fnInitComplete": function () {
fnOpenClose();
},
[/code]
... doesn't help either.
May i provide you with a test account to our prototype via email?
Allan