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
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
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
@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
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 aprocessing
event for exactly this).I'll get this into Buttons for its next release, but pull requests with the feature welcome .
Allan
A very raw solution: