rich:graphValidator is a component which allows to perform Object validation. value attribute should be defined with the value binding to bean. In the result all the bean properties will be validated during validation phase. That allows you to validate all the object properties and not just ones which are submitted with the current request.
Simple but probably most common example of such kind of usage is shown below. Below is the simple sample of cross-field validation. Passwords getting validated according to constraints for every field and isPasswordEquals validation check if them are equals.
<!DOCTYPE html> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> <h:outputStylesheet> .red { color: red; } .green { color: green; } </h:outputStylesheet> <h:form id="form"> <rich:graphValidator value="#{passwordValidationBean}" id="gv"> <rich:panel header="Change password" style="width:500px"> <rich:messages for="gv" /> <rich:messages globalOnly="true" /> <h:panelGrid columns="3"> <h:outputText value="Enter new password:" /> <h:inputSecret value="#{passwordValidationBean.password}" id="pass" /> <rich:message for="pass" /> <h:outputText value="Confirm the new password:" /> <h:inputSecret value="#{passwordValidationBean.confirm}" id="conf" /> <rich:message for="conf" /> </h:panelGrid> <a4j:commandButton value="Store changes" action="#{passwordValidationBean.storeNewPassword}" /> </rich:panel> </rich:graphValidator> </h:form> </ui:composition>
package org.richfaces.demo.validation; import java.io.Serializable; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; import javax.validation.constraints.AssertTrue; import javax.validation.constraints.Size; @ManagedBean @SessionScoped public class PasswordValidationBean implements Cloneable, Serializable { private static final long serialVersionUID = 1952428504080910113L; @Size(min = 5, max = 15, message = "Password length must be between {min} and {max} characters.") private String password = ""; private String confirm = ""; @AssertTrue(message = "Different passwords entered!") public boolean isPasswordsEquals() { return password.equals(confirm); } public void storeNewPassword() { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successfully changed!", "Successfully changed!")); } public void setPassword(String password) { this.password = password; } public void setConfirm(String confirm) { this.confirm = confirm; } public String getPassword() { return password; } public String getConfirm() { return confirm; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }