7

I have a button to download an excel file. When the user clicks the button, the onClick function calls window.location= url

and when the downloading is done, the save as dialog popups with the file.

Now, I want to show a spinner until the file dialog appears. How do I do this?

I tried to create a spinner before "window.location" and hide it after that, but the spinner goes away immediately because window.location does not block until the file downloads.

Any ideas?

Thanks.

hese
  • 3,397
  • 8
  • 25
  • 34
  • See here https://stackoverflow.com/questions/33902299/using-jquery-ajax-to-download-a-binary-file its an audio file but it works for any other kind of file. – Eric Oct 15 '19 at 21:06

3 Answers3

9

This would be a solution which only works for Firefox browsers:

<script type="text/javascript">
//<![CDATA[
function download(url){
document.getElementById('spinner').style.display='';
frame = document.createElement("iframe");
frame.onload=function(){document.getElementById('spinner').style.display='none';}
frame.src=url;
document.body.appendChild(frame);
}
//]]>
</script>

In your HTML, have a spinner set up and ready to go:

<div id="spinner" style="background:url('/images/ico-loading.gif') #000 center no-repeat;opacity:.5;width:100%;height:100%;display:none;position:absolute" />

Then call it using this:

<button type="button" onclick="download('/spreadsheet.xls');">DOWNLOAD SPREADSHEET</button>

The button will call our javascript function with the URL we want to download. At this time we make the hidden spinner DIV visible and allow it take over the screen (note position absolute in style). An IFRAME is created to suck down the file. After the file downloads, it is given to the user and the .ONLOAD event is fired which hides the spinner DIV. All done with client side javascript!

themenace
  • 2,601
  • 2
  • 20
  • 33
Hawk
  • 551
  • 8
  • 10
  • 1
    Only works on firefox, cf: http://stackoverflow.com/questions/20572734/load-event-not-firing-when-iframe-is-loaded-in-chrome – FeeJai Dec 04 '14 at 13:08
6

You can't do that using just client script, because there is no event for when the download completes.

You would have to download the file through a proxy page on the server, with a unique identity in the URL so that each download could be identified. Then you could send AJAX requests from the script to the server to determine the status of the download.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Was trying to avoid polling the server every sec. I was thinking of something like being able to check the the status of the window object to know if the location it is pointing to (the file) has loaded, (if that makes sense). – hese Apr 22 '11 at 19:25
  • like when you say window.location = href, when the html of the url loads the windows onLoad event is called right? Only that in my case the href is pointing to a file...So will the windows onload get called or something? i dont know if i am talking sense...am new to javascript and all. – hese Apr 22 '11 at 19:27
  • 1
    @hese: When you load a page in the window, the document has events, but when you load an Excel document it's not loaded in a document object. Depending on how the browser is integrated with the office application, it may not even be opened in a browser window. – Guffa Apr 22 '11 at 19:52
0

This code works for jQuery, but with simple modification also for javascript. With this you won't need to change your requests-codes at all.

  1. Create a div element which contains the animation (either another div element with css-animation or an animated gif in an img element) and give it the id = "loadingicondiv". For example like this

    &ltdiv id="loadingicondiv">
    &ltdiv id="loadingicon" style="background:url('imgs/logo.png') center no-repeat;opacity:1.0;display:none;position:absolute;z-index: 9999;">&lt/div>&lt/div>

  1. Set the style of that div in your css file as follows


    #loadingicondiv{
        width: 100vw;
        height: 100vh;
        background: rgba(0,0,0, 0.3);
        position: fixed;
        z-index: 9999;
    }

  1. In the embeded js file enter this


    function showAnimation(){
        $('#loadingicondiv').css({display : ''});
    };

    function hideAnimation(){
        $('#loadingicondiv').css({display : 'none'});
    };

    $(document).ajaxStart(showAnimation).ajaxStop(hideAnimation);

This last line makes, that every request sent by your web application, executes the function "showAnimation" at the beginning and executes the function "hideAnimation", when the request is done.

If you don't use jQuery and need pure javascript, simply replace $('#loadingicondiv') with the following code

document.getElementById('loadingicondiv').style.display = 'none'

Note: In case you have some frequent updating on your website, which you don't want to show that animation for, just make the displaying of the animation dependent from a global variable, which you set to false before sending those special requests, which you don't want the animation to be shown for. And don't forget to set it to true, when the request is done by them.

H.A.
  • 350
  • 5
  • 14
  • Of course I did answer that question. Just use that code and try to understand it, then you'll see that it works and maybe also understand how it works. The specific function is "ajaxStop(hideAnimation)" directly after "ajaxStart" function. – H.A. Jun 26 '23 at 13:35
  • The question isn't about Ajax nor jQuery – Martin Kirk Jun 27 '23 at 14:38
  • If you had understand the question, then you'd know, that although those words don't appear in the question and although the word Excel occurrs in the question, that the question is not about Excel, but about the behaviour of the page between sending a request and getting an answer from the server of a web application. And since his tags contain javascript, and since what he wants is not possible with javascript, but with jquery, my answer is the easiest possible answer to his question, because including jquery to a javascript application is a one line code. – H.A. Jun 30 '23 at 13:20