How to get the value of another component in a custom validator? [duplicate]

Just pass the whole component via <f:attribute>.

<h:form id="formId">
    <h:inputText value="#{bean.start}">
        <f:validator validatorId="rangeValidator" />
        <f:attribute name="endComponent" value="#{endComponent}" />
    </h:inputText>
    ...
    <h:inputText binding="#{endComponent}" value="#{bean.end}" />
    ...
</h:form>

(note: binding code is as-is, do NOT let it refer a bean property!)

with in validator

UIInput endComponent = (UIInput) component.getAttributes().get("endComponent");
Object endComponentValue = endComponent.getSubmittedValue();
// ...

Important note is that the components are processed, converted and validated in the order as they appear in the tree. Any submitted value of components which aren't converted/validated yet is available by UIInput#getSubmittedValue() and any of those which are already converted/validated is available by UIInput#getValue(). So, in your particular example, you should get the value by UIInput#getSubmittedValue() instead of UIInput#getValue().

If you'd like to work with the already converted and validated value as available by UIInput#getValue(), then you need to move the validator to the second component and then pass the first component along instead.

<h:form id="formId">
    <h:inputText binding="#{startComponent}" value="#{bean.start}" />
    ...
    <h:inputText value="#{bean.end}" />
        <f:validator validatorId="rangeValidator" />
        <f:attribute name="startComponent" value="#{startComponent}" />
    </h:inputText>
    ...
</h:form>
UIInput startComponent = (UIInput) component.getAttributes().get("startComponent");
Object startComponentValue = startComponent.getValue();
// ...

See also:

  • JSF doesn't support cross-field validation, is there a workaround?
  • Error validating two inputText fields together
  • Validator for multiple fields

You can just grab the other field's value from the request parameter map using the input field' name attribute. To get the name attribute of the input field do a view source to see what gets generated. See example below.

public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {
    String newPassword = fc.getExternalContext().getRequestParameterMap().get("centerForm:newPassword");
    String newPassword2 = (String) o;
    if(!newPassword.equals(newPassword2)){
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,"New Passwords do not match", null);            
        throw new ValidatorException(msg);            
    }
}