15

When clicking a button, my GWT application returns a PDF file embedded in an HTML page which looks something like:

<html><head></head>
<body marginwidth="0" marginheight="0" bgcolor="rgb(38,38,38)">
<embed width="100%" height="100%" name="plugin"
    src="http://myserver/?cmd=getMyPdf" type="application/pdf">
</body>
</html>

Problem is it can take a while for the server to create this PDF file, so what I want is a waiting screen with a loading animation which can have the PDF file download in the background, and then when the file is done, display the page as described above.

One obvious way would be to display a loading page, send an asynchronous command to the server and then once the onSucceed method is called, call the page as normal. Downside is I'd have to add some server-side logic for making the PDF creation work in the background...

Is there any way to do this client-side with the GWT API?

Epaga
  • 38,231
  • 58
  • 157
  • 245
  • Vaadin, a GWT fork, has something like this builtin. You can do it for sure via js (jQuery, extJS or similar) – Daniel Voina Feb 27 '11 at 20:15
  • Do you want to display the waiting screen until A) the file is fully downloaded, or B) only until pdf generation is finished, and the client starts downloading? – Chris Lercher Feb 28 '11 at 09:25

2 Answers2

7

Did you see this stackoverflow question Detect when browser receives file download? Basically the answer given is that you set a cookie in the return response and wait on the client side for this cookie to be set. This can be done easily with GWT as it has a Scheduler (for the repeated timer check) and easy access to Cookies. You still need to make some server changes, but you don't have to create a background process.

Community
  • 1
  • 1
Hilbrand Bouwkamp
  • 13,509
  • 1
  • 45
  • 52
  • +1 Very nice hack :D For the presentation side of things, I'd recommend looking at [`PopupPanel`](http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/user/client/ui/PopupPanel.html) or its subclasses, instead of rolling out your own :) Or [`DialogBox`](http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/user/client/ui/DialogBox.html), if you need something more complex. – Igor Klimer Feb 26 '11 at 22:03
  • I just tried the solution, unfortunately it didn't work for me (on Mac/Safari and Mac/Chrome) - the cookie gets set right at the beginning of the download, long before the file has finished downloading. Did it work on your system/browser? – Chris Lercher Feb 27 '11 at 13:29
  • There are 2 phases here. First the generation phase, second the download phase. The problem here is related to the first problem: the time needed to generate the pdf file. The solution I referred to sets the cookie after creating the pdf, just before download starts. Normally when download starts the users sees this and knows it's working, while in the generation phase there is no feedback so hence the solution for that phase. – Hilbrand Bouwkamp Feb 28 '11 at 09:11
  • Good point - I always assumed, that both phases should be covered. If this is only about the generation phase, your solution works very well (just like mine) :-) – Chris Lercher Feb 28 '11 at 09:31
5

I don't have the full answer, but the following code works for me in Safari, and maybe you can modify it, to make it work with other browsers, too (?):

<html><head>
<script type="text/javascript">
  function showPdf() {
    document.getElementById("loading").style.visibility = "hidden";
    document.getElementById("pdf").style.visibility = "visible";
  }
</script>
</head>

<body marginwidth="0" marginheight="0" bgcolor="rgb(38,38,38)">
  <div id="loading"
    style="position: absolute; background-color: white;">Loading...</div>

  <iframe id="pdf" width="100%" height="100%" name="plugin"
    src="http://myserver/?cmd=getMyPdf" onload="javascript:showPdf();"
        style="visibility: hidden;"></iframe>
</body>
</html>

This is pure JavaScript - but could certainly be done with GWT, too. Note, that I'm using an iframe instead of embed, because embed doesn't really support the onload method (and embed is not a standard HTML element, as far as I remember).

The reason, why this may not be the full answer, is that Chrome fires the onload event as soon as the PDF starts downloading (but after the PDF generation on the server side has finished). I'm not sure, if this is what you want?

Chris Lercher
  • 37,264
  • 20
  • 99
  • 131