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