30 Sept 2016

Time Picker Declarative Component

Recently I came across the following requirement: there is a Timestamp attribute in an entity and users should be able to modify only time part (hours and minutes) of the attribute value.

Apparently,  this requirement could be implemented with a kind of a time-picker component allowing  to input hours and minutes but hiding the date part. There is date-time-picker (af:inputDate) component in ADF Faces, but there is no just time-picker. The solution is to make a declarative component out of two input-number-spinboxes (one for hours, one for minutes):

<af:xmlContent>
    <afc:component>
        <afc:description/>
        <afc:display-name>TimePicker</afc:display-name>
        <afc:attribute>
            <afc:attribute-name>valueBinding</afc:attribute-name>
            <afc:attribute-class>
              oracle.jbo.uicli.binding.JUCtrlAttrsBinding
            </afc:attribute-class>
        </afc:attribute>
        <afc:attribute>
            <afc:attribute-name>label</afc:attribute-name>
            <afc:attribute-class>java.lang.String</afc:attribute-class>
        </afc:attribute>
    </afc:component>
</af:xmlContent>
<af:panelLabelAndMessage label="#{attrs.label}" id="pll1">
    <af:panelGroupLayout id="dc_pgl1" layout="horizontal">
        <af:inputNumberSpinbox simple="true" id="dc_ins1"
                               value="#{backingBeanScope.timePicker.hours}"
                               minimum="0" maximum="23"/>
        <af:spacer width="10" height="10" id="dc_s1"/>
        <af:inputNumberSpinbox simple="true" id="dc_ins2"
                               value="#{backingBeanScope.timePicker.minutes}"
                               minimum="0" maximum="59">
        </af:inputNumberSpinbox>
    </af:panelGroupLayout>
</af:panelLabelAndMessage>


Note, that values for the input-number-spinboxes are provided by backing bean properties. The timePicker backing bean is responsible for extracting hours and minutes from the timestamp value of the attribute value binding which is passed to the component as valueBinding attribute. This is not a big deal with Java 8 Date/Time API:
    private JUCtrlAttrsBinding getValueBinding() {
       return (JUCtrlAttrsBinding) getAttributes().get("valueBinding");
    }


    private LocalDateTime getTime() {
        Timestamp timeStampTime =
            (Timestamp) getValueBinding().getInputValue();
        return timeStampTime.toLocalDateTime();
    }


    public Integer getHours() {
        return getTime().getHour();
    }


    public Integer getMinutes() {
        return getTime().getMinute();
    }


On the other hand, the setters of hours and minutes of the backing bean properties create a new Timestamp instance out of hours and minutes and set it as an input value of the valueBinding attribute:
    public void setHours(Integer value) {
        setTime(value, getMinutes());
    }


    public void setMinutes(Integer value) {
        setTime(getHours(), value);
    }

    private void setTime(int hours, int minutes) {
      LocalDateTime time =
        LocalDateTime.of(getTime().toLocalDate(), LocalTime.of(hours, minutes));

      getValueBinding().setInputValue(Timestamp.valueOf(time));
    }

The sample application for this post, containing the TimePicker declarative component, is available here. It requires JDeveloper 12.2.1.1.

That's it!




17 Sept 2016

Customizing View Link Where Clause

Master-detail behavior is one of the most common use cases. Whenever we need to implement master-detail relationship between  two view objects we use view links for that. Usually, we do that declaratively with JDeveloper's wizard. The corresponding where clauses will be generated by the framework at runtime. For most cases it's enough, it works fine and we don't need to worry about anything else.

However, sometimes the definition of master-detail relationship is not that trivial.  For example, there is a page containing employee's details and a list of employee's colleagues. Like this:


We're building Employee-Colleagues master-detail relationships with the following view link:



Basically, we are selecting all employees of the same department. But! In this case the colleagues detail list will contain the master employee as well. The employee will be shown twice: on the form and in the colleagues list. We don't want that and we'd like to exclude the employees from their colleagues list.

We are adding one more pair of attributes to the view link definition:


















The framework at runtime will generate the following where clause for selecting colleagues:






Obviously, this is not what we actually want. So, we're going to manually specify the where clause to be used for this view link in the property inspector:









And now it will work as it is supposed to, selecting all employees of the my department except myself.


The sample application for this post is available here. It requires JDeveloper 12.2.1.1.

That's it!