exportData same format as copyHTML5

exportData same format as copyHTML5

Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2
edited June 2018 in DataTables 1.10

Is it possible to use the buttons.exportData() method to get the data from the table in the same format which is available if you use the copy button? I.e. the data is not returned as an object, instead it is just plain text?

I know I can format the data from the object but I just wondered if I could access the method which is already in use?

For example, if I do this I just get an object back, which is the correct behavior. But I would like this data in plain text, just like if I pressed the 'copy' button.

var data = table.buttons.exportData( {
                        columns : ':visible:not(.not-export-col)',  
                        modifier : {
                            selected : true
                        },                        
                        format: {
                            body: function(data, row, column, node) {   
                                if ( data || data.length ){
                                    var data = data.toString().replace(/<span class="hidden">[\s\S]*?<\/span>/, '').replace(/[^\x00-\x7F]/g, '').replace(/(&nbsp;|<([^>]+)>)/ig, '') + '\n';
                                }
                                console.log( data );
                                return data;
                            }
                        },
                    });

Thanks

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi @Restful Web Services ,

    I'd be tempted to just call the method table.buttons.exportData(), then stringify or manipulate the data some other way in the body object. It would be fairly easy to do,

    Cheers,

    Colin

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2
    edited June 2018

    Hi Colin,

    I am doing as you suggested. Only issue is that I cant seem to remove the 'tab' seperator between each cell so when I split the cell values onto separate lines each line beings with a tab indent.

    Like this:

    Test
        Test
        http://www.test.com/test-chalets/128/test
        undefined   
         
    
    Test
        Test
        http://www.test.com/test-chalets/216/test
        undefined   
         
    
    Test
        Test
        http://www.test.com/test-chalets/29/test
        undefined
    

    Any idea how to remove these, I have tried all sorts of regex expressions.

    Chris

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi Chris,

    How about something like this:

    JSON.stringify(table.buttons.exportData().body).replace(/[\[\]]/g, '')
    

    See example here,

    Cheers,

    Colin

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Hi Colin,

    That certainly works in your example. However, if I add it into my function it does not. Any idea why?

    {
                    extend : 'collection',
                    text : 'Export',
                    enabled: false,  
                    buttons : [{
                        extend : 'copy',
                        title : '', 
                        exportOptions : {
                            columns : ':visible:not(.not-export-col)',   
                            orthogonal: 'export',                            
                            modifier : {
                                selected : true
                            },
                            format: {
                                body: function(data, row, column, node) {   
                                    return data.replace(/[\[\]]/g, '') + '\n';
                                }
                            },
                        }
                    }
    

    Is it because the white space is created outside of the body function?

    Chris

  • allanallan Posts: 61,667Questions: 1Answers: 10,096 Site admin

    Hi - jumping in here - your button is still doing a copy to clipboard action, just with that extra formatting function. From your original question you don't want it to copy to clipboard, you want to get the data yourself and do something with it, so you'd use your own action method that would call the buttons.exportData() method - e.g.:

    buttons: [ {
      text: 'Do something',
      action: function ( e, dt, node, conf ) {
        var data = dt.buttons.exportData( {
          // optional export configuration such as your `orthogonal` parameter
        } );
    
        // Do something with the data
        // ...
      }
    } ]
    

    More information about custom buttons in the docs.

    Allan

  • kthorngrenkthorngren Posts: 20,276Questions: 26Answers: 4,765

    Checkout this thread where we worked out how to manipulate the copied data before it hits the paste buffer. It may not be the format you want but it should give you an idea of what to do:
    https://datatables.net/forums/discussion/comment/117387/#Comment_117387

    This is the working example:
    https://jsfiddle.net/f0c6qfj2/1/

    Instead of using format -> body it formats the whole document at once which is what you need to remove the tabs.

    Kevin

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Hi All. Thanks for the help, I have a working solution now.

    The context was that I wanted to make the data from the selected rows & visible columns available to both the clipboard and also available to me in an ajax modal which contains a form which generates emails. In this case I wanted an option to allow the data from the datatable to be available in the textarea 'body' field in the email form.

    I used this custom action button in DataTables,

    {
                        text : 'Copy',
                        action : function(e, dt, node, config) {
                            var data = table.buttons.exportData( {
                                columns : ':visible:not(.not-export-col)',  
                                orthogonal : 'export',  
                                modifier : {
                                    selected : true,
                                },    
                            });       
                            var exportData = '';
                            for (i = 0; i < data.body.length; i++) {  
                                for (j = 0; j < data.header.length; j++) { 
                                    if ( data.body[i][j].length > 0 ) {
                                        exportData += data.header[j] + ' : ' + data.body[i][j].replace(/<span class="hidden">[\s\S]*?<\/span>/, '').replace(/[^\x00-\x7F]/g, '').replace(/(&nbsp;|<([^>]+)>)/ig, '') + '\n';
                                    }
                                }
                                exportData += '\n';
                            } 
                            copyToClipboard( exportData );
                        }
                    }
    

    It takes the selected rows and visible columns and then loops through the data putting the header name alongside the corresponding body value with a line break following each value. If I have no value in the body I don't include it.

    Along with this javascript function which performs the copy to clipboard action.

    function copyToClipboard(rowData) {
        const el = document.createElement('textarea');
        el.value = rowData;
        el.setAttribute('readonly', '');
        el.style.position = 'absolute';
        el.style.left = '-9999px';
        document.body.appendChild(el);
        const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
        el.select();
        document.execCommand('copy');
        document.body.removeChild(el);
        if (selected) {
            document.getSelection().removeAllRanges();
            document.getSelection().addRange(selected);
        }
    };
    

    And, in order to make the same data available to my ajax modal I just store it as sessionStorage variable which I can then access from the ajax modal.

    The one thing that is missing is a prompt to the user to say 'your rows have been copied'.

    Not sure if this is a good solution?

  • allanallan Posts: 61,667Questions: 1Answers: 10,096 Site admin
    Answer ✓

    Looks good to me.

    If you want a confirmation dialogue, just throw up a div with the message in it and then use a setTimeout to remove it after a set amount of time (which is what Buttons does).

    Allan

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Okay, will do.

    Thanks

This discussion has been closed.