0

The situation: I need to capture a screenshot of the screen with html2canvas, get the resulting dataURL, send it to a backing bean, generate a JasperReport with the picture, and open the download dialog so the user can download a PDF with a picture of the screen in it.

My attempted solution (which is not working 100%):

This is the command link that does everything:

<p:commandLink ajax="true" value="Print PDF" onclick="printPDF();" oncomplete="clickPrintButton();" />

The printPDF() function in my javascript file:

function printPDF() {

    html2canvas($('#mainForm'), {
        onrendered : function(canvas) {
            var dataURL = canvas.toDataURL("image/png");
            var hiddenField = document.getElementById('mainForm:dataURLfield');
            hiddenField.setAttribute('value', dataURL);
            hiddenField.onchange(); 
        }
    });
}

As you can see, I send the dataURL value to a hidden field and call the onchange() event. This is my hidden field:

<h:inputText id="dataURLfield" style="display:none">
    <f:ajax event="change" listener="#{myController.printPDFListener}" />
</h:inputText>

In the listener for the change event I set a property in myController with the value of the dataURL. After the ajax completes, the image is supposed to be properly saved in my backing bean, and I should be able to generate the report and start the file download.

The function that is called on the 'oncomplete' event:

function clickPrintButton(){
    var hiddenButton = document.getElementById('mainForm:printPDFButton');
    hiddenButton.click();
}

The hidden button which is supposed to start the file download:

<h:commandButton ajax="false" id="printPDFButton" style="display:none">
    <p:fileDownload value="#{myController.downloadPDF}" />
</h:commandButton>

The problem is, sometimes it works, sometimes it doesn't, sometimes I get an error in the page, sometimes I get a blank PDF. What do you guys think? Any ideas?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Koz
  • 151
  • 2
  • 14
  • 1
    I do not use `` to download files but give it a try with `` instead. (additionally, `` does not have the `ajax` attribute. It always sends a synchronous POST request unless `` is properly used which in turn cannot work while downloading files). – Tiny Oct 14 '15 at 03:01
  • 1
    Hard to answer without having a MCVE and a copypaste of that error message (errors are answers! never ignore them if you can't interpret them, but share with us so we can translate them in layman's terms). Here's at least a related Q: http://stackoverflow.com/q/32591795 – BalusC Oct 14 '15 at 09:31

1 Answers1

1

I think the problem is html2canvas is an asynchronous operation. So, the printPDF() method returns immediatly, potentially before complete generation. And then the oncomplete="clickPrintButton(); event raises too early.

To check that, you could add some "console.writeline()", for example at the end of the "printPDF()" method and in the "onrendered" callback, to see if the first one is sometime raised before the second one.

I think to solve your problem you'll probably have to move your clickPrintButton() call, to launch it only when you are sure html2canvas has finished.

Elo
  • 2,234
  • 22
  • 28
  • Yes! That appears to be the problem! the method is returning before html2canvas is finished. Thank you. – Koz Oct 14 '15 at 13:42