I have one jsf page containing many h:inputText
fields. Before submitting the form using h:commandButton
I want to check data in input fields is same or not using f:validator
in backing bean. How i can get the values of two inputText fields in backing bean??
-
@LucianovanderVeekens bean properties will get null because form is not submitted yet – suhas_n Sep 27 '17 at 18:29
-
What you effectively asking is a cross-field validator https://stackoverflow.com/questions/6282466/jsf-doesnt-support-cross-field-validation-is-there-a-workaround – Kukeltje Sep 27 '17 at 18:42
1 Answers
The validation mechanism in JSF was designed to validate a single component. However, in practice, you often need to ensure that related components have reasonable values before letting the values propagate into the model. For example, it is not a good idea to ask users to enter a date into a single textfield. Instead, you would use three different textfields, for the day, month, and year.
If the user enters an illegal date, such as February 30, you would like to show a validation error and prevent the illegal data from entering the model.
The trick is to attach the validator to the last of the components. By the time its validator is called, the preceding components passed validation and had their local values set. The last component has passed conversion, and the converted value is passed as the Object parameter of the validation method.
Of course, you need to have access to the other components. You can easily achieve that access by using a backing bean that contains all components of the current form. Simply attach the validation method to the backing bean:
public class BackingBean {
private int day;
private int month;
private int year;
private UIInput dayInput;
private UIInput monthInput;
private UIInput yearInput;
// PROPERTY: day
public int getDay() { return day; }
public void setDay(int newValue) { day = newValue; }
// PROPERTY: month
public int getMonth() { return month; }
public void setMonth(int newValue) { month = newValue; }
// PROPERTY: year
public int getYear() { return year; }
public void setYear(int newValue) { year = newValue; }
// PROPERTY: dayInput
public UIInput getDayInput() { return dayInput; }
public void setDayInput(UIInput newValue) { dayInput = newValue; }
// PROPERTY: monthInput
public UIInput getMonthInput() { return monthInput; }
public void setMonthInput(UIInput newValue) { monthInput = newValue; }
// PROPERTY: yearInput
public UIInput getYearInput() { return yearInput; }
public void setYearInput(UIInput newValue) { yearInput = newValue; }
public void validateDate(FacesContext context, UIComponent component, Object value) {
int d = ((Integer) dayInput.getLocalValue()).intValue();
int m = ((Integer) monthInput.getLocalValue()).intValue();
int y = ((Integer) value).intValue();
if (!isValidDate(d, m, y)) {
throw new ValidatorException(new FacesMessage("Invalid Date"));
}
}
private static boolean isValidDate(int d, int m, int y) {
//DO YOUR VALIDATION HERE
}
}
Here is your JSP
<html>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<f:view>
<head></head>
<body>
<h:form>
<h:panelGrid columns="3">
<h:inputText value="#{bb.day}" binding="#{bb.dayInput}" size="2" required="true"/>
<h:inputText value="#{bb.month}" binding="#{bb.monthInput}" size="2" required="true"/>
<h:inputText value="#{bb.year}" binding="#{bb.yearInput}" size="4" required="true" validator="#{bb.validateDate}"/>
<h:message for="year" styleClass="errorMessage"/>
</h:panelGrid>
<h:commandButton value="Submit" action="submit"/>
</h:form>
</body>
</f:view>
</html>

- 510
- 8
- 32
-
Heyy thanks @Araf. But that intValue() is only for integers. What to do if having Strings – suhas_n Sep 28 '17 at 03:15
-