Display a loader when a built-in button (PDF, Print etc) is clicked

Display a loader when a built-in button (PDF, Print etc) is clicked

murday1983murday1983 Posts: 29Questions: 12Answers: 0

I have a table which has buttons but due to the large amount of data in the table, when I click a button (e.g. CSV), it takes a while to download the CSV so i want a loader to display until the user can click the downloaded file.

I currently have a custom loader I use when the table is loading on page load and hides when the table is loaded.

The code below for that:

JS File

..Other Datatable Code above This...
"initComplete": function () {
    $('#accountSearchDataTableLoader').hide();
}

HTML

<span id="accountSearchDataTableLoader">
    <div class="d-flex justify-content-center">
        <div class="spinner-border text-info" role="status">
            <span class="sr-only">Loading...</span>
        </div>
    </div>
</span>

I need to identify when the CSV, PDF doc etc has rendered and available then once it is, hide the loader but i don't know how to do this as i don't know what to look for and i'm relatively new to Datatables.

This is my whole code i am using for my Datatable

var accountSearchDataTable = $('#accountSearchDataTable').DataTable({
    "ordering": true, // Allows ordering
    "paging": true, // Pagination
    "searching": true, // Searchbox
    "info": false, // Shows 'Showing X of X' information
    "pagingType": 'simple_numbers', // Shows Previous, page numbers & next buttons only
    "pageLength": 10, // Defaults number of rows to display in table. If changing this value change the show/hide below
    "dom":
        "<'form-group row'<'col-12 text-right'B>>" +
        "<'row'<'col-6'l><'col-6'p>>" +
        "<'row'<'col-12'tr>>" +
        "<'row'<'col-12'p>>",
    "lengthMenu": [
        [10, 25, 50, -1],
        [10, 25, 50, "All"]
    ],
    "buttons": [
        {
            extend: 'csv',
            text: '<i class="fas fa-file-csv"></i>',
            titleAttr: 'Click to download as a CSV',
            className: 'd-flex align-items-center justify-content-center alert-warning mb-0 roundButton'
        },
        {
            extend: 'pdf',
            orientation: 'landscape',
            text: '<i class="far fa-file-pdf"></i>',
            titleAttr: 'Click to download as a PDF',
            className: 'd-flex align-items-center justify-content-center alert-warning mb-0 roundButton'
        },
        {
            extend: 'print',
            text: '<i class="fas fa-print"></i>',
            titleAttr: 'Click to print the results',
            className: 'd-flex align-items-center justify-content-center alert-warning mb-0 roundButton'
        }
    ],
    "fnDrawCallback": function () {
        accountSearchDataTableInfo = $('#accountSearchDataTable').DataTable().page.info();
        $('.dt-buttons').removeClass('btn-group').css("display", "inline-flex");
        $('.btn').removeClass('btn-secondary').attr('data-toggle', 'tooltip').attr('data-placement', 'bottom');

        if (accountSearchDataTableInfo.pages == 1 && accountSearchDataTableInfo.length == -1) {
            $('.mb-2').show();
            $('#accountSearchDataTable_previous').hide(); // Pagintator 'Previous' button
            $('#accountSearchDataTable_next').hide(); // Pagintator 'Next' button
            $('.paginate_button').hide(); // Pagintator page '1' button
        } else if (accountSearchDataTableInfo.pages == 1) {
            $('.mb-2').hide(); // Items per page DD
            $('#accountSearchDataTable_previous').hide(); // Pagintator 'Previous' button
            $('#accountSearchDataTable_next').hide(); // Pagintator 'Next' button
            $('.paginate_button').hide(); // Pagintator page '1' button
        } else {
            $('.mb-2').show();
        }

        // Shows/Hides 'No Results' wording        
        if (accountSearchDataTableInfo.recordsDisplay > 1) {
            $('#noResultsWording').hide();
            $('#accountSearchDataSpan').show();
        } else {
            $('#noResultsWording').show();
            $('#accountSearchDataSpan').hide();
        }
        alert('hi');
    },
    "language": {
        "lengthMenu":
            "<span class='mb-2' style='display: flex'>" +
            "<span class='mr-2 d-flex align-items-center'>Displaying</span>" +
            "_MENU_" +
            "<span class='ml-2 d-flex align-items-center'>records</span>" +
            "</span>"
    },
    "ajax": {
        "type": 'GET',
        "url": 'test_JS_Files/jsonFiles/accountSearch.json',
        "data": function (data) {
            return data;
        },
        "dataSrc": function (res) {
            return res.data;
        },
        "error": function () {
            $('#accountSearchDataTable_wrapper').hide();
            $('#existingRuleLoadErrorMessage').html(
                '<p>There was an issue retrieving data. Please try again.</p>' +
                '<p>If the error keeps occurring, please get in touch.</p>').addClass('text-danger');
        }
    },
    "columns": [
        {
            "data": "id"
        },
        {
            "data": "type"
        },
        {
            "data": "company"
        },
        {
            "data": "contactname",
            "render": function (data) {
                if (data == '') {
                    data = 'N/A';
                } else {
                    data = data;
                }

                return data;
            }
        },
        {
            "data": "telno",
            "render": function (data) {
                if (data == '') {
                    data = 'N/A';
                } else {
                    data = data;
                }

                return data;
            }
        },
        {
            "data": "mobileno",
            "render": function (data) {
                if (data == '') {
                    data = 'N/A';
                } else {
                    data = data;
                }

                return data;
            }
        },
        {
            "data": "emailaddress",
            "render": function (data, type) {
                if (type != 'N/A') {
                    data = '<a href="mailto:' + data + '">' + data + '</a>';
                } else {
                    data = 'N/A';
                }

                return data;
            }
        },
        {
            "data": "prefix",
            "render": function (data) {
                if (data == '') {
                    data = 'N/A';
                } else {
                    data = data;
                }

                return data;
            }
        },
        {
            "data": "accountstatus"
        },
        {
            "searchable": false, // Stops search in the fields
            "sorting": false, // Stops sorting
            "orderable": false, // Stops ordering
            "data": null,
            "render": function (data) {
                return '<div class="d-flex align-items-center justify-content-center alert-info m-0 roundButton" data-toggle="tooltip" data-placement="bottom" title="Click to view details">' +
                    '<i class="fas fa-eye"></i>' +
                    '</div>'
            }
        },
    ],
    "initComplete": function () {
        $('#accountSearchDataTableLoader').hide();
        $('#accountSearchDataSpan').show();

        accountSearchDataTableInfo = $('#accountSearchDataTable').DataTable().page.info();
        if (accountSearchDataTableInfo.recordsDisplay < 10) {
            $('#accountSearchDataTable_length').hide();
            $('#accountSearchDataTable_paginate').hide();
        }
    },
    "destroy": true
});

Answers

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

    Hi @murday1983 ,

    I'm not sure where the time is spent when exporting data, but you could potentially add that code to the customize function, there's an example on the CSV button page.

    Cheers,

    Colin

  • murday1983murday1983 Posts: 29Questions: 12Answers: 0

    @colin Thanks for the suggestion, unfortunately it doesn't work I cant believe that the creators of the DT's have not thought of this solution before. I have spent almost a day trying to find a solution but cant find anything.

    Alternatively i was thinking about finding a way of when the CSV is downloaded but also cant find a solution to this either.

    Whey is this so hard. Reason i need it is that it take 10sec's for my CSV to be generated due to the amount of data so i need the loader.

    I also thought of just displaying my loader when they click for 10sec's but then if the table has 20 records the file is downloaded straight away so the user cant do anything.

    Not sure what or how to do this

  • allanallan Posts: 61,710Questions: 1Answers: 10,103 Site admin

    We display a little processing icon for the button that was clicked (at least in the newer versions of Buttons), which is controlled via the button().processing() method - and in turn that is this code.

    At the moment as you'll see there it is just a class name modification on the button. Perhaps what we should do is also trigger an event that can be listened for (e.g. by your own code) - buttons-processing.dt for example (DataTables has a processing event for exactly this).

    I'll get this into Buttons for its next release, but pull requests with the feature welcome :).

    Allan

  • uomopaleseuomopalese Posts: 4Questions: 1Answers: 0

    A very raw solution:

    customize: function (csv) {
      alert('start loader here');
      
      // ... put your code...
    
      if (window) {
        // ...will check for download window
        alert('stop loader here');
      }
    }
    
This discussion has been closed.