0
votes

I am writing a JSF datepicker composite component that is backed by jquery-ui's datepicker.(I don't have the option of using component libraries)

I have gotten the functionality to work, but I am now trying to simplify the component's interface by removing unnecessary attributes.

One of the attributes exposed by my component is called "value". I expect the user of the component to provide an el reference here eg. #{myCarBean.selectedCar}

What I have noticed is that the component only ever seems to read the attribute's value. The setter never seems to get invoked.

I managed to get around this by exposing this method as a clientBehaviour . But now I have an actionListener that is invoked through this clientBehaviour(to set the value) as well as the "value" attribute which reads the value from #{cc.attrs.values}.

How can I have a single attribute that can both read/write the "value" attribute to the underlying managedBean provided by the using page?

Here is the code:

<ui:component xmlns="http://www.w3.org/1999/xhtml" xmlns:util="http://discovery.co.za/mytags" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface componentType="modal">
    <cc:attribute name="value" type="java.util.Date" shortDescription="An El expression representing the managed bean field to which the selected date will be wired."></cc:attribute>
    <cc:attribute name="minYear" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the year component of the minDate"></cc:attribute>
    <cc:attribute name="minMonth" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the month component of the minDate.(January is 0)"></cc:attribute>
    <cc:attribute name="minDay" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the day component of the minDate."></cc:attribute>
    <cc:attribute name="maxYear" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the year component of the maxDate"></cc:attribute>
    <cc:attribute name="maxMonth" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the month component of the maxDate"></cc:attribute>
    <cc:attribute name="maxDay" type="java.lang.Integer" shortDescription="An El expression representing a managed bean field which should return an Integer indicating the day component of the maxDate"></cc:attribute>
    <cc:attribute name="render" type="java.lang.String" />

    <cc:clientBehavior name="change" targets="#{cc.clientId}:dateInput" event="change" />
</cc:interface>
<cc:implementation>
    <div id="#{cc.clientId}">
        <h:inputText id="dateInput" value="#{cc.attrs.value}" styleClass="jquery-datepicker"
            onclick="modifyDatePickerOptions('#{cc.attrs.clientId}', #{cc.attrs.minYear}, #{cc.attrs.minMonth}, #{cc.attrs.minDay}, #{cc.attrs.maxYear}, #{cc.attrs.maxMonth}, #{cc.attrs.maxDay} );">
            <f:ajax execute="@form"  event="change"  render="#{cc.attrs.render}" />
        </h:inputText>

    </div>
</cc:implementation>

And the using page :

<h:form id="datePickerForm">
            <my:datepicker  render=":datePickerForm:datePickerAjax" value="#{datePickerBean.selectedDate}" minYear="1999" minMonth="0" minDay="1" maxYear="2019" maxMonth="0" maxDay="1">
                <f:ajax  event="change" listener="#{datePickerBean.selectedDate}" />
            </my:datepicker>
            <h:panelGroup id="datePickerAjax" layout="block">
            <br />
                <b><h:outputText value="You selected : #{datePickerBean.selectedDate}" rendered="#{datePickerBean.selectedDate != null}" /></b>
            </h:panelGroup>
        </h:form>
1
Out of curiosity, why not: "(I don't have the option of using component libraries)"Kukeltje
@Kukeltje : The architects on the project felt that they don't want to depend on component libraries, as new and better component libraries are always coming out and they don't want migration overhead. So I'm limited to mojarra 2.1. They have at least allowed me to use Omnifaces thoughDuran Wesley Harris
So even with simple components like autoComplete they do not want to use e.g. PrimeFaces, but do want custom complexity like stackoverflow.com/questions/42834630/…? ok... Good luck them with datatables, filtering, sorting paging, tree tables and other components ;-)Kukeltje
It's a strange decision, I know. Even more so considering that our other applications are already running on PrimeFaces... so why not one more?Duran Wesley Harris

1 Answers

0
votes

You need to add a converter to your inputText field. You can nest an <f:convertDateTime/> tag in your inputText to achieve this. See convertDateTime for all the available attributes.