I will try to be as brief as possible, please stay with me here
“A.jsf” -> managed bean : bean
“#{bean.list}”: will take us to B.jsf
<p:growl id="msgs" showDetail="true"/>
<h:form id="myform1" enctype="multipart/form-data">
<p:panel header="Upload" style="font-size: 11px;">
<h:panelGrid columns="2" cellpadding="10">
<h:outputLabel value="Drawing:" />
<p:fileUpload fileUploadListener="#{bean.handleFileUpload}" update="msgs" allowTypes="*.*;"/>
</h:panelGrid>
<p:commandButton ajax="false" immediate="true" id="back" value="Back" action="#{bean.list}"/>
<p:commandButton ajax="false" id="persist" value="Persist" action="#{bean.handleRevision}" />
</p:panel>
</h:form>
Then the handleFileUpload()
if(!upload){
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "You do not have permission to upload.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
...
“B.jsf” -> managed bean: bean2
...
<p:growl id="msgs" showDetail="true"/>
...
When I click upload, it give me a growl error message “You do not have permission to upload.”, which is good. But then when I click “Back”, which will take me to B.jsf, I see the growl message “You do not have permission to upload.” again. What seem to be happening is as I click the “Back”, I send other form request to upload, which then generated the same error message, which then being displayed at B.jsf. Is there a way to fix this, beside putting the “Back” button into an empty form, because now I have two buttons standing on top of each others, instead of side by side. I try to do this:
FacesContext.getCurrentInstance().addMessage("tom", msg);
hoping that it would send to component with id=”tom”, so then the growl with id=msgs, would not get load, but no luck. I try to turn the upload flag on when I click the Back button, but the web form get requested before the method that handle the back navigation get called.
It is not as brief as I want it to be, therefore I want apologize for it 😀
The HTML
<form>is by default a block element. HTML block elements are by default been placed in a new line. You actually want to make it an inline element. You can do this usingdisplay: inline;in CSS.Back to the actual problem, it however surprises me that the
fileUploadListenermethod is called in spite of theimmediate="true"in thep:commandButton. I tried to reproduce this and I can confirm this. But I wouldn’t expect it to happen. Normally theimmediate="true"on a button is the solution to skip submitting of the “whole” form (at least, skip theUIInputcomponents without this attribute). Further investigation learnt me that thep:fileUploadisn’t anUIInputcomponent at all and that the listener is fired during apply request values phase instead of validations or update model values phase. So this behaviour is fully predictable, but imo still an oversight in the design.Since the
p:fileUploadrequiresajax="false"on thep:commandButtoncomponent, you can on the other hand also just remove it from the back button so that it fires an ajaxical request and hereby skips thefileUploadListenerbeing called.