Cross field validation in jsf h:datatable using p:calendar
- by Matt Broekhuis
I noticed this question was asked, but it has not been answered correctly.
I have a datatable that has two columns start date and end date. Both contain primefaces p:calendar controls in them. I need to ensure that for each row that the date in column1 is not after the date in column2. I would like to tie this into the JSF validation framework, but I'm having trouble.
i've tried marking the datatable rowStatePreserved="true" , this allows me to get the values, but something is still wrong as when it fails, all the values in the first row overwrite all the other values. What am I doing wrong, or should I be using a completely different strategy?
xhtml code
<h:form>
<f:event type="postValidate" listener="#{bean.doCrossFieldValidation}"/>
<p:dataTable id="eventDaysTable" value="#{course.courseSchedules}" var="_eventDay" styleClass="compactDataTable"
>
<p:column id="eventDayStartColumn">
<f:facet name="header">
Start
</f:facet>
<p:calendar id="startDate" required="true" value="#{_eventDay.startTime}" pattern="MM/dd/yyyy hh:mm a"/>
</p:column>
<p:column id="eventDayEndColumn">
<f:facet name="header">
End
</f:facet>
<p:calendar id="endDate" required="true" value="#{_eventDay.endTime}" pattern="MM/dd/yyyy hh:mm a"/>
</p:column>
</p:dataTable>
</h:form>
validationCode
public void doCrossFieldValidation(ComponentSystemEvent cse) {
UIData eventsDaysStable = (UIData) cse.getComponent().findComponent("eventDaysTable");
if (null != eventsDaysStable && eventsDaysStable.isRendered()) {
Iterator<UIComponent> startDateCalendarIterator = eventsDaysStable.findComponent("eventDayStartColumn").getChildren().iterator();
Iterator<UIComponent> endDateCalendarIterator = eventsDaysStable.findComponent("eventDayEndColumn").getChildren().iterator();
while (startDateCalendarIterator.hasNext() && endDateCalendarIterator.hasNext()) {
org.primefaces.component.calendar.Calendar startDateComponent = (org.primefaces.component.calendar.Calendar) startDateCalendarIterator.next();
org.primefaces.component.calendar.Calendar endDateComponent = (org.primefaces.component.calendar.Calendar) endDateCalendarIterator.next();
Date startDate = (Date) startDateComponent.getValue();
Date endDate = (Date) endDateComponent.getValue();
if (null != startDate && null != endDate && startDate.after(endDate)) {
eventScheduleChronologyOk = false;
startDateComponent.setValid(false);
endDateComponent.setValid(false);
}
}
if (!eventScheduleChronologyOk) {
showErrorMessage(ProductManagementMessage.PRODUCT_SCHEDULE_OUT_OF_ORDER);
}
}
}