0

I have a form on my page that generates a large PDF file (can take up to 20 seconds). Is there a way to show a throbber while the download file is being created and to hide it when the download prompt appears?

I did some checking, initially thought I could use progressive display, but figured that's not its purpose.

I figured I could attach a JS function that will trigger showing my throbber when the "Download" button is clicked, but I'm not so sure how to hide it when the download window appears.

Is there a way to do this in Tapestry?

ioreskovic
  • 5,531
  • 5
  • 39
  • 70

2 Answers2

1

There's a restriction with HTTP in that you can't return a single response that contains the PDF and some json.

What you can do is:

  1. Submit the form (which has a zone parameter)
  2. Start an asynchronous job which generates the PDF
  3. Return immediately from the submit (before the PDF is generated)
  4. Start some javascript which polls the job until it is complete
  5. Once the job is complete, download the PDF via javascript (document.location.href = /path/to/pdf)

You can see the progresslink for an example of polling an asynchronous task. You'll need to store the PDF somewhere in the asynchronous task (ie session, database or file system).

lance-java
  • 25,497
  • 4
  • 59
  • 101
1

Possibly a better solution is to NOT submit the form. You could use javascript to construct a GET url and use an iframe.

eg:

<form>
    <input id="someText" />
    <button onclick="downloadPdf()">Click Me</button>
</form>

<script>
   function downloadPdf() {
      var url = "/path/to/pdf?someText=" + encodeURIComponent($("#someText").val());
      startThrobber();
      $('<iframe src="' + url + '" onLoad="stopThrobbber()">').appendTo('body');
   }
</script>
lance-java
  • 25,497
  • 4
  • 59
  • 101
  • This looks like it may work, however, I don't have the actual link to the PDF file, since the actual file does not exists – ioreskovic Feb 13 '14 at 14:27
  • Just create a tapestry page (or a component event) to generate the PDF and link to it. You can return a StreamResponse from onActivate() of a page. – lance-java Feb 13 '14 at 14:29
  • I'm not sure I follow you here correctly. Are you saying I should have a component event like this `myContextRoot/myPage/customevent:customparam` and have url point to that? – ioreskovic Feb 13 '14 at 14:40
  • I'd create a page which generates a PDF in it's `onActivate(EventContext)`. You can pass the form values to it via request parameters or via activation context. You can get the URL to the page via `Componentresources.createPageLink(...)`. – lance-java Feb 13 '14 at 14:47
  • Note, you could just as easily use a component event and generate the URL via `ComponentResources.createEventLlink(...)` – lance-java Feb 13 '14 at 15:50