Question

I have a button which sets window.location to a php file which generates a feed which is then downloaded. However, as the files vary in size due to what data is put into the feed it can sometimes take a while from the click of the button to the file dialog popping up.

What I would like to be able to do is click the button and display a loading.gif until the dialog / file is complete.

Any ideas would be cool!

Cheers

Was it helpful?

Solution

Just make the RSS generating script show image you want (output image's HTML, then flush output buffer and start data generation). At the end of the data generation do:

<?php
print '<script>window.location = "http://www.newlocation.com"</script>'

That's all.

OTHER TIPS

I'm not really sure why you need to check the size of the file at all? If you use ajax to dynamically do the get/post, and all you are doing is trying to show a loading icon while this is happening, its fairly simple to throw up an asynchronous activity indicator. For instance, with jquery:

$("#loading").ajaxStart(function(){
   $(this).show();
});

$("#loading").ajaxStop(function(){
   $(this).hide();
});

$("#feeds").load("feeds.php?id=89734258972347895");

The above code sets a DOM object with id "loading" to show and hide when any asynchronous request has been initiated and stopped. .load(url) loads the content of the url into the div #feeds. If you are setting the content-disposition: attachment header with php, it will automatically initiate a file download window, even though it has been loaded asynchronously into a div. This is also possible without jquery of course, there's just a bunch of browser compatibility javascript and its not as easy as simply subscribing to the ajaxStart and ajaxStop events to show and hide your loading img.

Josh

before setting window.location you could display a hidden div with your gif

It's old school, but this can be done very easily with server push

<?php
  $separator = "end_of_section_marker";
  header('Content-type: multipart/x-mixed-replace;boundary=$separator');
  print "\n--$separator\n";
  print "Content-type: text/html\n\n";
  // Send placeholder message here
  print "--$separator\n";
  ob_flush();
  flush();
  // Start long processing here
  print "Content-type: text/html\n\n";
  // send data here
  print "--$separator--\n";
?>

Just adjust the content-types for the data you're sending. $separator can be any value so long as it does not appear in the data being sent.

A method I've used in the past works like this...

  • Set window.location to a loading page, and pass the destination page in the querystring. The loading page should display an animated gif or whatever you prefer to demonstrate that processing is taking place. The loading page should IMMEDIATELY redirect to the destination page passed in the querystring (along with any other applicable querystring parameters).

EDIT: The loading page should redirect to the destination page using javascript (set window.location to the URL provided in the querystring). This is an important point, because if you redirect on the server-side the loading page won't get displayed.

EDIT 2: If your loading page is a php file, you can check the to-be-downloaded file's size and display an estimated download time to the user (along with an animated "loading" gif), or whatnot.

  • The destination page should render with buffering enabled (call ob_start() before you render any content). With buffering enabled, nothing is sent to the browser until the entire page is rendered. Meanwhile your loading page from step 1 will continue to be displayed.

You will have to use AJAX to communicate to the server to discover the exact size of the file you are downloading. Then you have something to test against. There is no way to know the size of the expected payload from the client side only.

Is it possible for you to use an iframe to load the feed and then check the readyState of the iframe/document using an interval? So the process would be:

  • Load a window containing an iframe of width and height 100% and a loading.gif over the iframe.
  • Set a timer checking for the iframe.contentWindow.document.readyState property
  • Once readyState == complete, show the save file dialog.

One downside is, for most browsers the PHP file would need to be on the same domain (on IE you can just check the readyState property of the iframe).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top