Problem Statement
Let’s say that we want to trigger an ajax request when the user changes the value in a <rich:calendar />, but it has to work when the user types the date into the text field manually, as well as when the user uses the calendar to pick the date.
<rich:calendar /> defines two events just for this purpose:
- “change”: Triggered when the date is changed from the calendar
- “inputchange”: Triggered when the text in the text field is changed manually
But how do we combine them?
Solution
I already had my calendar inside a Composite JSF Component, so my solution uses the following approach.
YourWebApp/WebContent/resources/components/calendar.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.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:c="http://java.sun.com/jsp/jstl/core"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="value" required="true" />
<composite:attribute name="timeZone" required="true" />
<composite:attribute name="disabled" default="false" />
<composite:attribute name="displayValueOnly" default="false" />
<composite:attribute name="required" />
<composite:clientBehavior name="date_change" event="change" targets="#{cc.id}"/>
<composite:clientBehavior name="date_change" event="inputchange" targets="#{cc.id}"/>
</composite:interface>
<composite:implementation>
<c:if test="#{cc.attrs.displayValueOnly == false}">
<rich:calendar id="#{cc.id}"
inputSize="10"
required="#{cc.attrs.required}"
enableManualInput="true"
value="#{cc.attrs.value}"
disabled="#{cc.attrs.disabled}"
datePattern="yyyy-MM-dd"
onchange="if (DirtyFieldHandler) DirtyFieldHandler.setDirty();">
<f:convertDateTime pattern="yyyy-MM-dd" timeZone="#{cc.attrs.timeZone}" />
</rich:calendar>
</c:if>
<c:if test="#{cc.attrs.displayValueOnly == true}">
<h:inputText value="#{cc.attrs.value}" disabled="true" id="#{cc.id}InputDate" size="10">
<f:convertDateTime pattern="yyyy-MM-dd" timeZone="#{cc.attrs.timeZone}" />
</h:inputText>
</c:if>
</composite:implementation>
</html>
Then we use the component like so:
<comp:calendar value="#{backingBean.approvedDate}">
<a4j:ajax event="date_change" execute="@this" />
</comp:calendar>
I’m trying to pass a4j:ajax does not work though, only with f:ajax is working, can you give me some light?
You don’t need be a ‘composite:clientBehavior’. Above my consideration
When ‘xxx’ will be your JSEvent, (change, blur, etc.)
For me Works fine in JSF 2.0 and RichFaces 4.x