[SOLVED] How to add button to expand all details

[SOLVED] How to add button to expand all details

premiumbiscuitspremiumbiscuits Posts: 13Questions: 0Answers: 0
edited June 2012 in TableTools
I currently have two tables which take advantage of the onclick details expansion (as seen in this example: http://datatables.net/release-datatables/examples/api/row_details.html) and was wondering if it is possible to create a TableTool Button that would expand all the details in the visible page for the sake of printing/saving/copying. And, if it is possible, could I get a nudge in the right direction? I was looking at the "Plug-in Buttons" example (http://datatables.net/release-datatables/extras/TableTools/plug-in.html) but I'm a bit confused on what to do with it since it would be affecting things within the table itself.

This is what I'm working with:
[code]
/* Formating function for row details */
function fnFormatDetails ( oTable, nTr ){
var aData = oTable.fnGetData( nTr );
var sOut = '';
sOut += 'This fix is located in: ' +aData[3]+ '';
sOut += '';

return sOut;
}

$(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";

$('#prevRev thead tr').each( function () {
this.insertBefore( nCloneTh, this.childNodes[0] );
});

$('#prevRev tbody tr').each( function () {
this.insertBefore( nCloneTd.cloneNode( true ), this.childNodes[0] );
});

/*
* Initialse DataTables, with no sorting on the 'details' column
*/
var oTable = $('#prevRev').dataTable({
"aLengthMenu":[[5, 10, 25, -1],[5, 10, 25, "All"]],
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0 ] }
],
"aaSorting": [[1, 'asc']],
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"sDom": '<"H"Tfr>t<"F"ip>',
"oTableTools": {
"sSwfPath": "jQuery/DataTables-1.9.1/extras/TableTools/media/swf/copy_csv_xls_pdf.swf",
"aButtons": ["csv", "xls", "pdf", "print"]
},
"aoColumns": [
/* Details */ { "bVisible": false },
/* WorkItem */ null,
/* Comment */ null,
/* Location */ { "bVisible": false },
/* Knowledgebase */ null,
/* Version */ null
]
});


/* 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
*/
$('#prevRev tbody tr td').live('click', function () {
var nTr = $(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
//this.src = "jQuery/DataTables-1.9.1/examples/examples_support/details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row */
//this.src = "jQuery/DataTables-1.9.1/examples/examples_support/details_close.png";
oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
}
});
[/code]

Also note, the Location column is the one that is actually hidden and reappears. The Details column just holds the optional images.

Replies

  • allanallan Posts: 63,680Questions: 1Answers: 10,498 Site admin
    Hi,

    I'd suggest looking at using something like this:

    [code]
    {
    "sExtends": "text",
    "sButtonText": "Open all",
    "fnClick": function ( button, config ) {
    table.$('tr').each( function () {
    if ( !table.fnIsOpen( this ) ) {
    // ... open the row (could call 'click()' on it
    $(this).click();
    }
    }
    }
    }
    [/code]

    So something along those lines... You would need a collapse button as well, and possibly also to keep track of which rows are already open when the user presses the buttons so they can go back to that state.

    Allan
  • premiumbiscuitspremiumbiscuits Posts: 13Questions: 0Answers: 0
    edited June 2012
    When declaring the table, I have
    [code]
    var oTable = $('#currRev').dataTable({
    "aLengthMenu":[[5, 10, 25, -1], [5, 10, 25, "All"]],
    "aoColumnDefs": [
    { "bSortable": false, "aTargets": [ 0 ] }
    ],
    "aaSorting": [[1, 'asc']],
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "sDom": 'T<"clear"><"H"lfr>t<"F"ip>',
    "oTableTools": {
    "sSwfPath": "Final/TableTools-2.1.2/media/swf/copy_csv_xls_pdf.swf",
    "aButtons": ["copy", "csv", "xls", "pdf", "print",
    {
    "sExtends": "text",
    "sButtonText": "Expand all",
    "fnClick": function ( button, config ) {
    $('#curRev tbody tr:not(.details)').each( function() {
    if( !oTable.fnIsOpen( this ) ){
    $(this).click();
    }
    })
    }
    }]
    },
    "aoColumns": [
    /* Details */ { "bVisible": false },
    /* WorkItem */ null,
    /* Comment */ null,
    /* Location */ { "bVisible": false },
    /* Knowledgebase */ null
    ]
    });[/code]

    The new function doesn't work as is, but my question is whether or not it's okay to refer to oTable within the button function definition, or if I should make a new table variable to reference it?

    (also pardon me if these are stupid questions; I'm relatively new to web programming and there's all kinds of black magic that you're allowed to do with JS that would totally not fly with more structured languages like C/C++, so I'm never quite sure what's okay and what isn't)
  • allanallan Posts: 63,680Questions: 1Answers: 10,498 Site admin
    In this case, yes it is fine to use oTable in the button, because by the time the closure function in the button executes oTable will be defined (i.e. that function is "saved for later"). By contrast, you couldn't, for example, use oTable in fnDrawCallback since the first fnDrawCallback occurs during the DataTables initialisation (i.e. oTable is still undefined).

    If that isn't working, I'd suggest adding a bit of debug in to make sure it is doing what you expect - for example is 'this' in the each function a TR element (looks like it will be, but I'd make sure. Also note that your click function is assigned to TD elements, not the TR:

    [code]
    $('#prevRev tbody tr td').live('click', function
    [/code]

    Allan
  • premiumbiscuitspremiumbiscuits Posts: 13Questions: 0Answers: 0
    Man, I can't thank you enough! It totally works now. I didn't even notice that I was just selecting the rows.

    I'm really blown away with both this product and the fact that its creator still lurks around the forums answering questions. Thank you so much :)

    I got it working with the following, if anyone wants it for future reference:
    [code]
    "aButtons": ["copy", "csv", "xls", "pdf", "print",
    {
    "sExtends": "text",
    "sButtonText": "Expand all",
    "fnClick": function ( button, config ) {
    $('#currRev tbody tr td:not(.details,.expand)').each( function() {
    if( !oTable.fnIsOpen( $(this).parents('tr')[0] ) ){
    $( this ).click();
    }
    })
    }
    },
    {
    "sExtends": "text",
    "sButtonText": "Collapse all",
    "fnClick": function ( button, config ) {
    $('#currRev tbody tr td:not(.details,.expand)').each( function() {
    if( oTable.fnIsOpen( $(this).parents('tr')[0] ) ){
    $( this ).click();
    }
    })
    }
    }]
    [/code]
  • ljriveraljrivera Posts: 11Questions: 0Answers: 0
    Thanks for sharing!
    I have 2 questions
    1. Is there a way of making the expand affect all the elements on the table? Currently the ones that are not loaded on the page are not expanding/colapsing.

    2. Is there a way to make these buttons showable one the Print View?

    Thanks again for your time and help
This discussion has been closed.