views:

1183

answers:

2

How can I create a validator that validates if the user inputed the same values in the password field and the password confirmation field?

I did it in the managed bean, but I prefer to do it using a JSF validator...

The real question is, how to create a validator that access other JSF components other than the component being validated?

I am using ADF Faces 11.

Thanks...

A: 

The real question is, how to create a validator that access other JSF components other than the component being validated?

Don't try to access the components directly; you'll regret it. JSF's validation mechanism work best at preventing junk from getting into the model.

You could use a different type of managed bean; something of the form:

/*Request scoped managed bean*/
public class PasswordValidationBean {
  private String input1;
  private String input2;
  private boolean input1Set;

  public void validateField(FacesContext context, UIComponent component,
      Object value) {
    if (input1Set) {
      input2 = (String) value;
      if (input1 == null || input1.length() < 6 || (!input1.equals(input2))) {
        ((EditableValueHolder) component).setValid(false);
        context.addMessage(component.getClientId(context), new FacesMessage(
            "Password must be 6 chars+ & both fields identical"));
      }
    } else {
      input1Set = true;
      input1 = (String) value;
    }
  }
}

This is bound using the method-binding mechanism:

<h:form>
  Password: <h:inputSecret
    validator="#{passwordValidationBean.validateField}"
    required="true" />
  Confirm: <h:inputSecret
    validator="#{passwordValidationBean.validateField}"
    required="true" />
  <h:commandButton value="submit to validate" />
  <!-- other bindings omitted -->
  <h:messages />
</h:form>

In future, you should be able to do this sort of thing using Bean Validation (JSR 303).

McDowell
Seems a little ugly, but that's ok
razenha
JSF validation works at the field level rather than the page (something JSF 2 + JSR 303 aims to change). The bean could probably be improved upon, though. The alternative would be a custom renderer and/or component, but that is perhaps too much work for something like this.
McDowell
A: 

You could always pull the value of your other fields from the context map and perform your validations on multiple fields. Something like below:

public void  validatePassword2(FacesContext facesContext, UIComponent uIComponent, Object object) throws ValidatorException{
    String fieldVal = (String)object;

    String password1 = (String)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("password1");
    if(!password1.equalsIgnoreCase(fieldVal)){
        FacesMessage message = new FacesMessage("Passwords must match");
        throw new ValidatorException(message);
    }
}   

and the jsf looks something like this:

<h:inputSecret value="#{profile.password2}" validator="#{brokerVal.validatePassword2}" required="true" requiredMessage="*required" id="password2" />

HTH

Romeo Foxtrot
This does not work vor me :( i have a bean with Bean.password and bean.password2 but if i validate password2 and try to get the password value i ever get null
Markus