Reputation: 17172
I'm trying to create a <p:ajaxstatus />
like indicator when downloading a file using OmniFaces Faces.sendFile
function. When the user clicks the Export link a dialog tells them the file is being created (because this can take sometime depending on the data size), then after the file downloads the message closes.
In my xhtml:
<p:dialog widgetVar="excelDialog" modal="true">
<h2>Building Spreadsheet</h2>
</p:dialog>
<h:commandLink value="Export" action="#{resultsBean.excelExport}" onclick="excelDialog.show();" />
and in my ViewScoped bean:
public void excelExport() throws IOException {
ExcelExport ee = new ExcelExport(results);
Faces.sendFile(ee.getFile(), true);
}
What I can't figure is how I could close the dialog after the response is complete.
I've tried using the PrimeFaces RequestContext (which should work for non-ajax requests) but does not work. I wonder if this is because Faces.sendFile
calls FacesContext.responseComplete()
before the RequestContext is used.
public void excelExport() throws IOException {
ExcelExport ee = new ExcelExport(results);
Faces.sendFile(ee.getFile(), true);
RequestContext c = RequestContext.getCurrentInstance();
c.execute("PF('excelDialog').hide();");
}
Upvotes: 0
Views: 2237
Reputation: 1108792
I wonder if this is because
Faces.sendFile
callsFacesContext.responseComplete()
before the RequestContext is used.
It just prevents the download file content from being corrupted because something else's trying to write more data to the response.
You're basically trying to send multiple responses on a single request. This is not possible. You can send only one response back per request. If your attempt were possible, the download file content would be corrupted because some XML code representing a PrimeFaces ajax response would be appended to the end of the download file content.
You basically need to send 2 requests whereby the 2nd request is fired automatically on end of 1st request. The 1st request should prepare the file and park it somewhere (property of @ViewScoped
bean?) and then close the dialog and trigger the 2nd request. The 2nd request should just download the parked file. The 1st request can be done by ajax like with <p:commandButton>
, but the 2nd request must be fully synchronous for obvious reasons. You can perform the 2nd request using a <h:commandLink>
which is hidden using CSS.
E.g.
<h:form id="formId">
<p:commandLink value="Export" action="#{resultsBean.excelExport}"
onclick="excelDialog.show();"
oncomplete="excelDialog.hide(); document.getElementById('formId:linkId').click();" />
<h:commandLink id="linkId" action="#{resultsBean.excelDownload}" style="display:none;" />
</h:form>
with
private File excelFile;
public void excelExport() {
excelFile= new ExcelExport(results).getFile();
}
public void excelDownload() throws IOException {
Faces.sendFile(excelFile, true);
}
Upvotes: 4