I've been working on CRUD application, and I need to export data from database to csv file. In order to export, I had to disable ajax, in a manner shown in following code:
<p:commandButton value="Export" ajax="false" action="myController.export"/>
In the method invoked, I create the file and download it via OmniFaces utility method:
Faces.sendFile(file, true);
Using the same method, I check if there actually is any data, and if there isn't any data, warning dialog is shown:
RequestContext.getCurrentInstance().showMessageInDialog(new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning!", "No available data for export."));
Now, while all of this does work as intended, the problem is that because ajax is disabled, dialog cannot be dynamically shown, and page is reloaded. If ajax is enabled, dialog is shown dynamically, but file download doesn't start.
I've been trying to work around this issue, by using Monitor download, or by force clicking second button, but so far I haven't made any progress on the matter.
Is there any generally acceptable way of solving issues like this one?
Is there any generally acceptable way of solving issues like this one?
You basically want to fire an ajax request first and in its oncomplete check if it's successful, and then trigger a synchronous request to download the file (note that you can't download files with ajax). You could make use of FacesContext#validationFailed()
(or OmniFaces Faces.validationFailed()
) to mark the validation fail state which is available via args
object which PrimeFaces injects in the oncomplete
function context (note that ajax related attributes such as oncomplete
don't work when ajax is disabled).
Something like this:
<p:commandButton
value="Export"
action="#{bean.export}"
oncomplete="if (args && !args.validationFailed) PF('download').jq.click()" />
<p:commandButton
widgetVar="download"
styleClass="ui-helper-hidden"
action="#{bean.download}" ajax="false" />
public void export() {
// Prepare file locally.
if (fail) {
// Show message your way and then set validation failed as below.
Faces.validationFailed();
}
}
public void download() throws IOException {
Faces.sendFile(file, true);
// Delete local file afterwards?
}
Note that a hidden <p:commandButton>
is being used instead of <p:remoteCommand>
as the latter doesn't support ajax="false"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With