Multi Components Validator in JSF 2.0
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.








Dear friends and mkyong,
This is a great article. (@mkyong) Thank you for writing such a great and guiding article.
Since I am a starter validator programmer, I didn’t find my way of retrieving a selectOneMenu component.
The below is the xhtml code for my case in the view:
And I would like to retrieve that selectOneMenu component’s value by the following way (guided by your article) in my validator class:
However, I am retrieving null value in the metalCode variable while I can retrieve inputText components values perfectly .
I think for the retrieval of the selectOneMenu components, there should be a special treatment. What would you recommend?
Thank you.
Yours sincerely…