For an example think that you are creating a JSF page to enter employee details.
In that page you have two calendar components. One is to enter the join date and the other one is to enter the retired date of the employee.
So obviously join date should be earlier than the retired date. How do you validate whether join date is earlier than retired date and show a rich:message if validation failed?
1) Method 1 (For JSF users)
If you are not using JBoss SEAM, this method is for you. (Its obvious that SEAM users also can use this method.)
First, you have to create a validator class as below.
package inova;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class DateComparator implements Validator {
public void validate(FacesContext context, UIComponent component, Object date1) throws ValidatorException {
Date joinedDate = (Date) date1;
UIInput retiredDateComponent =
(UIInput) component.getAttributes().get("retiredDateComponent");
String dateString = (String) retiredDateComponent.getSubmittedValue();
System.out.println("dateString>" + dateString);
String pattern = "yyyy/MM/dd hh:mm";
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
Date retiredDate;
try {
retiredDate = dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
return;
}
System.out.println("retiredDate> " + retiredDate);
if (joinedDate == null || retiredDate == null) {
return;
}
if (joinedDate.compareTo(retiredDate) > 0) {
retiredDateComponent.setValid(false);
throw new ValidatorException(new FacesMessage("Retired date should be
greator than joined Date"));
}
}
}
<validator-id>dateComparator</validator-id>
<validator-class>inova.DateComparator</validator-class>
</validator>
If you are using a date pattern in your second calendar(end date) component, you have to use the same date pattern in your validator class.
Your page will be as below.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core">
<head></head>
<body>
<h:form>
Start date :
<rich:calendar id="cal_1">
<f:validator validatorId="dateComparator"/>
<f:attribute name="endDateComponent" value="#{endDate}"/>
</rich:calendar>
<br/>
End date : <rich:calendar binding="#{endDate}" datePattern="yyyy/MM/dd hh:mm"/>
<br/>
<rich:message for="cal_1" style="color:red;"/>
<br/>
<a4j:commandButton value="Save"/>
</h:form>
</body>
</html>
That is all. I think its clear for you what we have done.
♫ In our xhtml page we bind the 'end date calendar' component to the variable named as 'endDate' by using the 'binding' attribute of it.
♫ Then in our 'start date calendar' component, we use it as an attribute.
♫ In our validator class, we get that attribute by using the 'component.getAttributes().get(....)' method. Then we get the end date.
♫ If two dates are valid according to our criteria, we have nothing to do and if dates are invalid we throws a 'ValidatorException' with our own message.
2) Method 2(For seam users only)
This way is easier than the above method.
✱ The validator class is almost the same as above except three annotations are introduced before the class name as below.
@Name("dateComparator")
@org.jboss.seam.annotations.faces.Validator
@BypassInterceptors
public class DateComparator implements Validator {
..........
}
Enjoy......