Triggering export after table is redrawn to show all records

Triggering export after table is redrawn to show all records

wblakencwblakenc Posts: 19Questions: 3Answers: 0

Hello all,
I have datatables set up to use server side processing and as we all know, if you click export it will only export what it has in memory. This makes perfect sense, however I need the ability to export all rows. I know there are various other questions about this, and other ways to solve it, however I am interested in try to automatically change the page length to 'All' when the user clicks the export button.

i.e.:

 "buttons": 
            [
                { 
                    extend: "edit",   
                    editor: editor 
                },
                { 
                    extend: 'excel',
                    text: 'Export to Excel',
                    action: function ( e, dt, node, config ) {
                        theTable.page.len(-1).draw();
                        theTable.button('1').trigger();
                        
                    }
                }
            ]

The above throws a Stackoverflow (which I think makes some sense as it looks like an endless loop). Long story short how do I (or can I?) change the action of the excel export to first change the page length to 'All' then export the data? I can always instruct my users to manually select 'All' then export, but they won't listen.

I have also tried:

 "buttons": 
            [
                { 
                    extend: "edit",   
                    editor: editor 
                },
                { 
                    extend: 'excel',
                    text: 'Export to Excel',
                    action: function ( e, dt, node, config ) {
                        theTable.page.len(-1).draw();
                        $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config);
                        
                    }
                }
            ]

Which 'works' in that it does export the data but it doesn't wait for the draw to complete which means it only exports the first page. Is there anyway to have the $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config); wait until after the draw completes?

Thoughts?

Answers

  • wblakencwblakenc Posts: 19Questions: 3Answers: 0

    Also on a side note when I try:

     "buttons": 
                [
                    { 
                        extend: "edit",   
                        editor: editor 
                    },
                    { 
                        
                        text: 'Export to Excel',
                        action: function ( e, dt, node, config ) {
                            frppTable.page.len(-1).draw();
                            $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config);
                            
                        }
                    }
                ]
    

    I get the following error:

    datatables.min.js:250 Uncaught (in promise) TypeError: Cannot read property 'indexOf' of undefined
        at w (datatables.min.js:250)
        at datatables.min.js:265
        at <anonymous>
    

    Which is odd as it is almost exactly mirrors the example on https://datatables.net/reference/option/buttons.buttons.action

    Perhaps I am missing something?

  • allanallan Posts: 42,105Questions: 1Answers: 5,347 Site admin

    Try this:

    action: function ( e, dt, node, config ) {
      dt.one( 'draw', function () {
        $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config);
      } );
      dt.page.len(-1).draw();
    }
    

    The issue you are running into is that the draw action when using server-side processing is async. So you have to wait for the next draw before the data is known to be loaded.

    Allan

  • wblakencwblakenc Posts: 19Questions: 3Answers: 0

    Thanks Allan! However, when enter the above it results in the following error:

    Uncaught TypeError: this.processing is not a function
        at HTMLTableElement.action (datatables.js:39288)
        at HTMLTableElement.<anonymous> (index.cfm?action=actUserLogin:549)
        at HTMLTableElement.fn (datatables.js:4508)
        at HTMLTableElement.dispatch (datatables.js:4749)
        at HTMLTableElement.elemData.handle (datatables.js:4561)
        at Object.trigger (datatables.js:7819)
        at HTMLTableElement.<anonymous> (datatables.js:7887)
        at Function.each (datatables.js:377)
        at jQuery.fn.init.each (datatables.js:149)
        at jQuery.fn.init.trigger (datatables.js:7886)
    action @ datatables.js:39288
    (anonymous) @ index.cfm?action=actUserLogin:549
    fn @ datatables.js:4508
    dispatch @ datatables.js:4749
    elemData.handle @ datatables.js:4561
    trigger @ datatables.js:7819
    (anonymous) @ datatables.js:7887
    each @ datatables.js:377
    each @ datatables.js:149
    trigger @ datatables.js:7886
    _fnCallbackFire @ datatables.js:27865
    _fnDraw @ datatables.js:24738
    _fnAjaxUpdateDraw @ datatables.js:25363
    (anonymous) @ datatables.js:25203
    callback @ datatables.js:25095
    success @ datatables.js:25125
    fire @ datatables.js:3199
    fireWith @ datatables.js:3329
    done @ datatables.js:8769
    (anonymous) @ datatables.js:9135
    XMLHttpRequest.send (async)
    send @ datatables.js:9187
    ajax @ datatables.js:8668
    _fnBuildAjax @ datatables.js:25179
    _fnAjaxUpdate @ datatables.js:25199
    _fnDraw @ datatables.js:24662
    _fnReDraw @ datatables.js:24781
    (anonymous) @ datatables.js:28669
    iterator @ datatables.js:28249
    (anonymous) @ datatables.js:28658
    (anonymous) @ datatables.js:28417
    action @ index.cfm?action=actUserLogin:551
    action @ datatables.js:37106
    (anonymous) @ datatables.js:37121
    dispatch @ datatables.js:4749
    elemData.handle @ datatables.js:4561
    

    Just to confirm my setup is correct here is my code:

     "buttons": 
                [
                    { 
                        extend: "edit",   
                        editor: editor 
                    },
                    { 
                        
                        extend: 'excel',
                        text: 'Export to Excel',
                        action: function ( e, dt, node, config ) {
                          dt.one( 'draw', function () {
                            $.fn.dataTable.ext.buttons.excelHtml5.action.call(this, e, dt, node, config);
                          } );
                          dt.page.len(-1).draw();
                        }
                    }
                ]
    
  • wblakencwblakenc Posts: 19Questions: 3Answers: 0

    Allan,
    I changed my code a little bit to include the non minified version of buttons.html5.js which gave me the ability to debug the issue I was getting. I found that when I comment out: this.processing( true ); on line 989 and that.processing( false ); on line 1202 and I was able to refresh (draw) the table showing all records and export the results as a excel doc.

Sign In or Register to comment.