Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

ajax - Conditionally provide either file download or show export validation error message

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?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

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 &amp;&amp; !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".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...