TableTools on multiple tables

TableTools on multiple tables

ColdFFFColdFFF Posts: 3Questions: 0Answers: 0
edited January 2011 in TableTools
I have managed to get TableTools working for me *nearly* perfectly.

The only issue I have at the moment is that if I use TT on multiple tables within the same page, the swf is loaded on the first table (and thus the buttons work correctly), but the other tables buttons do not work.

Checking the javascript console, I get an uncaught exception "Unable to load SWF file - please check the SWF path" for the number of flash based buttons for all but the first table (eg: 3 tables, 1st works fine, so 8 exceptions).

When I view the source for the page, the broken flash based buttons seem to have the correct markup (button with unique id, div containing embeded swf)

I have experimented a bit, and if I only define the swf path in the first table, none of the tables buttons will work (including the first).


Is there any known work around for this?

Replies

  • Dave177Dave177 Posts: 7Questions: 0Answers: 0
    Can you post your code?
  • ColdFFFColdFFF Posts: 3Questions: 0Answers: 0
    Unfortunately not, the page is also using the smarty templating engine for php, and the individual template for this page is apparently far too large to post in a single comment. I expect it would take up over 3 comments to fit it all.

    Instead, Ive stuck it on pastebin:
    http://pastebin.com/uPg7khcd
  • jonesbjonesb Posts: 1Questions: 0Answers: 0
    I was having the same problem and figured out what was wrong...

    You cannot use multiple different selections in the same dataTables call, and still have tableTools work.


    For example, you cannot do:
    [code]
    $(document).ready( function () {
    TableTools.DEFAULTS.aButtons = [ "copy", "csv", "xls", "pdf" ];
    TableTools.DEFAULTS.sSwfPath = "../TableTools-2.0.0/media/swf/copy_cvs_xls_pdf.swf";

    $("#table1, #table2, #table3").dataTable({
    "bJQueryUI": true,
    "sDom": '<"H"Tfr>t<"F"ip>'
    });
    } );
    [/code]

    This will cause the TableTools buttons to confusingly show up on each table, but only actually export data from the first table. I.e. clicking the Copy button on 'table3' will actually copy the data from 'table1'.


    The solution is to break the dataTable calls into separate calls as follows:

    [code]
    $(document).ready( function () {
    TableTools.DEFAULTS.aButtons = [ "copy", "csv", "xls", "pdf" ];
    TableTools.DEFAULTS.sSwfPath = "../TableTools-2.0.0/media/swf/copy_cvs_xls_pdf.swf";

    $("#table1").dataTable({
    "bJQueryUI": true,
    "sDom": '<"H"Tfr>t<"F"ip>'
    });

    $(" #table2").dataTable({
    "bJQueryUI": true,
    "sDom": '<"H"Tfr>t<"F"ip>'
    });

    $("#table3").dataTable({
    "bJQueryUI": true,
    "sDom": '<"H"Tfr>t<"F"ip>'
    });
    } );
    [/code]


    This seems to work.

    As an aside... I could not get setting the 'sDom' option as a TableTools default to work. That's why it's repeated in each dataTable call.
  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin
    Hi folks,

    Thanks for flagging this up ColdFFF and the analysis jonesb :-). The issue with the multiple instances of TableTools with a single selector was basically due to a complication with how the instance reference is stored in DataTables. While it would be possible to fix this in TableTools, I think the right thing to do is to make a small modification to DataTables, which allows TableTools (and any other plug-ins which refer to the instance) to operate as you would expect.

    You can grab the 1.7.6 development from the downloads page on this site or GitHub:

    http://datatables.net/download/
    https://github.com/DataTables/DataTables/

    Regards,
    Allan
  • ColdFFFColdFFF Posts: 3Questions: 0Answers: 0
    edited January 2011
    I'm afraid neither the 1.7.6 dev nor the workaround provided by jonesb has worked for me.

    I'm wondering if perhaps the issue is an incompatability with the jQuery plugin loader I'm using instead. http://code.google.com/p/rloader/

    I'll do a test without the loader and post back the results.


    Edit:
    Nope - same results without the loader
  • GregPGregP Posts: 487Questions: 8Answers: 0
    I know this isn't helpful, so I apologize in advance: do you have the ability to move the plug-in loading to the server side? Client-side plug-in loading strikes me as a recipe for broken timing.

    I only mention this because I had some of my own plug-in loading issues recently relating to timing of scripts being loaded.
  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin
    Can you give us a link to a demo page showing this issue? You can send a link to me using the form at http://datatables.net/contact if you don't want to make it public. The basic problem is that you get the Javascript error - but no other side effects?

    Allan
  • cschwedacschweda Posts: 6Questions: 0Answers: 0
    I, too, am need of a way to run table tools on two tables on the same page. I checked both links above for DataTables 1.76 -- but I don't see it listed as a download. Where can I get 1.76 to test out multiple table tools?
  • cschwedacschweda Posts: 6Questions: 0Answers: 0
    Edit: found 1.76. This doesn't solve the problem of multiple instances. With this, only the print view works. The excel, csv, and pdf don't work.
  • cschwedacschweda Posts: 6Questions: 0Answers: 0
    Well, I got it to work. I ended up calling each instance of the table via ajax (through jquery ui's tabs). This seemed to work.

    Example here:

    http://www.icjia.org/sbox/fsgu-grants.cfm
  • GustGust Posts: 17Questions: 0Answers: 0
    Hello cschweda,

    I look at your site, pretty nice!

    I have bit of difficulty to find the relative example where you need to have TableTool to work on different table...

    Also, you seem to use JSON file to get your data into DTs, but with my little knowledge with jQuery I don't figure out how you initialize DTs instance... Is the init of DTs in a different html file that you call into a master html with ajax or what?

    Can you help by showing a DTs init example some how?

    Thanks

    Gust
  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin
    [quote]Gust said: I have bit of difficulty to find the relative example where you need to have TableTool to work on different table...[/quote]

    What difficulty are you having?

    [quote]Gust said: Can you help by showing a DTs init example some how?[/quote]

    From the docs:

    [code]
    /*
    * Example initialisation
    */
    $(document).ready( function () {
    $('#example').dataTable( {
    "sDom": 'T<"clear">lfrtip',
    "oTableTools": {
    "sSwfPath": "/swf/copy_cvs_xls_pdf.swf"
    }
    } );
    } );
    [/code]

    If that doesn't help - perhaps you can link to the page to see how far you've got.

    Allan
  • GustGust Posts: 17Questions: 0Answers: 0
    I get there :

    [code]

    everything is imported properly....


    {{=page_title}}{{=table_name}}







    <!--
    {{=T('Tab1')}}
    {{=T('Tab2')}}
    -->

    {{=T('Tab1')}}


    {{=table1}}







    {{=T('Tab2')}}


    {{=table2}}






    ALL JS DEPENDENCIES ARE IMPORTED CORRECTLY NO SPACE TO PUT EVERYTHING...



    TRYED THIS INIT WITH TABS NOT WORKING

    /*$(document).ready(function() {
    $("#tabs").tabs( {
    "show": function(event, ui) {
    var oTable = $('div.dataTables_scrollBody>table.sortable', ui.panel).dataTable();
    if ( oTable.length > 0 ) {
    new FixedColumns( oTable, {
    "iLeftColumns": 1,
    //"iLeftWidth": 150
    } );
    //$('td', oTable.fnGetNodes()).hover( function() {
    // var iLeftColumns = $('td').index(this) % 0;
    // var nTrs = oTable.fnGetNodes();
    // $('td:nth-child('+(iLeftColumns+1)+')', nTrs).addClass( 'highlighted' );
    //}, function() {
    // $('td.highlighted', oTable.fnGetNodes()).removeClass('highlighted');
    //} ); // Not working properly
    //oTable.fnAdjustColumnSizing();
    }
    }
    } );

    var filename_export = "{{=request.args(0)+request.now.strftime('_%Y-%m-%d_%H-%M-%S-%f')}}"
    var sSwfPath_location = "{{=URL('static','plugin_added/DataTables-1.8.1/extras/TableTools/media/swf/copy_cvs_xls_pdf.swf')}}"
    $('table.sortable').dataTable( {
    "bJQueryUI": true,
    "bAutoWidth": false,
    "bScrollInfinite": true,
    "sScrollY": "300px",
    "sScrollX": "100%",
    "bPaginate": false,
    "bProcessing": true,
    "bSortClasses" : false,
    "sDom": '<"H"Tfr>t<"F"ip>',
    "oTableTools": {
    "sRowSelect": "multi", // It copy all rows anyway?? + Glitch if fixedcolumn : NEED "bSelectedOnly": true
    "aButtons": [
    {
    "sExtends": "copy",
    "bSelectedOnly": true,
    "sCharSet": "utf16le"
    },
    {
    "sExtends": "csv",
    "sFieldBoundary": '"',
    //"sFieldSeperator": "-",
    "bSelectedOnly": true,
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".csv"
    },
    {
    "sExtends": "xls",
    "sFieldBoundary": '"',
    //"sFieldSeperator": "-",
    "bSelectedOnly": true,
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".csv"
    },
    {
    "sExtends": "pdf",
    "sPdfSize": "tabloid",
    "sPdfOrientation": "landscape",
    "sPdfMessage": "Your custom message would go here.",
    "bSelectedOnly": true,
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".pdf"
    }
    ],
    "sSwfPath": sSwfPath_location
    },
    "oLanguage": {
    "sSearch": "Search:"
    },
    "aoColumnDefs": [
    { "sWidth": "10%", "aTargets": [ -1 ] }
    ]
    } );

    } );*/

    TRYED DIFFERENTS THINGS

    /*$(document).ready(function() {
    $("#tabs").tabs( {
    "show": function(event, ui) {
    var oTable = $('div.dataTables_scrollBody>table.sortable', ui.panel).dataTable();
    if ( oTable.length > 0 ) {
    new FixedColumns( oTable, {
    "iLeftColumns": 1,
    //"iLeftWidth": 150
    } );
    //$('td', oTable.fnGetNodes()).hover( function() {
    // var iLeftColumns = $('td').index(this) % 0;
    // var nTrs = oTable.fnGetNodes();
    // $('td:nth-child('+(iLeftColumns+1)+')', nTrs).addClass( 'highlighted' );
    //}, function() {
    // $('td.highlighted', oTable.fnGetNodes()).removeClass('highlighted');
    //} ); // Not working properly
    //oTable.fnAdjustColumnSizing();
    }
    }
    } );*/


    LAST IMPLEMENTATION WITHOUT TABS AND A PER TABLE INIT AS FAR AS I UNDERSTAND


    $(document).ready( function () {

    var sSwfPath_location = "{{=URL('static','plugin_added/DataTables-1.8.1/extras/TableTools/media/swf/copy_cvs_xls.swf')}}"
    var filename_export = "{{=request.args(0)+request.now.strftime('_%Y-%m-%d_%H-%M-%S-%f')}}"

    TableTools.DEFAULTS.aButtons = [
    {
    "sExtends": "copy",
    "sCharSet": "utf16le",
    "bSelectedOnly": true
    },
    {
    "sExtends": "csv",
    "sFieldBoundary": '"',
    //"sFieldSeperator": "-",
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".csv",
    "bSelectedOnly": true
    },
    {
    "sExtends": "xls",
    "sFieldBoundary": '"',
    //"sFieldSeperator": "-",
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".csv",
    "bSelectedOnly": true
    },
    /*{
    "sExtends": "pdf",
    "sPdfSize": "tabloid",
    "sPdfOrientation": "landscape",
    "sPdfMessage": "Your custom message would go here.",
    "sCharSet": "utf16le",
    "sFileName": filename_export + ".pdf",
    "bSelectedOnly": true
    }*/
    ];

    TableTools.DEFAULTS.sSwfPath = sSwfPath_location;

    TableTools.DEFAULTS.sRowSelect = "multi";

    var oTable1 = $('#table1').dataTable( {
    "bJQueryUI": true,
    "bAutoWidth": false,
    "bScrollInfinite": true,
    "sScrollY": "300px",
    "sScrollX": "100%",
    "bPaginate": false,
    "bProcessing": true,
    "bSortClasses" : false,
    "sDom": '<"H"Tfr>t<"F"ip>',

    } );

    var oTable2 = $('#table2').dataTable( {
    "bJQueryUI": true,
    "bAutoWidth": false,
    "bScrollInfinite": true,
    "sScrollY": "300px",
    "sScrollX": "100%",
    "bPaginate": false,
    "bProcessing": true,
    "bSortClasses" : false,
    "sDom": '<"H"Tfr>t<"F"ip>',

    } );

    //var TableTools1 = TableTools.fnGetInstance( 'example1' );

    new FixedColumns( oTable1, {
    "iLeftColumns": 1,
    //"iLeftWidth": 150
    } );

    new FixedColumns( oTable2, {
    "iLeftColumns": 1,
    //"iLeftWidth": 150
    } );
    } );

    I ALSO TRY TO INIT TABS FROM BASIC jQUERY TABS PLUGINS SYNTAX...

    /*$(function() {
    var $tabs = $( "#tabs" ).tabs();
    //$tabs.tabs('select', {{=request.args(0)}});
    // return false;
    });*/



    I use Web2py so that why you have imbeded {{=SOMETHING}} sometimes...

    Thanks
    Width": 150
    } );
    } );

    I ALSO TRY TO INIT TABS FROM BASIC jQUERY TABS PLUGINS SYNTAX...

    /*$(function() {
    var $tabs = $( "#tabs" ).tabs();
    //$tabs.tabs('select', {{=request.args(0)}});
    // return false;
    });*/

    [/code]

    I use Web2py so that why you have imbeded {{=SOMETHING}} sometimes...

    Thanks

    Gust
  • GustGust Posts: 17Questions: 0Answers: 0
    The problem, can't get TableTools working on both tables independantly if I use Tabs plugin Init...

    Thanks

    Gust
  • dtlewisdtlewis Posts: 7Questions: 0Answers: 0
    The problem can be reproduced using TableTools on two separate DataTables each in it's own div then hiding one of the divs with jQuery .hide() TableTools will not work for the hidden div once it's made visible with jQuery .show()
  • dtlewisdtlewis Posts: 7Questions: 0Answers: 0
    edited August 2012
    It appears that if a DataTable is initialized in a div that is hidden, TableTools will not work on that table once it is visible. I originally thought the problem was related to using more than one table but it appears to be related to Tables within hidden divs during initialization. If I initially keep the div visible then hide after initialization, TableTools will work.
  • dtlewisdtlewis Posts: 7Questions: 0Answers: 0
    In light of my earlier comments, the problem can be prevented by initializing the DataTable with the TableTools plugin immediately after making the containing div visible (don't initiallize a DataTable in a hidden div if it's using TableTools).
  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin
    > It appears that if a DataTable is initialized in a div that is hidden, TableTools will not work on that table once it is visible.

    It is because the element is display:none and thus has no height / width. As a result of this, the Flash buttons can't be correctly sized and you can't click on a 0x0 element.

    You need to use the TableTools http://datatables.net/extras/tabletools/api#fnResizeButtons method to resizing the buttons when the tab is made visible.

    Allan
  • dtlewisdtlewis Posts: 7Questions: 0Answers: 0
    That did the trick. Thank you.
  • drakula1234drakula1234 Posts: 58Questions: 1Answers: 0
    dtlewis,

    I have exactly the same problem, I have table inside a hidden div. When I make the div visible, then it would show and doesn't show when div is set to display:none.


    I have

    [code]




    [/code]

    For some reason this code wouldn't work for me.
    [code]
    var jqTable = $('datatablesTableID');
    if ( jqTable.length > 0 ) {
    var oTableTools = TableTools.fnGetInstance( jqTable[0] );
    if ( oTableTools != null && oTableTools.fnResizeRequired() )
    {
    /* A resize of TableTools' buttons and DataTables' columns is only required on the
    * first visible draw of the table
    */
    jqTable.dataTable().fnAdjustColumnSizing();
    oTableTools.fnResizeButtons();
    }
    }

    [/code]

    Can you post some code how to make the buttons work. Thanks !
  • alessbenalessben Posts: 2Questions: 0Answers: 0
    edited December 2012
    Hi all, I have the same problem but I have all div already displayed on screen.
    I do the initialisation of datatables with this code
    [code]
    $("table[id^='tab_case_']").dataTable({
    [/code]
    with this tablestools's button params
    [code]
    "oTableTools": {
    "sSwfPath": "/js/dataTable/extras/TableTools/swf/copy_cvs_xls_pdf.swf",
    "sRowSelect": "multi",
    "aButtons": [
    {
    "sExtends":"text",
    "sButtonText": "",
    "sButtonClass": 'info_class',
    "sButtonClassHover": 'info_class',
    "fnMouseover":function ( nButton, oConfig, oFlash ) {
    jQuery(this).removeClass('ui-button ui-state-default ui-state-hover DTTT_button');
    },

    "fnMouseout": function ( nButton, oConfig, oFlash ) {
    jQuery(this).removeClass('ui-button ui-state-default ui-state-hover DTTT_button');
    }
    },
    {
    "sExtends": "copy",
    "sButtonText": "Copia",
    "bSelectedOnly": "true",
    "fnComplete": function(nButton, oConfig, flash, text) {
    var
    len = text.split('\n').length - 1;
    plural = (len==1) ? "a" : "he";
    plural2=(len==1) ? "a" : "e";
    alert( <?php echo $TestiInLingua["statistiche_ebay"][$langid][69] ?> );
    }
    },
    {
    "sExtends": "csv",
    "sButtonText": "CSV",
    "bSelectedOnly": "true",
    "sTips": ""
    },
    {
    "sExtends": "xls",
    "sButtonText": "Excel",
    "bSelectedOnly": "true"
    },
    {
    "sExtends": "pdf",
    "sButtonText": "PDF",
    "bSelectedOnly": "true"
    }


    ]
    [/code]
    The first's table buttons are correctly displayed, with correct css, correct position, etc while the other tables are not. In subsequent tables there are default buttons and it seems to ignore the "aButtons": [ options
    The buttons work properly in all tables, doing the correct job.
    The number of table is not predictable so I cann't use separate initialisation.
    Could you help me?
    Thx
    Alessandro



    },
  • alessbenalessben Posts: 2Questions: 0Answers: 0
    Seems I've found the solution. It sounds strange for me because I don't understand why it works.
    I've changed
    [code]
    $("table[id^='tab_case_']").dataTable({
    [/code]
    with
    [code]
    jQuery("table[id^='tab_case_']").each(function(){
    $(this).dataTable({
    [/code]

    All buttons are correctly displayed and do right work.
    Hope it's usefull.

    Ale
This discussion has been closed.