Problem with <f: validator> and ajax in JSF
I want to validate two dates on a form before the user takes an action. So I got f: validator inside p: calendar working with ajax, the problem is with the f: attribute. I am passing the start date as a parameter and the validator does not receive this date. However, if you click the action button, the date parameter will be set in the validation. I am using this post as a guide. My xhtml:
<p:column >
<p:calendar id="txtStartDate" binding="#{txtStartDate}"
pattern="dd/MM/yyyy"
value="#{myBean.bean.startDate}">
</p:calendar>
</p:column>
<p:column>
<p:calendar id="txtEndDate"
pattern="dd/MM/yyyy"
value="#{myBean.bean.endDate}">
<f:validator validatorId="validator.dateRangeValidator" />
<f:attribute name="fromDate" value="#{txtStartDate.value}" />
<p:ajax event="dateSelect" execute="@Form" update=":formHeader:messages" />
</p:calendar>
</p:column>
And the validator:
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (value == null || component.getAttributes().get("fromDate") == null) return;
Date endDate = (Date) value;
Date startDate = (Date) component.getAttributes().get("fromDate");
if (!endDate.after(startDate)) {
FacesMessage message = new FacesMessage("End date before the start date.");
message.setSeverity(FacesMessage.SEVERITY_ERROR);
addMessageOnSession(FacesMessage.SEVERITY_ERROR, "Invalid dates");
throw new ValidatorException(message);
}
}
Appreciate any help with this.
source to share
If you are using Primefaces there is a problem sending the parameter. They don't support the date.
Your code:
Date startDate = (Date) component.getAttributes().get("fromDate");
You should get the date as UIInput and parse it.
final UIInput startDate = (UIInput) component.getAttributes().get("fromDate");
final String dateFromString = (String) String.valueOf(startDate.getValue());
final SimpleDateFormat parserSDF = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
final Date parsedDateTo = parseDate(parserSDF, dateFromString);
To update your form use:
execute="@this" render="yourFormId"
Next tip:
You can change f:ajax event="dateSelect"
to f:ajax event="change"
to manually enter the change date. It also works like a date picker too.
source to share