In JSF 2.0, javax.faces.event.PostValidateEvent is a system event class which is fire after a component is validated. With some tricks, you can use this to implement multiple components / fields validator easily.

Idea…
1. Find out which components are required to perform the group validation.
2. Group it with a h:panelGrid component.
3. Attach a PostValidateEvent to the h:panelGrid component.
4. Now you are validate a h:panelGrid component, which consist of few components.

The following JSF 2.0 example is the implementation of above idea.

1. JSF Page

In this page, you created two h:inputText components, and group it with a h:panelGrid component, named “textPanel” and, attached a PostValidateEvent via f:event tag.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"   
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      >
 
	<h:body>
 
	 <h1>Multi Componenets Validator in JSF 2.0</h1>
 
	 <h:form>
 
		<h:message for="textPanel" style="color:red;" />
 
		<h:panelGrid columns="2" id="textPanel">
 
		    <f:event listener="#{user.validateTextBox}" type="postValidate" />
 
			Textbox 1 : enter "mkyong" :
			<h:inputText id="textbox1" value="#{user.textbox1}" />
 
			Textbox 2 : enter "123" :
			<h:inputText id="textbox2" value="#{user.textbox2}" />
 
		</h:panelGrid>
 
		<h:commandButton action="result" value="Submit" />
 
	</h:form>
 
	</h:body>
</html>

2. Managed Bean

The listener method for PostValidateEvent must have this method signature “public void method-name(ComponentSystemEvent event)“. Later, you can get back all the group components via ComponentSystemEvent class easily.

package com.mkyong;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
 
@ManagedBean(name="user")
@SessionScoped
public class UserBean{
 
	public String textbox1;
	public String textbox2;
 
	//getter and setter methods
 
	public void validateTextBox(ComponentSystemEvent event){
 
		FacesContext fc = FacesContext.getCurrentInstance();
 
		UIComponent components = event.getComponent();
 
		//get textbox1 value
		UIInput uiText1 = (UIInput)components.findComponent("textbox1");
		String text1 = uiText1.getLocalValue().toString();
 
		//get textbox2 value
		UIInput uiText2 = (UIInput)components.findComponent("textbox2");
		String text2 = uiText2.getLocalValue().toString();
 
		if(!"MKYONG".equals(text1.toUpperCase()) || (!"123".equals(text2))){
 
			FacesMessage msg = 
			  new FacesMessage("Textbox validation failed.", 
			    "Please enter 'mkyong' in Textbox1, '123' in Textbox2.");
 
                        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
 
			//components.getClientId() = textPanel
			fc.addMessage(components.getClientId(), msg);
 
			//passed to the Render Response phase
			fc.renderResponse();
		}
 
	}
}

How it works
In this case, when form is submitted, it will call listener method “validateTextBox(ComponentSystemEvent event)” to make sure the textbox1 = “MKYONG” and textbox2 = “123″, if not, set a FacesMessage and display it immediately.

3. Demo

If invalid text is entered, display the error message which is generated by #{user.validateTextBox} above.

jsf2-multi-components-validator-example

Download Source Code

Reference

  1. JSF 2 PostValidateEvent JavaDoc
  2. JSF 2 PreValidateEvent JavaDoc
Note : You can find more similar articles at - JSF 2 Tutorials