Validation messages rendered multiple times after upload
blebleskeble Apr 4, 2013 8:29 AMHi. I am facing strange problem with combination of client side validation and file upload.
On my page I have input with client side validation on blur event. When validation fails, message is correctly displayed by rich:messages component. then if I upload file via rich:fileUpload and trigger validation again, message is displayed twice. After next upload three times etc. Can anyone tell me what I am doing wrong? If i submit input via button, server validator is triggered and message is rendered only once regardless on how many files i have uploaded.
(RF 4.2.0, myfaces 2.1.9, tomcat 7.0.30)
here is my page:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Upload and Messages</title>
</h:head>
<h:body>
<h:outputScript library="js" name="scripts.js" target="head" />
<h:form id="myForm">
<h:inputText id="inp" value="#{upload.inputString}" >
<f:validator validatorId="requiredValidator"/>
<rich:validator event="blur" />
</h:inputText>
<a4j:commandButton id="button" execute="inp" render="envelope" />
<br />
<a4j:outputPanel id="envelope">
<h:outputText value="#{upload.status}" />
<br />
<rich:fileUpload id="upload" fileUploadListener="#{upload.uploadListener}" >
<a4j:ajax event="uploadcomplete" render="envelope" />
</rich:fileUpload>
</a4j:outputPanel>
</h:form>
<rich:popupPanel id="messagePopup" left="500" top="20" show="true" modal="false" >
<rich:messages id="mess" />
</rich:popupPanel>
</h:body>
</html>
and here my managed bean
package bleble.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.richfaces.event.FileUploadEvent;
@SuppressWarnings("serial")
@ManagedBean(name = "upload")
@ViewScoped
public class UploadController implements Serializable {
private String inputString;
private File f = null;
private String status = "Waiting for file.";
public UploadController() {
}
public void uploadListener(final FileUploadEvent event) {
System.out.println("uploading");
String filename = event.getUploadedFile().getName();
try {
if (filename.contains("\\")) {
filename = filename.substring( event.getUploadedFile().getName().lastIndexOf("\\") + 1, event.getUploadedFile().getName().length());
}
f = File.createTempFile(filename , "");
FileOutputStream fos = new FileOutputStream(f);
FileInputStream fis = (FileInputStream) event.getUploadedFile().getInputStream();
byte buf[] = new byte[524288];
int len;
while ((len = fis.read(buf)) > 0) {
fos.write(buf, 0, len);
}
fos.close();
fis.close();
} catch (IOException e1) {
} finally {
if (f != null) {
status = "File " + f.getName() + " uploaded.";
}
}
}
public String getStatus() {
return status;
}
public String getInputString() {
return inputString;
}
public void setInputString(final String inputString) {
this.inputString = inputString;
}
}
this i my faces validator
package bleble.validator;
import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.faces.application.FacesMessage;
import javax.faces.application.ResourceDependency;
@SuppressWarnings("serial")
@FacesValidator(value = "requiredValidator")
@org.richfaces.javascript.ClientSideScript(function = "validateMandatory", resources = @ResourceDependency(name = "scripts.js", library = "js", target = "head"))
public class RequiredValidator implements Serializable, Validator {
@Override
public final void validate(final FacesContext context, final UIComponent component, final Object value) throws ValidatorException {
FacesMessage message = new FacesMessage();
message.setDetail("field is mandatory");
message.setSummary("Validation failed: field is mandatory! (server)");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
if (value == null || "".equals(value.toString().trim())) {
throw new ValidatorException(message);
}
}
}
and its client implementation in scripts.js
function mymessage(summary, detail, severity){
this.summary=summary;
this.detail=detail;
this.severity=severity;
}
function validateMandatory(value, label, params, msg) {
if (jQuery().trim(value) != "") {
return;
} else {
var myMess = new mymessage("Validation failed: field is mandatory! (client)", "field is mandatory", 2);
throw myMess;
}
}
all files are also attached in archive
-
messagesAndUpload.zip 2.5 KB