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 :D
The simplest solution to prevent the form submission is to return false on submit event handler defined using the onsubmit property in the HTML <form> element.
What ever the reason, if you want to prevent the form submission on pressing Enter key, you can write the following function in javascript: $(document). ready(function() { $(window). keydown(function(event){ if(event.
A button element is valid anywhere in the document body where text-level markup may appear. Such an element need not have any relationship to a form element.
beside putting the "Back" button into an empty form, because now I have two buttons standing on top of each others
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 using display: inline;
in CSS.
Back to the actual problem, it however surprises me that the fileUploadListener
method is called in spite of the immediate="true"
in the p:commandButton
. I tried to reproduce this and I can confirm this. But I wouldn't expect it to happen. Normally the immediate="true"
on a button is the solution to skip submitting of the "whole" form (at least, skip the UIInput
components without this attribute). Further investigation learnt me that the p:fileUpload
isn't an UIInput
component 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:fileUpload
requires ajax="false"
on the p:commandButton
component, you can on the other hand also just remove it from the back button so that it fires an ajaxical request and hereby skips the fileUploadListener
being called.
Actually, putting the button in a different form sounds like an excellent solution. The reason the buttons don't align any more is that the new starting <form>
element starts on its own line. You should be able to prevent this by adding form { display: inline; }
to your CSS file.
That said, if you have some leftover error messages that you want to get rid of, you can do this in the initializing method of your backing bean (if you have one). The following works peachily:
public void clearErrorMessages() {
//it may get messy to debug why messages are swallowed
logger.debug("clearing messages, coming from " + new Exception().getStackTrace()[1]);
Iterator iter = FacesContext.getCurrentInstance().getMessages();
while (iter.hasNext()) {
FacesMessage msg = (FacesMessage) iter.next();
logger.debug("clearing message: " + msg.getDetail());
iter.remove();
}
}
The disadvantage here is that any errors that occur between submitting the form and initializing the backing bean of the target page are also swallowed.
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