DataTable inside parent DataTable details
DataTable inside parent DataTable details
kahlusha
Posts: 3Questions: 0Answers: 0
Hey there,
I'm needing to embed one DataTable inside another's details. They have two completely separate data sources.
I have placed the second table inside a hidden column in the first table and then show that hidden column inside the details. Basic implementation of the details.
I have managed to get the child DataTable to initialize by calling the jQuery to run on the child when the details are opened:
[code]
jQuery('#parentTable > tbody > tr > td > img').live('click', function () {
var nTr = jQuery(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "../details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row and call child datatable*/
this.src = "../details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
jQuery('.childTable').dataTable( {
"bPaginate": false,
});
}
} );
[/code]
This will make my child table into a DataTable, but it fails when I open a second set of details (as it can't 'reinitialize') ... if I move the initialization outside of the "open" statement then the initialization just doesn't happen (my guess is it cannot run on a hidden column).
Perhaps there is a destroy or something that I can do when I open a second set of "details"? I'm also okay with the first one closing in order to open a second.
I'm hoping that someone with a better knowledge of how the DataTables work can help me out (I'm a bit of a noob)! Thanks!!
I'm needing to embed one DataTable inside another's details. They have two completely separate data sources.
I have placed the second table inside a hidden column in the first table and then show that hidden column inside the details. Basic implementation of the details.
I have managed to get the child DataTable to initialize by calling the jQuery to run on the child when the details are opened:
[code]
jQuery('#parentTable > tbody > tr > td > img').live('click', function () {
var nTr = jQuery(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "../details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row and call child datatable*/
this.src = "../details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
jQuery('.childTable').dataTable( {
"bPaginate": false,
});
}
} );
[/code]
This will make my child table into a DataTable, but it fails when I open a second set of details (as it can't 'reinitialize') ... if I move the initialization outside of the "open" statement then the initialization just doesn't happen (my guess is it cannot run on a hidden column).
Perhaps there is a destroy or something that I can do when I open a second set of "details"? I'm also okay with the first one closing in order to open a second.
I'm hoping that someone with a better knowledge of how the DataTables work can help me out (I'm a bit of a noob)! Thanks!!
This discussion has been closed.
Replies
For my purposes there is no reason to have more than one "details" set open.
[code]
$('#example td.control').live( 'click', function () {
var oTable = example;
var nTr = this.parentNode;
var i = $.inArray( nTr, anOpen );
var iId = nTr.id;
if ( i === -1 ) {
$('img', this).attr( 'src', sImageUrl+"details_close.png" );
var nDetailsRow = oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
$('div.innerDetails', nDetailsRow).slideDown();
var tInnerTable = $('#dtInnerTable').dataTable({
// Reinitialization
"bRetrieve": true,
// Look and feel
"bPaginate": false,
"bInfo": false,
"bFilter": false,
"bJQueryUI": true
}); // End of datatable
tInnerTable.makeEditable({
sDeleteURL: "detail_row_delete.php"
});
anOpen.push( nTr );
}
else {
$('img', this).attr( 'src', sImageUrl+"details_open.png" );
$('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
oTable.fnClose( nTr );
anOpen.splice( i, 1 );
} );
}
} );
[/code]
The table in the detail box is written by javascript as in the drill down example.
Thanks!
Peter
Here's what my code looks like. I'm not terribly good at looking at other people's code, so I don't have any feedback for you on your stuff, sorry! I haven't implemented editable, so I don't know how that works either :)
[code]
/* Formating function for row details */
function fnFormatDetails ( oTable, nTr )
{
var aData = oTable.fnGetData( nTr );
var sOut = ''+aData[9]+''; // 9 here is the td containing my child table
return sOut;
}
var oldRow = null;
jQuery(document).ready(function() {
/*
* Insert a 'details' column to the table
*/
var nCloneTh = document.createElement( 'th' );
var nCloneTd = document.createElement( 'td' );
nCloneTd.innerHTML = '';
nCloneTd.className = "center";
jQuery('#parent > thead > tr').each( function () {
this.insertBefore( nCloneTh, this.childNodes[0] );
} );
jQuery('#parent > tbody > tr').each( function () {
this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] );
} );
/*
* Initialse DataTables
*/
var oTable = jQuery('#parent').dataTable( {
"aoColumnDefs": [
{ "bVisible": false, "aTargets": [ 9 ] }, // 9 here is the td containing my child table
],
"bSortable" : false,
"bPaginate": false,
});
/* Add event listener for opening and closing details
* Note that the indicator for showing which row is open is not controlled by DataTables,
* rather it is done here
*/
jQuery('#parent > tbody > tr > td:first-child > img').live('click', function () {
var nTr = jQuery(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "/assets/icons/expand.png";
oTable.fnClose( nTr );
oldRow = null;
}
else
{
/* Another row is open - close it */
if (oldRow != null)
{
jQuery('#parent > tbody > tr > td:first-child > img').attr('src', '/assets/icons/expand.png');
oTable.fnClose( oldRow );
}
/* Open this row */
oldRow = nTr;
this.src = "/assets/icons/collapse.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
/* initialize dataTable for child table */
jQuery('.child').dataTable( {
"bPaginate": false,
"bFilter": false,
"bInfo": false
});
/* call any other js for your child table here */
}
} );
} );
[/code]'
I hope that will help. You may notice I've used the "first-child" selector ... this is because I have other images in my table. I also use the ">" in my selector so my child table doesn't inherit the parent behaviours.
Thanks for sharing. I'll try to adopt to my solution and keep you posted. Thanks again!
Peter
Thanks again for sharing your code. I managed to implement your method which is very good and understandable. Unfortunately I still have issues with the editable feature. Without the makeEditable() plugin many rows can be selected but with the plugin none. When the parent table is not editable the child's row can be selected. I don't know what I miss or it can be an issue with the editable plugin.
Thank you!
Peter
I.e., instead of:
[code]
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
/* initialize dataTable for child table */
jQuery('.child').dataTable( {
"bPaginate": false,
"bFilter": false,
"bInfo": false
});
[/code]
Try:
[code]
var nTrOpened = oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
/* initialize dataTable for child table */
jQuery('.child', nTrOpened).dataTable( {
"bPaginate": false,
"bFilter": false,
"bInfo": false
});
[/code]
Other strange behavior that when I click on one of the child's th element the parent's delete row button becomes enabled and can be clicked (making the click fires the error: _fnDisableDeleteButton is not defined).
Can anyone post a link of this working ?
Not sure how to set up the html for the child table ..