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