Enterprise Java

Master-Detail data with ADF List View

Lately the ADF Faces table component has not been considered cool anymore from UI perspective. List View is supposed to be cool today for displaying data collections. It doesn’t mean that we shouldn’t use af:table at all. In some cases (pretty often :)) a table is far more suitable than a list view. However, the list view component looks really nice, it fits well with the modern UI tendency and it definitely deserves to be used widely in ADF applications.

One of the most common use-cases related to data collections is displaying master-detail data. In this post I am going to show what we can do about that with List View.

The List View component provides out-of-the-box functionality to display hierarchical data by the use of groupHeaderStamp facet.

Let’s say there is Departments-Employees hierarchy defined in the application:

Screen Shot 2015-12-01 at 2.53.27 PM

If we drag the detail collection Employees onto a page and choose ADF List View as a desired component, the wizard will allow us to include a group header containing attributes from the parent collection:

Screen Shot 2015-12-01 at 2.56.44 PM

As a result the list view on the page will contain groupHeaderStamp facet with Department attributes:

<af:listView value="#{bindings.Departments.treeModel}" var="item" ...
             fetchSize="#{bindings.Departments.rangeSize}" id="lv1">
  <af:listItem id="li1">
    <af:panelGridLayout id="pgl2">
      <af:gridRow marginTop="5px" height="auto" marginBottom="5px" id="gr1">
        <af:gridCell marginStart="5px" width="34%" id="gc1">
          <af:outputFormatted value="#{item.bindings.EmployeeId.inputValue}"
          id="of1"/>
        </af:gridCell>
        ...
    </af:panelGridLayout>
  </af:listItem>
  <f:facet name="groupHeaderStamp">
    <af:listItem id="li2">
      <af:outputFormatted value="#{item.bindings.DepartmentName.inputValue}"
          id="of6"/>
    </af:listItem>
  </f:facet>
</af:listView>

And it looks like this:

Screen Shot 2015-12-01 at 4.12.37 PM

It looks nice, but it is not actually what I need!  My requirement is to implement something like this:

Screen Shot 2015-12-01 at 4.15.09 PM

So that each department is represented with a panel containing two tabs: general department info and list of employees. This use-case can be easily implemented using Accessors from the tree model node definition. The tree model for our list view in the page def file looks like this:

<tree IterBinding="DepartmentsIterator" id="Departments">
  <nodeDefinition DefName="DepartmentsDeafultVO" Name="Departments0">
    <AttrNames>
      <Item Value="DepartmentId"/>
      <Item Value="DepartmentName"/>
    </AttrNames>
    <Accessors>
      <Item Value="Employees"/>
    </Accessors>
  </nodeDefinition>
  <nodeDefinition DefName="EmployeesDeafultVO" Name="Departments1">
    <AttrNames>
      <Item Value="EmployeeId"/>
      <Item Value="FirstName"/>
      <Item Value="LastName"/>
      <Item Value="Email"/>
    </AttrNames>
  </nodeDefinition>
</tree>

There is Employees accessor defined in the Departments0 node definition. It uses Employeesview link accessor  to retrieve detail records for each department row. The structure of detail records is described in the Departments1 node definition.

We are going to make use of this hierarchical tree model like this:

<af:listView value="#{bindings.Departments.treeModel}" var="item" ...>            
  <af:listItem id="li1">
   <af:panelTabbed position="above" id="pt1" childCreation="lazyUncached">
    <af:showDetailItem id="tab1" text="Department">
      <af:panelFormLayout id="pfl1" inlineStyle="height:150px;">
      <af:panelLabelAndMessage label="#{item.bindings.DepartmentId.hints.label}"
                               id="plam1">
        <af:inputText value="#{item.bindings.DepartmentId.inputValue}"id="ot1"/>
      </af:panelLabelAndMessage>
        ...

      </af:panelFormLayout>
    </af:showDetailItem>
    <af:showDetailItem id="sdi1" text="Employees">
     <af:listView value="#{item.Employees}" var="empItem" ...>
      <af:listItem id="li2">
        <af:panelGridLayout id="pgl2">
          <af:gridRow  id="gr1">
            <af:gridCell id="gc1">
       <af:outputFormatted value="#{empItem.bindings.EmployeeId.inputValue}"
                           id="of1"/>
            </af:gridCell>
            ...
        </af:panelGridLayout>
      </af:listItem>
     </af:listView>
    </af:showDetailItem>
    </af:panelTabbed>
  </af:listItem>
</af:listView>

So each list item contains a panel tabbed inside and the Employees tab contains a nested list view (actually it could be whatever, for example a table) referring to the Employees accessor.

  • The sample application for this post is available here.

It requires JDeveloper 12.1.3.

That’s it!

Reference: Master-Detail data with ADF List View from our JCG partner Eugene Fedorenko at the ADF Practice blog.

Eugene Fedorenko

I am a Senior Architect at Flexagon focusing on ADF and many other things.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button