Skip Headers

Oracle® Application Development Framework Developer's Guide 10g Release 3 (10.1.3) B25386-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 8.6 Displaying Detail Information Using an Inline Table

As you may recall from Section 7.5, "Adding Hidden Capabilities to a Table", you can use the `detailStamp` facet in a table to hide or show additional information about a specific data object displayed in a table. When you add a component to this facet, the table displays an additional column labeled Details, which displays the additional information. It includes a toggle mechanism that enables the user to hide or show the information displayed in the Details column in a manner similar to the mechanism in an ADF tree or tree table. In the case described in Chapter 7, the additional information was a single attribute from the same data collection that populates the table.

Using master-detail collections on the Data Control Palette, you can declaratively add an inline table to the `detailStamp` facet that displays additional information from a detail collection. A master collection is used to populate the main table and a detail collection is used to populate the inline ``table.

Figure 8-7 shows how an inline table of service requests can be embedded in a table of service request staff. If the user clicks the Show link in the Details column, the inline table of service requests is displayed under the selected row of the table. The main table is populated by the `User` collection and displays the user's first and last name. The inline table is populated by the `ServiceRequest` detail collection and displays the service request number, its status, and the problem description.

Figure 8-7 Inline Table Displaying Information from a Detail Collection

## 8.6.1 How to Display Detail Information Using an Inline Table

Using the Data Control Palette, you can create both the main table and the inline table in a single declarative action. Since an inline table is similar to a tree table, you use the Tree Binding Editor to define the rules that populate the main table and the inline detail table. There must be one rule for the main table and one rule for the inline detail table. Each rule defines the following properties:

- The data collection that populates the table

- The attributes from the data collection that are displayed in the table

The rule for the main table must also specify an accessor method that returns the detail collection that will populate the inline table.

To create a master table with an inline detail table:

1. Drag a master data collection from the Data Control Palette, and drop it on the page. This should be the master collection that you want to populate the main table.

   Note: You cannot use a single object accessor return to create a table.

2. In the context menu, choose Tables > ADF Master Table, Inline Detail Table.

   JDeveloper displays the Tree Binding Editor (previously shown in Figure 8-4).

3. In the Edit Rule page of the Tree Binding Editor, define a rule for populating the main table and another rule for populating the inline table. To define a rule you must select the following items:

   - Data Collection Definition: Select the data collection that will populate the table you are defining. The first rule defines the main table. So, for the first rule, select the same data collection that you dragged from the Data Control Palette (the master collection). When defining the rule for the inline table, select the appropriate detail collection. For example, to create a main table of users, you would select the `User` collection for the first rule; to create an inline table that displays services requests related to a user, you would select the `ServiceRequest` collection in the branch rule.

   - Display Attribute: Select one or more attributes to display in the table you are defining. Each attribute is a column in the table. For example, if the main table is displaying users, you might select both the firstName`` and lastName`` attributes.

   - Branch Rule Accessor: If you are defining the rule for the main table, select the accessor method that returns the detail collection that you want to appear in the inline detail table. (As previously mentioned, detail collections are always returned by accessor methods.) The list displays only the accessor methods that return the detail collections for the master collection you selected for the rule. If you are defining the rule for the inline table, select <none>, because you cannot embed a table in the inline table.

     Tip: Be sure to click the Add New Rule button after you define each rule. If you click the OK button instead, the last rule you defined will not be saved. When you click Add New Rule, JDeveloper displays the Show Rules tab of the Tree Binding Editor, where you can verify the rules you have created.

4. Use the Show Rules page of the Tree Binding Editor, shown in Figure 8-5, to:

   - Change the order of the rules

     The rule that populates the main table must be first in the list

   - Identify the icons you want displayed for the expand and collapse mechanism

     Only the main table uses the icons, so if you want to use an icon other than the default, specify it in the rule for the main table.

     The default open icon is a solid down arrow with a minus sign, while the default closed icon is a solid right arrow with a plus sign

   - Delete rules

## 8.6.2 What Happens When You Create an Inline Detail Table

When you drag and drop from the Data Control Palette, JDeveloper does many things for you. For a full description of what happens and what is created when you use the Data Control Palette, see Section 5.2.3, "What Happens When You Create a Component From the Data Control Palette".

### 8.6.2.1 Code Generated in the JSF Page

When you create a master table and an inline detail table using the Data Control Palette, JDeveloper adds binding objects to the page definition file, and it also adds the table and facet to the JSF Page. The resulting UI components are fully functional and do not require any further modification.

Example 8-7 shows the code generated in a JSF page. This sample displays users in the main table and service requests in the inline detail table. The `User` collection is returned by the `findAllStaff` method. The main table is defined the same as any other ADF databound table. It is bound to the `findAllStaff1` binding object in the page definition file, which is a tree binding object. The columns in the main table display the user's first name and last name. The table includes a `detailStamp` facet in which the detail table is defined. The detail table is also bound to the `findAllStaff1` tree binding object, and the columns are set up to display the data from the service request collection. As with tree components, the page definition file defines the accessor method that returns the detail collection.

Example 8-7 JSF Code Created for the Master Table with an Inline Detail Table

    <af:table rows="#{bindings.findAllStaff1.rangeSize}"
              emptyText="#{bindings.findAllStaff1.
                           viewable ? \'No rows yet.\' : \'Access Denied.\'}"
              var="row" value="#{bindings.findAllStaff1.treeModel}">
      <af:column headerText="#{bindings.findAllStaff1.labels.city}"
                 sortable="false" sortProperty="city">
        <af:outputText value="#{row.city}"/>
      </af:column>
      <af:column headerText="#{bindings.findAllStaff1.labels.firstName}"
                 sortable="false" sortProperty="firstName">
        <af:outputText value="#{row.firstName}"/>
      </af:column>
      <af:column headerText="#{bindings.findAllStaff1.labels.lastName}"
                 sortable="false" sortProperty="lastName">
        <af:outputText value="#{row.lastName}"/>
      </af:column>
      <f:facet name="detailStamp">
        <af:table rows="#{bindings.findAllStaff1.rangeSize}"
                  emptyText="No rows yet." var="detailRow"
                  value="#{row.children}">
          <af:column headerText="#{row.children[0].labels.problemDescription}"
                     sortable="false" sortProperty="problemDescription">
            <af:outputText value="#{detailRow.problemDescription}"/>
          </af:column>
          <af:column headerText="#{row.children[0].labels.status}"
                     sortable="false" sortProperty="status">
            <af:outputText value="#{detailRow.status}"/>
          </af:column>
          <af:column headerText="#{row.children[0].labels.svrId}"
                     sortable="false" sortProperty="svrId">
            <af:outputText value="#{detailRow.svrId}">
              <f:convertNumber groupingUsed="false"
                               pattern="#{row.children[0].formats.svrId}"/>
            </af:outputText>
          </af:column>
        </af:table>
      </f:facet>
    </af:table>

### 8.6.2.2 Binding Objects Added to the Page Definition File

Example 8-8 shows the binding objects added to the page definition file. The `findAllStaffIter` iterator binding object iterates over the `User` collection, which is displayed in the main table. No iterator is needed for the detail collection, because the accessor method referenced in the tree binding object returns the detail data that is related to the currently selected master data.

In the bindings element, the `methodAction` binding object invokes the method that returns the `User` collection. The tree binding object populates the data in the master and detail tables. The `nodeDefintion` elements define the attributes that are displayed in the columns of master and detail tables. The first `nodeDefinition` element defines the data in the master table. For more information about tree binding objects, see Section 8.4.2, "What Happens When You Create an ADF Faces Databound Tree".

Example 8-8 Binding Objects Added to the Page Definition File for a Master Table with an Inline Detail Table

    <executables>
      <methodIterator id="findAllStaffIter" Binds="findAllStaff.result"
                      DataControl="SRPublicFacade" RangeSize="10"
                      BeanClass="oracle.srdemo.model.User"/>
    </executables>
    <bindings>
      <methodAction id="findAllStaff" InstanceName="SRPublicFacade.dataProvider"
                    DataControl="SRPublicFacade" MethodName="findAllStaff"
                    RequiresUpdateModel="true" Action="999"
                    ReturnName="SRPublicFacade.methodResults.
                                SRPublicFacade_dataProvider_findAllStaff_result"/>
      <tree id="findAllStaff1" IterBinding="findAllStaffIter">
        <AttrNames>
          <Item Value="city"/>
          <Item Value="countryId"/>
          <Item Value="email"/>
          <Item Value="firstName"/>
          <Item Value="lastName"/>
          <Item Value="postalCode"/>
          <Item Value="stateProvince"/>
          <Item Value="streetAddress"/>
          <Item Value="userId"/>
          <Item Value="userRole"/>
        </AttrNames>
        <nodeDefinition DefName="oracle.srdemo.model.User" id="UserNode">
          <AttrNames>
            <Item Value="city"/>
            <Item Value="firstName"/>
            <Item Value="lastName"/>
          </AttrNames>
          <Accessors>
            <Item Value="ServiceRequestCollectionAssignedTo"/>
          </Accessors>
        </nodeDefinition>
        <nodeDefinition DefName="oracle.srdemo.model.ServiceRequest"
                        id="ServiceRequestNode">
          <AttrNames>
            <Item Value="problemDescription"/>
            <Item Value="status"/>
            <Item Value="svrId"/>
          </AttrNames>
        </nodeDefinition>
      </tree>
    </bindings>

## 8.6.3 What Happens at Runtime

When the user hides or shows the details of a row, the table generates a `DisclosureEvent` event, which expands or collapses the inline detail table. The `isExpanded` method on this event determines whether the user is showing or hiding the detail table.

The `DisclosureEvent` event has an associated listener. The `DisclosureListener` attribute on the table is implicitly bound to the accessor method specified in the node rule defined in the page definition file. This accessor method is invoked in response to the `DisclosureEvent` event; in other words, whenever a user expands or collapses a node.