Search code examples
jsfprimefacesrefresh

How to refresh a page after download


I have a commandButton that will invoke a function to download a file (standard stuffs like InputStream, BufferedOutputStream ...) After download success, at the end of the function, I change some values of the current object and persist it into database. All of these work correctly. Now when file is done downloading, the content of the page is not updated. I have to hit refresh for me to see updated content. Please help. Below are the basic structure of my code

document: Managed Bean
getDrawings(): method return a list of Drawing (entity class)
CheckedOutBy: attribute of Entity Drawing

<p:dataTable id="drawing_table" value="#{document.drawings}" var="item" >                            
    <p:column>
        <f:facet name="header">
              <h:outputText value="CheckedOutBy"/>
        </f:facet>
        <h:outputText value="#{item.checkedOutBy}"/>
        ...
</p:dataTable>
<p:commandButton ajax="false" action="#{document.Download}" value="Download" />

Inside my Managed Bean

public void Download(){
    Drawing drawing = getCurrentDrawing();
    //Download drawing
    drawing.setCheckedOutBy("Some Text");
    sBean.merge(drawing);  //Update "Some Text" into CheckedOutBy field
}

Solution

  • You can't return two HTTP responses to one HTTP request.

    To refresh the page after download, use PrimeFaces.monitorDownload() in JS API and invoke location.reload() in the end callback.

    <p:commandButton ... onclick="PrimeFaces.monitorDownload(null, stopDownload)">
        <p:fileDownload value="#{fileDownloadController.file}" />
    </p:commandButton>
    
    function stopDownload() {
        location.reload();
    }
    

    In case you're already on PrimeFaces 10.x or newer then <p:fileDownload> will support ajax (as noted by Jasper de Vries). You can use it to partially update the page.

    <h:outputText id="checkedOutBy" value="#{item.checkedOutBy}" />
    ...
    <p:commandButton ... update="checkedOutBy">
        <p:fileDownload value="#{fileDownloadController.file}" />
    </p:commandButton>
    

    In case you're not on PrimeFaces 4.x yet and thus can't find PrimeFaces.monitorDownload(), simply upgrade PrimeFaces.

    Alternatively, use <p:poll> to check for bean state.

    <h:outputText id="checkedOutBy" value="#{item.checkedOutBy}" />
    ...
    <p:poll ... interval="5" update="checkedOutBy" stop="#{not empty item.checkedOutBy}" />