Monday, August 6, 2012

Oracle ADF: af:navigationPane instead af:panelTabbed


Issue

Show Database table rows in an ADF Page using tabs: Each tab have to represent a table record and content's information, there could be many tabs to show.

Solution

The tab content has the same structure for every DB table row. It's possible to use the af:panelTabbed and af:showDetailItem for each row, iterating it with an af:iterator.

  <af:panelTabbed>
     <af:iterator>
       <af:showDetailItem>
         .....
         <!-- tab content -->
         .....
       </af:showDetailItem>
     </af:iterator>
  </af:panelTabbed>

This approach has a disadvantage: the page is rendered with each tab and its content, duplicating the tab detail for each rendered tab (tab content could be very complex). If, in the page, there are many tabs it could slow down the page behavior.
An alternative approach could be simulate the tab behavior using an af:navigationPane. In this case a af:forEach iterates the tabs component represented by the af:commandNavigationItem.

The af:navigationPane is used only for its graphical property, the tab content is out side the Tab and it is render at run time only one time and not for every tab. the only complication of this approach is refresh the tab content for every tab selection.

  <af:navigationPane>
    <af:forEach>
      <af:commandNavigationItem/>
    </af:forEach>
  </af:navigationPane>
...
<!-- tab content -->
...


For this example it's used the HR.JOBS table of the Oracle XE 11g database.

To simulate the af:panelTabbed, create a pageFlow managed bean (TabLike) 'tablike.bean.LikeTabBean' and create two methods.

  • getTabList: get a TabInfo (tab title and jobs.id container) list that represent all the tabs ti show in the page.

    public List<TabInfo> getTabList() {
        DCIteratorBinding iter = ADFUtils.findIterator("JobsVO1Iterator");
        List<TabInfo> attributeList = new ArrayList<TabInfo>();
        TabInfo tmp = null;
        logger.info("JobsVO1Iterator rows " + iter.getEstimatedRowCount());
        for (Row r : iter.getAllRowsInRange()) {
            tmp = new TabInfo();
            tmp.setId((String)r.getAttribute("JobId"));
            tmp.setTitle((String)r.getAttribute("JobTitle"));
            attributeList.add(tmp);
        }
        return attributeList;
    }

  • selectTab: a listener on the tab selection that move the iterator on the selected item updating the tab content.

    public void selectTab(ActionEvent actionEvent) {
        RichCommandNavigationItem cni = (RichCommandNavigationItem)actionEvent.getSource();
        String current = ((String)cni.getAttributes().get("jobId")).toString();
        logger.info("selected jobid: " + current);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("rowKey", new String(current));
        ADFUtils.executeOperationBinding("setCurrentRowWithKeyValue", params);
    }

To create tab details, drag and drop under the af:navigationPanel from the DataControl panel what you need (in this case a Job form).
The iterator used by the form and the by the tab must be the same.

      <af:forEach items="#{pageFlowScope.TabLike.tabList}" var="tab"
                  varStatus="tabStatus">
        <af:commandNavigationItem text="#{tab.title}" id="cni1"
                                  actionListener="#{pageFlowScope.TabLike.selectTab}"
                                  selected="#{tab.id eq bindings.JobId.inputValue}">
          <f:attribute name="jobId" value="#{tab.id}"/>
        </af:commandNavigationItem>
      </af:forEach>
    </af:navigationPane>

...
<!-- tab content -->
...


Here you can download the code source. The classic approach (af:panelTabbed) is developed in the fragment tab.jsff; in the fragment liketab.jsff is developed the second approach (af:navigationPane). The main page is mainPage.jspx

JDeveloper version used: 11.1.1.4.0


2 comments:

  1. hi
    Thanks for the post. I have a question
    what is "TabInfo". Is it a class. if it is a class , what is the code of this class.

    Thanks

    ReplyDelete
  2. Thanks for sharing this great information I am impressed by the information that you have on this blog. Same as your blog i found another one Oracle Fusion Financials , Oracle Project Portfolio Management (PPM) Cloud Tutorial and Oracle Fusion Procurement . Actually I was looking for the same information on internet for Oracle Fusion Manufacturing , Oracle APEX , Oracle Financials Cloud and came across your blog. I am impressed by the information that you have on this blog. It shows how well you understand this subject, you can check more aboutOracle Fusion Supply Chain Management Cloud , Oracle HCM Cloud , Oracle Project Portfolio Management (PPM) Cloud , Oracle Cloud Applications to better understand

    ReplyDelete