1

I have a page with a download button on it. When A user presses the download button (which is just a link), a excel file is generated and returned as download. Generating this file could take up to a minute.

Currently the user only sees that something is happening because his browser is loading. I would like to make it a bit more visible that something is happening. For that, I have a div to show a spinner:

#contentLoading {
  position: fixed;
  z-index: 100000;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  display: inline-block;
  border-width: 30px;
  border-radius: 20%;
  -webkit-animation: spin 3s linear infinite;
  -moz-animation: spin 3s linear infinite;
  -o-animation: spin 3s linear infinite;
  animation: spin 3s linear infinite;
}

.style-3 {
  border-style: double;
  border-color: #1C90F3 #ff0000;
}

@keyframes spin {
  100% {
    transform: rotate(359deg);
  }
}
<div id="contentLoading">
  <span class="loading style-3"></span>
</div>

I'm now looking for a way to display this spinner while the download is created. I can trigger it with javascript like this:

$("#contentLoading").show() 

and hide it like this:

$("#contentLoading").hide()

But I don't know what to do in between them. I tried a Ajax call:

$('#exportExcel').click(function () {
  $("#contentLoading").show()
    $.ajax({
      url: 'download_excel_excel.php',
      type: 'POST',
      success: function () {
        $("#contentLoading").hide()
      }
    })
}); 

But with that, no download is returned to the browser

I also tried this:

$('#exportExcel').click(function () {
  $("#contentLoading").show()
  window.location = '/progs/q-store/projecten_ea/projectenlijst_excel.php';
  $("#contentLoading").hide()
});

But with that, the spinner is not shown.

Any idea how I can accomplish this?

2
  • This is a common problem, you can't determine when user get its file downloaded. You can try to set some function on your server, so when you're finished to generate your file there you can call this function to send some JSON object to the client to inform him that file has been downloaded successfully. Commented Oct 19, 2017 at 7:32
  • 1
    $('#exportExcel').click(function () { $("#contentLoading").show() }); should be enough to show spinner. To hide it it's a bit trickier. You would want to change you approach and use GET request that would generate proper content as well as content-disposition headers. Then you would indeed make GET request and do what you are doing in the first snippet. Commented Oct 19, 2017 at 7:33

2 Answers 2

1

Hi you can use below code, but you should get file link from AJAX result or if you already know that then you can give you directly.

$('#exportExcel').click(function () {
$("#contentLoading").show()
$.ajax({
  url: 'download_excel_excel.php',
  type: 'POST',
  success: function (result) {
    $("#contentLoading").hide();
    getFile(result['fileLink']);
  }
})
}); 

And here is getFile function it is basically create hidden iframe and set file

function getFile(fileUrl) {
var iframe = null;
if($('#downloadFrame').length > 0){
    iframe = $('#downloadFrame');
    iframe.attr('src',fileUrl)
}else {
    iframe = $("<iframe/>",{
        id: 'downloadFrame',
        src: fileUrl,
        style: 'visibility:hidden;display:none'
    });
    $('body').append(iframe);
}
}
Sign up to request clarification or add additional context in comments.

1 Comment

This will work, right. Just need to modify server side to generate file.
0

The way I usually set the loading screen is for all the aplication with the ajaxSetup

In the main JS file I have:

$(document).ready(function () {
//show and hide loading screen on each AJAX call
$.ajaxSetup({
    'beforeSend': function () {
        $('#contentLoading').show();
    },
    'complete': function () {
        $('#contentLoading').hide();
    },

});
....
});//end of $(document).ready

This will work on each AJAX call and you may set them without taking care about showing or hiding the loading screen.

Regards.

2 Comments

The problem is that OP doesn't have any AJAX calls, so this will never show/hide anything.
dfsq, you are right. I'm sorry I didn't understand properly the question :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.