How to write a validator that compares two fields
chawax Oct 9, 2007 10:52 AMHi,
I need to write a JSF validator which compares two fields. It could be used for example to compare "new password" and "confirm password" fields.
To do this, I wrote the following class :
@Name (value="validator.compareFields")
@org.jboss.seam.annotations.faces.Validator
public class CompareFieldsValidator implements Validator {
 private @In FacesMessages facesMessages;
 public void validate(FacesContext context, UIComponent cmp, Object value)
 throws ValidatorException
 {
 String compareTo = (String) cmp.getAttributes().get("compareTo");
 UIInput input = (UIInput) cmp.findComponent(compareTo);
 String otherValue = (String) input.getSubmittedValue();
 boolean error = false;
 if (value != null) {
 if (! value.equals(otherValue)) error = true;
 }
 else {
 if (otherValue != null) error = true;
 }
 if (error) {
 facesMessages.addToControlFromResourceBundle(cmp.getId(), "error.fieldsNotEqual", null);
 throw new ValidatorException(new FacesMessage());
 }
 }
}Then in my JSF, I use it this way :
<h:outputLabel value="New password :" for="newPassword" />
<h:inputSecret id="newPassword" value="#{userCrud.newPassword}">
 <f:validator validatorId="validator.compareFields" />
 <f:attribute name="compareTo" value="confirmPassword" />
</h:inputSecret>
<h:outputLabel value="Confirm password :" for="confirmPassword" />
<h:inputSecret id="confirmPassword" value="#{userCrud.confirmPassword}" />It works well except when my inputSecret fields are surrounded by <s:decorate>.
<s:decorate template="/decorateField.xhtml">
 <h:inputSecret id="newPassword" value="#{userCrud.newPassword}">
 <f:validator validatorId="validator.compareFields" />
 <f:attribute name="compareTo" value="confirmPassword" />
 </h:inputSecret>
</s:decorate>In this case, the UIComponent.findComponent() can't find the field corresponding to "compareTo" attribute. For what I understood, it works only if the two fields to compare have the same parent in JSF components tree (while I thought findComponent was searching recursively the component). Anyone knows how I could make it work ?
Note also that I'm not sure the way I used facesMessages object, especially the way I throw ValidatorException. I couldn't find an example with message in a resource bundle. So please tell me if there's a better way to write it.
Thanks in advance
 
     
    