Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

jsf - Show status on start of p:fileDownload and hide status when it is finished

I would like to display ajaxStatus while zipManager.makeZip() is executed... until the download starts. if ajax=false, the file download works but ajaxStatus not displayed. if ajax=true, ajaxStatus is displayed but download not working!

Any idea how to make the ajaxStatus and fileDownload work together.

Thanks in advance

kem

<h:form id="form">
    <p:commandLink id="download" value="Download"
        onstart="showStatus()" oncomplete="hideStatus()" 
        actionListener="#{zipManager.makeZip()}">
        <p:fileDownload value="#{zipManager.zip}"/>  
    </p:commandLink>
</h:form>

<p:ajaxStatus id="status" widgetVar="st" style="position:fixed;right:50%;bottom:50%">  
    <f:facet name="start">  
        <p:graphicImage value="images/wait.gif" />  
    </f:facet>  
</p:ajaxStatus>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

if ajax=false, the file download works but ajaxStatus not displayed

That's because the download doesn't take place by an ajax request.


if ajax=true, ajaxStatus is displayed but download not working!

That's because the download can't take place by an ajax request. JS/Ajax will successfully retrieve the file, but have no idea how to deal with it. There's no way to force a Save As dialogue with JS. There's no way to access the local disk file system with JS (it would otherwise have been a huge security breach).


Any idea how to make the ajaxStatus and fileDownload work together.

Use the PrimeFaces-provided PrimeFaces.monitorDownload() JS function. A complete example can be found on their own <p:fileDownload> showcase page which is copypasted below for reference (note particularly the onclick attribute of the file download command button):

<p:dialog modal="true" widgetVar="statusDialog" header="Status" 
    draggable="false" closable="false" resizable="false">  
    <p:graphicImage value="/design/ajaxloadingbar.gif" />  
</p:dialog>  

<h:form id="form">  
    <p:commandButton id="downloadLink" value="Download" ajax="false"
        onclick="PrimeFaces.monitorDownload(start, stop)"
        icon="ui-icon-arrowthichk-s">  
        <p:fileDownload value="#{fileDownloadController.file}" />  
    </p:commandButton>  
</h:form>  

<script type="text/javascript">  
    function start() {  
        statusDialog.show();  
    }  

    function stop() {  
        statusDialog.hide();  
    }  
</script>  

This can be applied in your particular case by changing the command link as follows:

<p:commandLink id="download" value="Download" ajax="false"
    onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)"
    actionListener="#{zipManager.makeZip()}">

and replacing the <p:ajaxStatus> by a simple <p:dialog> as demonstrated in showcase example.


This all works behind the scenes with a special cookie which is polled at short intervals by JS (every 100ms or so). During creating of the file download response, a special cookie will be set on its headers. Once the file download response headers arrives at the browser, then the cookie is set in the browser. When the JS poller finds it in the browser cookie space, then it closes the progess.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...