[jboss-user] [JBoss Seam] - How to write a validator that compares two fields

chawax do-not-reply at jboss.com
Tue Oct 9 10:53:00 EDT 2007


Hi,

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

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4093072#4093072

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4093072



More information about the jboss-user mailing list