0

I need to show in another tab the generate Report with bean method (bean.generateReporte()). And show a message when the Report is not possible to be generated (not data is found according to criteria).

my first code in the .xhtml was:

<p:commandButton id="printDeliveryList" label="Generate Delivery List" styleClass="btn-success"
     style="float:left" icon="fa fa-print" 
     action="#{bean.generateReporte()}"
     onclick="this.form.target = '_blank'"
     ajax="false"
 />

I was reading this question How to prevent commandButton from executing action when onclick method return false and this question How to call JS function on click of JSF button and block page reload/navigation? and this post https://www.adictosaltrabajo.com/2011/09/14/primefaces-client-side-ajax-events/ And this documentation https://www.primefaces.org/showcase/ui/misc/requestContext.xhtml

I was thinking in onsuccess event.

Here my code later....

In the bean side I have:

public void generateReporte() {
    // blabla
    if (success) {
        addGeneratedToCallback(true);
    } else {
        addGeneratedToCallback(false);
    }
}

private void addGeneratedToCallback(boolean value) {
    PrimeFaces.current().ajax().addCallbackParam("generated", value);
}

In the .xhtml side

<script type="text/javascript">
    function handleComplete(xhr, status, args) {
        if (args.validationFailed) {
            PrimeFaces.debug("Validation Failed");
        } else {
            if (args.generated) {
                // open a new tab in the browser
                //window.open(this.form.target = '_blank');
                form.target = '_blank';
            } else {
                // show message
            }
        }
    }
</script>


<p:commandButton id="printListaEntrega" label="Generar Lista de Entrega" styleClass="btn-success"
                 style="float:left" icon="fa fa-print" 
                 action="#{bean.generateReporte()}"
                 ajax="false"
                 oncomplete="handleComplete(xhr, status, args)"
                 />

The Result of my code

With ajax="false" I got this when the generation of Report is not possible. enter image description here

When I remove ajax="false" from the p:commandButton and the report is generated I got. (Not open the new tab in browser And Can't download the report) enter image description here

Is it possible to set contitional ajax="bean.someMethodOrProperty"?

joseluisbz
  • 1,491
  • 1
  • 36
  • 58
  • I fail ro see what you are actually asking, or rather, why you want to solve aomethibg this way? – Kukeltje Jul 11 '19 at 05:55
  • @Kukeltje sorry yesterday I need to leave the office, but I edited my question. – joseluisbz Jul 11 '19 at 12:49
  • I feel this is a http://xyproblem.info Can you state what you want to achieve functional wise? – Kukeltje Jul 11 '19 at 14:08
  • https://stackoverflow.com/questions/37519295/jsf-file-download-exception-handling-how-to-prevent-view-rerendering – Kukeltje Jul 11 '19 at 14:37
  • Possible duplicate of [JSF file download exception handling (how to prevent view rerendering)](https://stackoverflow.com/questions/37519295/jsf-file-download-exception-handling-how-to-prevent-view-rerendering) – Kukeltje Jul 11 '19 at 14:38
  • This is better: https://stackoverflow.com/questions/32591795/conditionally-provide-either-file-download-or-show-export-validation-error-messa – Kukeltje Jul 11 '19 at 14:40
  • You are very welcome. Thank you for the appreciation. Great incentive to help in the future. – Kukeltje Jul 11 '19 at 18:55

1 Answers1

0

In the .xhtml

<p:commandButton id="printDeliveryList" label="Generate Delivery List" styleClass="btn-success"
                 style="float:left" icon="fa fa-print" 
                 action="#{bean.generateReport()}"
                 oncomplete="if (args &amp;&amp; !args.validationFailed) {PF('download').jq.click();PF('openNewTab').jq.click() }"
                 />
<p:commandButton widgetVar="download" styleClass="ui-helper-hidden" 
                 action="#{bean.downloadFile()}" ajax="false" />
<p:commandButton widgetVar="openNewTab" styleClass="ui-helper-hidden" 
                 action="#{bean.openInNewTab()}" 
                 onclick="this.form.target = '_blank'" ajax="false" />

in the bean

public void generateReport() {
    // blabla
    if (success) {
        bytesToBeDownload = getBytesOfReport();
        nameOfFile = getNameOfReport() + ".pdf";
    } else {
        Faces.validationFailed();
    }
}


public void downloadFile() {
    try {
        // byte[] bytesToBeDownload = ....
        org.omnifaces.util.Faces.sendFile(bytesToBeDownload, nameOfFile, true);
    } catch (IOException e) {
        //Exception handling
    }
}


public void openInNewTab() {
    try {
        byte[] bytes = bytesToBeDownload;
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length);
        baos.write(bytes, 0, bytes.length);
        buildResponse(baos, "application/pdf");
    } catch (Exception e) {
        //Exception handling
    }
}


private static void buildResponse(ByteArrayOutputStream out, String contentType) {

    ByteArrayInputStream input = null;
    BufferedOutputStream output = null;

    try {

        input = new ByteArrayInputStream(out.toByteArray());
        int bufferSize = out.toByteArray().length;

        FacesUtils.getHttpServletResponse().reset();
        FacesUtils.getHttpServletResponse().setHeader("Content-Type", contentType);
        FacesUtils.getHttpServletResponse().setHeader("Content-Length", String.valueOf(bufferSize));
        output = new BufferedOutputStream(FacesUtils.getHttpServletResponse().getOutputStream(), bufferSize);

        byte[] buffer = new byte[bufferSize];
        int length;
        while ((length = input.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        output.flush();

    } catch (Exception ex) {
        //Exception handling
    } finally {
        try {
            output.close();
            input.close();
        } catch (Exception ex) {
        //Exception handling
        }
    }
    FacesUtils.getFacesContext().responseComplete();
}
joseluisbz
  • 1,491
  • 1
  • 36
  • 58
  • Great you solved it. But when you answer (effectively not really needed since the question seems to be a full duplicate) adding a little text as an explanation what happens where and why would be very much appreciated by others. Adding explicit references to the posts you used (giving credits to the others and also upvoting the other Q/A's) is a good thing to do as well.! – Kukeltje Jul 11 '19 at 18:50
  • @Kukeltje Thank you. I need to do one of two (erase the question or edit the question/answer). I'm really ashamed. But What is your recommendation about of this? To Edit it, in order to related the answer based on (or from of), I think is needed. – joseluisbz Jul 12 '19 at 13:35