rich:calendar and rich:ajaxValidator problem
gs_noe Nov 9, 2009 7:43 PMI'm trying to use a custom validator along with a rich:ajaxValidator for the rich:calendar component. I'm using the rich:calendar's "ondateselected" event in the rich:ajaxValidator. The problem I'm having is that the first time the ondateselected event is fired, the default value for the rich:calendar is sent to the validator instead of the selected value. The second time the event is fired the correct value goes to the validator.
Am I missing something obvious?
I'm using RichFaces-3.3.2-SR1, JSF 1.2, Tomcat 6.0.20.
My abbreviated page:
<!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"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<ui:composition>
<a4j:form id="reportForm" >
<rich:panel header="I am the header">
<a4j:region id="criteriaContainer">
<rich:messages>
<f:facet name="errorMarker">
<h:graphicImage styleClass="errorMarker" value="/icons/exclamation.png" />
</f:facet>
<f:facet name="infoMarker">
<h:graphicImage styleClass="errorMarker" value="/icons/information.png" />
</f:facet>
</rich:messages>
<h:panelGrid columns="2" columnClasses="pgValignTop pgBoldText, pgPadLeft15 pgColAlignLeft" rowClasses="pgRowClass">
...
<h:column id="colAsOfDateLab">
<h:outputLabel value="#{rptMsg.report_asof_date_label}" title="#{rptMsg.report_asof_date_title}" for="calAsOfDate" />
</h:column>
<h:column id="colAsOfDateInp">
<rich:calendar id="calAsOfDate" value="#{reportBean.asOfDate}" showWeeksBar="false"
disabled="#{reportBean.selectedPolicyYear lt 0}" datePattern="MM/dd/yy hh:mm a">
<f:validator validatorId="reverseDateValidator" />
<rich:ajaxValidator event="ondateselected" id="calDateValidator" attachTo="calAsOfDate" />
</rich:calendar>
</h:column>
...
<h:column id="colButtonLab">
<h:outputText value=" "/>
</h:column>
<h:column id="colButtonInp">
<a4j:commandButton action="#{reportBean.executeReportAction}"
value="#{rptMsg.btn_run_rpt_label}" title="#{rptMsg.btn_run_rpt_title}"
disabled="#{reportBean.reportTypeSelected}"
reRender="resultIncludeContainer,criteriaContainer"
status="resultStatus" id="rptRunBtn"
onclick="document.getElementById('resultIncludeContainer').style.display='none';"
onbeforedomupdate="document.getElementById('resultIncludeContainer').style.display='';"/>
<a4j:commandButton action="#{reportBean.clearReportAction}"
value="#{rptMsg.btn_clr_rpt_label}" title="#{rptMsg.btn_clr_rpt_title}"
disabled="false" reRender="resultIncludeContainer,criteriaContainer"
status="resultStatus" id="rptClearBtn" onclick="" onbeforedomupdate=""/>
</h:column>
</h:panelGrid>
</a4j:region>
</rich:panel>
<br/>
<rich:panel header="#{rptMsg.report_result_panel_header}" id="resultPanel">
<a4j:region id="resultRegion">
...
</a4j:region>
</rich:panel>
</a4j:form>
</ui:composition>
</html>
Here's the validator
public class ReverseDateValidator implements Validator {
public ReverseDateValidator() {}
public void validate(FacesContext arg0, UIComponent arg1, Object value) throws ValidatorException {
Date inDate = null;
// Check type
if (value instanceof Date) {
inDate = (Date)value;
} else if (value instanceof String) {
try {
SimpleDateFormat formatter = new SimpleDateFormat(WS_DATE_FORMAT);
String strDate = (String)value;
inDate = formatter.parse(strDate);
} catch (ParseException e) {
// Bad date format
throw new ValidatorException(message);
}
} else {
// Value is of an unexpected type
throw new ValidatorException(message);
}
// At this point we should have a valid date.
if (inDate.after(new Date())) {
// Date is wrong.
throw new ValidatorException(message);
}
}
}