TableTools Copy/Xls with Ajax

TableTools Copy/Xls with Ajax

ZadamsZadams Posts: 5Questions: 0Answers: 0
edited September 2011 in TableTools
Hi,

When DataTable is not on server side processing, TableTools Copy and Xls functions work fine.
But I also need to make those functions work for server side processing.

My problem :
I need to copy and export all the data, and not just what aoData contains (in serverSide it only contains the page on display).
I know that TableTools was not intended for serverSide Processing, but I hope we'll find the answer.

Here is my attempt to make the copy button work for server side.

I redifined sSwfPath, and for the button sExtends, sAction, sAjaxUrl, fnClick, fnAjaxComplete :
- sSwfPath -> mySwfPath (wich already works for client side processing)
- sExtends -> "ajax"
- sAction -> "flash_copy"
- sAjaxUrl -> myUrl
- fnClick :
I do my custom Ajax call and set the callback to fnAjaxComplete.
This call returns all the data (the same way fnServerData works).
- fnAjaxComplete :
I process the response the same way you process the data in "fnGetDataTablesData".
Then I retrieve the tableTools instance and call fnSetText.

Everything seems to work fine, but the copy didn't occur.
The flash element is properly set, but it didn't copy my text in the clipboard...

If I click again the copy works (cause the flash is already set before the click I guess).

Do I miss a step?
If not, how can I tricked ZeroClipboard to fake another click on his hidden flash div?

Btw, I'm on TableTools V2.0.1 and DataTables 1.7.6.

I thank you in advance,
Regards

Replies

  • ZadamsZadams Posts: 5Questions: 0Answers: 0
    edited September 2011
    Hi again,

    I got my solution to work by dealing with ZeroClipBoard myself.

    - I don't set the sAction anymore
    - I added an alert popup onAjaxComplete
    - I created a flash element the same way as you do, but I linked it to the confirmation button of the new popup

    I almost redefined every step of DataTools, but as you said, It wasn't meant for serverSide :)

    It was the only solution I could think of, because I don't see how to make JS click the flash div.

    Have a nice day !
  • saichaitanyad1saichaitanyad1 Posts: 6Questions: 0Answers: 0
    Hi Zadams
    I too struck with same problem but copying to csv file. I am doing an ajax call on fnAjaxComplete and creating a string with whole data and setting that string to flash but it works in some instances and it didnt in some. Please paste your code.
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Yup its a non-trivial one this one since TableTools was specifically designed to work on the client-side rather than server-side. What needs to be done, is to use the 'ajax' button to get all the data from the server (indeed, you might need to define your own $.ajax() call in fnClick for this to be workable in your environment) and then pass that through to the Flash component to save the file locally. A little bit messy really.

    Another option is to generate the file server-side and have the browser download it upon request, which can be done with this plug-in button: http://datatables.net/extras/tabletools/plug-ins#download (although obviously you need to craft the server-side code to create the file!).

    Allan
  • ZadamsZadams Posts: 5Questions: 0Answers: 0
    edited September 2011
    Hi,
    Yes, the ajax call need to be in fnClick, and the callback is fnAjaxComplete.

    But when I tried to use the flash mechanics inbeded in the plugin, I had some problems.
    Because the flash is bind to the copy/xls/csv button, so when you click it, it doesn't wait for your callback to finish. And when your callback takes too long, there is nothing in the clipboard (or in the file).

    The only solution I could think of was to handle the flash myself.
    In the end I almost redifined everything, so the only reason I kept the DataTool plugin was to comply with the style and code of the other pages of my application.

    Here are the key parts of my solution:

    First the DataTools plugin init part:
    [code]
    aButtons: [
    {
    sExtends: "ajax",
    sButtonText: "BtnName",
    sFieldSeperator: "\t",
    sNewLine: "auto",
    mColumns: "visible",/*Just a requierment in my case*/
    sAjaxUrl: './myUrl.do',/* I was using Struts*/
    fnClick: function( nButton, oConfig) {
    theOconfig = oConfig;
    myData = initYourParametersIfYouNeedTo();
    $.ajax( {
    dataType: 'json',
    type: 'POST',
    url: oConfig.sAjaxUrl,
    data: myData,
    success: oConfig.fnAjaxComplete
    } );
    },
    fnAjaxComplete: function ( json ) {
    var textData = json.myData;

    nButton=textData.split("\n").length - 1;
    jAlert(nButton+" line"+(nButton==1?"":"s")+" blabla...","");

    var clip = fnInitFlash("swf/copy_cvs_xls_pdf.swf","flash_copy",theOconfig);
    fnSetText( clip, textData); /*Set the data*/

    /*glue the flash to the ok button of the popup*/
    clip.glue('popup_ok');
    clip.addEventListener( 'complete', function(client, text) {
    /*when the copy/export is done*/
    $("#popup_ok").click(); /*close the popup*/
    clip.destroy(); /*destroy the flash*/
    } );
    }
    }
    ],
    [/code]
    For the fnSetText, you can use the one define in TableTools.


    For the flash init I also looked in TableTools, here is the code :
    [code]
    if ( typeof ZeroClipboard != 'undefined' )
    {
    ZeroClipboard.moviePath = swfPath;
    }

    var flash = new ZeroClipboard.Client();

    flash.setHandCursor( true );

    if ( action == "flash_save" )
    {
    flash.setAction( 'save' );
    flash.setCharSet( (oConfig.sCharSet=="utf16le") ? 'UTF16LE' : 'UTF8' );
    flash.setBomInc( oConfig.bBomInc );
    flash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle()) );
    }
    else if ( action == "flash_pdf" )
    {
    flash.setAction( 'pdf' );
    flash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle()) );
    }
    else
    {
    flash.setAction( 'copy' );
    }
    [/code]

    I hope this will help you.

    Have a nice day.
    Zadams
  • ParimalParimal Posts: 17Questions: 1Answers: 0
    i would like to know how you set the data into fnSetText, so can you share your code or how i can call tabletools 'fnSetText' function. sorry as i am new into datatable.
  • ParimalParimal Posts: 17Questions: 1Answers: 0
    I am getting error 'not define' on 'fnSetText( clip, textData); /*Set the data*/'
  • ZadamsZadams Posts: 5Questions: 0Answers: 0
    edited September 2011
    Hi,

    Here is the code of fnSetText, but you can find it in TableTools.

    [code]
    /**
    * Set the text for the flash clip to deal with
    *
    * This function is required for large information sets.
    * There is a limit on the amount of data that can be transfered
    * between Javascript and Flash in a single call, so we use this
    * method to build up the text in Flash by sending over chunks.
    * It is estimated that the data limit is around 64k, although it
    * is undocuments, and appears to be different between different
    * flash versions. We chunk at 8KiB.
    */

    var asReturn = [];
    var iStrlen = sData.length; /* here sData is your txt*/

    /*Break a string up into an array of smaller strings*/
    for ( var i=0 ; i
  • ParimalParimal Posts: 17Questions: 1Answers: 0
    hi thanks for reply

    i am calling tabletool function 'fnsettext ' but i am getting following error.
    ------------

    sData.substring is not a function
    [Break On This Error] asReturn.push( sData.substring( i, iStrlen ) );

    ----------------
    I am showing only 15 records on page but requirement is that when i click on export i want to export all the data so here i am calling to server to get all the data so flash can use it this new data. am i on right direction or i am doing something wrong? or i am miss understanding and working on wrong direction?

    after server call i am getting json data like
    [["99202218", "Alison Fitzgerald", "Dr . Cowie", 6 more...],
    ["97200309", "Helen Turnbull", "Dr Iain Robert Keith Myers", 6 more...],
    ["97200060", "Helen Turnbull", "Dr Jennifer E McInnes", 6 more...]
    ......10,000 more records here

    ]


    "fnClick": function (nButton, oConfig, oFlash) {
    theOconfig = oConfig;
    obj = this;
    myData = null;
    $.ajax({
    dataType: 'json',
    type: 'POST',
    url: ajaxHandlerURL + "?bExporting=true",
    data: myData,
    //success: oConfig.fnAjaxComplete
    success: function (json) {
    var textData = json.aaData;

    //nButton=textData.split("\n").length - 1;
    //jAlert(nButton+" line"+(nButton==1?"":"s")+" blabla...","");

    var clip = fnInitFlash("/Scripts/TableTools/media/swf/copy_cvs_xls_pdf.swf", "flash_save", theOconfig);
    debugger;
    obj.fnSetText(clip, textData); /*Set the data*/

    /*glue the flash to the ok button of the popup*/
    clip.glue('popup_ok');
    clip.addEventListener('complete', function (client, text) {
    /*when the copy/export is done*/
    $("#popup_ok").click(); /*close the popup*/
    clip.destroy(); /*destroy the flash*/
    });
    }
    });
    },


    when i done debuge., sData is an array rather than text so how i can resolve this issue?
  • ZadamsZadams Posts: 5Questions: 0Answers: 0
    Hi,

    Your server need to return a string with all the result or you should try to handle your array in the JS to have a string in the end.
    You can look how TableTools does that in "_fnGetDataTablesData".

    I Had to do the first solution cause if you have a lot of result, ie7 takes to long to parse the string (yes my solution needed to work on ie7 :s ^^).
This discussion has been closed.