Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label ADF tree. Show all posts
Showing posts with label ADF tree. Show all posts

Monday 26 August 2013

Tree Table Component with declarative presentation in ADF, Access childs without custom selection listener

Hello all,
this is my second post on af:treeTable, first post was about creating and overriding tree table selection listener to get node value in managed bean, see
Tree Table Component in Oracle ADF(Hierarchical Representation)

In this post i am going to explain how to
  • use multiple detail column in treeTable
  • design better UI
  • manage child rows
  • use link,image,checkbox in treeTable conditionally
so i assume that you all know about creating treeTable, i am using default HR Schema (Employees ,Departments table) to master detail relation in tree and i have to show detail of Employee under Department node
  • I have created a treeTable using following details of Employees VO
  • Now on running my page it is looking like this, very odd and complex view
        xml source-

  <af:treeTable value="#{bindings.Departments1.treeModel}" var="node"
                              selectionListener="#{bindings.Departments1.treeModel.makeCurrent}" rowSelection="single"
                              id="tt1">
                    <f:facet name="nodeStamp">
                        <af:column id="c1" width="500">
                            <af:outputText value="#{node}" id="ot1"/>
                        </af:column>
                    </f:facet>
                    <f:facet name="pathStamp">
                        <af:outputText value="#{node}" id="ot2"/>
                    </f:facet>
                </af:treeTable>

  • It shows that all details of employees are clubbed in one column that is nodestamp, now to show details in different columns i have added 5 columns in treeTable, and seperate detail in each column as Email, FirstName,LastName etc
    To add column right click on treeTable and insert-
 In column drop an input text and set its value taking node reference




  •  Now run page and see, there is now 5 column with different details but still that clubbed value is shown.
  • Now to remove that clubbed detail, go to nodestamp facet of treeTable and see value of output text inside column, it is set to #{node} ,due to this all values available in node are clubbed and displayed in page, now we have to set its value to any of Master table's (Departments) attribute



  •  Now run page , only department name is displayed on header, and corresponding value for detail is blank
  •  We are done with this part, now try to make its UI somewhat better using some styles, so i have used different background color for header and detail part of treeTable conditionally
  • To do this i have set inline style property conditionally , because i have to change color of same column according to master and detail data, see condition

  • #{node.DepartmentName!=null ? 'background-color:darkgreen' :  'background-color:rgb(239,255,213);'  }
    

  • Now see how to get selected child row without over-riding treeTable's selection listener, to do this i have added a image link in treeTable and created a action listener on that to show current selected detail row
  • Bind tree table to managed bean and create two methods to get selected RowIterator and node Key

  •     /**Tree Table Binding in managed bean*/
        private RichTreeTable treeTabBind;
    
        public void setTreeTabBind(RichTreeTable treeTabBind) {
            this.treeTabBind = treeTabBind;
        }
    
        public RichTreeTable getTreeTabBind() {
            return treeTabBind;
        }
    
        /**Method to get Iterator*/
        public RowIterator getSelectedNodeIterator() {
            if (getTreeTabBind() != null && getTreeTabBind().getSelectedRowKeys() != null) {
                for (Object rKey : getTreeTabBind().getSelectedRowKeys()) {
                    getTreeTabBind().setRowKey(rKey);
                    return ((JUCtrlHierNodeBinding)getTreeTabBind().getRowData()).getRowIterator();
                }
            }
            return null;
        }
    
        /**Method to get Node Key*/
        public Key getSelectedNodeKey() {
            if (getTreeTabBind() != null && getTreeTabBind().getSelectedRowKeys() != null) {
                for (Object rKey : getTreeTabBind().getSelectedRowKeys()) {
                    getTreeTabBind().setRowKey(rKey);
                    return ((JUCtrlHierNodeBinding)getTreeTabBind().getRowData()).getRowKey();
                }
            }
            return null;
        }
    

  • Now to get currently selected node and row pass Iterator and Node key in this method- see

  •     public void showCurRowDetail(RowIterator ri, Key selectedNodeKey) {
            Row[] rows = ri.findByKey(selectedNodeKey, 1);
    
            FacesMessage msg = new FacesMessage(rows[0].getAttribute("FirstName") + "'s data available in this row");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    

  • Now Run application and click on link to see selected row -


Saturday 27 July 2013

Implementing master/detail tree relation using af:Iterator and af:forEach for better UI designs - Oracle ADF

In ADF Faces tree and tree table is used for hierarchical representation of master/detail form of data,
in this tutorial i will show you that how can we design better UI's using master detail data.
af:iterator and af:ForEach both are used to iterate data as af:table for custom UI component-

here i am taking example of default HR Schema of Oracle database , Departments and Employees table to show master-detail relation

Using af:iterator-

  • Create a Fusion Web Application and prepare model for master detail relationship between departments and employees table, and in your page drop af:showDetailHeader from component palette
  • Go to page binding, add tree binding for Departments (Master) and Employees (Detail)


  • Surround showDetailHeader with an af:iterator,  and set value and var for iterator (master)

  •  Now change text of showDetailHeader to show department name on it, taking reference from iterator's var


  • master part is done, for detail part  drop two output text (for employee's first name and last name) inside showDetailHeader surrounding with an iterator (for detail part)




  • set the value and var for detail iterator taking reference from master iterator 

  • Now to show detail values in output text , set the value in both output text, taking reference from detail iterator


  • See the source of page for more clarification-

  • <af:iterator id="i3" value="#{bindings.Departments1.collectionModel}" var="departments">
                                    <af:showDetailHeader text="#{departments.DepartmentName}" disclosed="true" id="sdh1"
                                                         inlineStyle="width:350px;">
                                        <f:facet name="context"/>
                                        <f:facet name="menuBar"/>
                                        <f:facet name="toolbar"/>
                                        <f:facet name="legend"/>
                                        <f:facet name="info"/>
                                        <af:panelGroupLayout id="pgl2" layout="vertical">
                                            <af:iterator id="i2" var="emp" value="#{departments.Employees}">
                                                <af:separator id="s3"/>
                                                <af:panelFormLayout id="pfl1" rows="1">
                                                    <af:outputText value="#{emp.FirstName}" id="ot2"
                                                                   inlineStyle="font-weight:bold;color:darkblue;"/>
                                                    <af:outputText value="#{emp.LastName}" id="ot3"
                                                                   inlineStyle="font-weight:bold;color:red;"/>
                                                </af:panelFormLayout>
                                                <af:spacer width="10" height="10" id="s1"/>
                                            </af:iterator>
                                        </af:panelGroupLayout>
                                    </af:showDetailHeader>
                                </af:iterator>
    

  • Now Run your page to see UI of this master-detail relationship-


Using af:ForEach-

  •  Drop a panel accordion on page, by default it has one af:showDetailItem , surround it with af:ForEach and set items and var for ForEach

  • change text of showDetailItem to show department name on it, taking reference from ForEach's var 

  • Now drop Employees detail table from data control inside showDetailItem and set its value , taking reference from ForEach 


  • For more clarification see source of page-

  • <af:panelAccordion id="pa1" styleClass="AFStretchWidth" visible="true">
                                    <af:forEach items="#{bindings.Departments1.children}" var="dept">
                                        <af:showDetailItem text="#{dept.DepartmentName}" id="sdi1" inflexibleHeight="200">
                                            <af:table value="#{dept.children}" var="row"
                                                      rows="#{bindings.Employees3.rangeSize}"
                                                      emptyText="#{bindings.Employees3.viewable ? 'No data to display.' : 'Access Denied.'}"
                                                      fetchSize="#{bindings.Employees3.rangeSize}" rowBandingInterval="0"
                                                      filterModel="#{bindings.Employees3Query.queryDescriptor}"
                                                      queryListener="#{bindings.Employees3Query.processQuery}"
                                                      filterVisible="true" varStatus="vs"
                                                      selectedRowKeys="#{bindings.Employees3.collectionModel.selectedRow}"
                                                      selectionListener="#{bindings.Employees3.collectionModel.makeCurrent}"
                                                      rowSelection="single" id="t1" styleClass="AFStretchWidth">
                                                <af:column sortProperty="#{bindings.Employees3.hints.EmployeeId.name}"
                                                           filterable="true" sortable="false"
                                                           headerText="#{bindings.Employees3.hints.EmployeeId.label}"
                                                           id="c1">
                                                    <af:outputText value="#{row.EmployeeId}"
                                                                   shortDesc="#{bindings.Employees3.hints.EmployeeId.tooltip}"
                                                                   id="ot4">
                                                        <af:convertNumber groupingUsed="false"
                                                                          pattern="#{bindings.Employees3.hints.EmployeeId.format}"/>
                                                    </af:outputText>
                                                </af:column>
                                                <af:column sortProperty="#{bindings.Employees3.hints.FirstName.name}"
                                                           filterable="true" sortable="false"
                                                           headerText="#{bindings.Employees3.hints.FirstName.label}"
                                                           id="c2">
                                                    <af:outputText value="#{row.FirstName}"
                                                                   shortDesc="#{bindings.Employees3.hints.FirstName.tooltip}"
                                                                   id="ot5"/>
                                                </af:column>
                                                <af:column sortProperty="#{bindings.Employees3.hints.LastName.name}"
                                                           filterable="true" sortable="false"
                                                           headerText="#{bindings.Employees3.hints.LastName.label}" id="c3">
                                                    <af:outputText value="#{row.LastName}"
                                                                   shortDesc="#{bindings.Employees3.hints.LastName.tooltip}"
                                                                   id="ot6"/>
                                                </af:column>
                                                <af:column sortProperty="#{bindings.Employees3.hints.Email.name}"
                                                           filterable="true" sortable="false"
                                                           headerText="#{bindings.Employees3.hints.Email.label}" id="c4">
                                                    <af:outputText value="#{row.Email}"
                                                                   shortDesc="#{bindings.Employees3.hints.Email.tooltip}"
                                                                   id="ot7"/>
                                                </af:column>
                                            </af:table>
                                        </af:showDetailItem>
                                    </af:forEach>
                                </af:panelAccordion>
    


  • Now run your page to see its UI-


Download Sample workspace here- Download
Happy Jdeveloping..

Monday 26 November 2012

Tree Table Component in Oracle ADF(Hierarchical Representation)


Hello All

This post is about ADF Faces Tree Table component (about designing component and get selected value from tree table)

We have a simple sample application that shows how can we use tree table component in Oracle ADF.
Tree Table component represents  Hierarchical view of Master Deatil form of data
Here we take example from HR schema using Employees and Department table
Follow these steps -

  • Create EOs,VOs of Employees and Department table in HR Schema and create association and viewlink between Department To Employees considering Department Id
  • Now go to data control and select Department table and drop it on page as Tree table 

Drop ViewObject as ADF Tree Table
  •  Now we have to edit its bindings, it means you have to select attributes that you want to display in page, and below Department table you should add Employees table using "add" button on top, and select appropriate Iterator in EL picker
Edit tree binding in pageDef
  • Now go to page and select treetable in Structure window of Jdeveloper and Go to its selection listener and copy default value
Override default selection listener
  • And change selection listener set it to bean, click on edit and create new selection listener in Bean




Create custom selection listener in managed bean for af:treeTable
  •  Now go to Selection Listener and Use this code to get Value of selected node in treetable, if you will get value of node you can perform any operation on Tree Table
    public void treeTableSelectionListener(SelectionEvent selectionEvent) {
        String adfSelectionListener = "#{bindings.Department1.treeModel.makeCurrent}";

        FacesContext fctx = FacesContext.getCurrentInstance();
        Application application = fctx.getApplication();
        ELContext elCtx = fctx.getELContext();
        ExpressionFactory exprFactory = application.getExpressionFactory();
        MethodExpression me = null;
        me =
 exprFactory.createMethodExpression(elCtx, adfSelectionListener, Object.class, new Class[] { SelectionEvent.class });
        me.invoke(elCtx, new Object[] { selectionEvent });
       
        RichTreeTable tree = (RichTreeTable)selectionEvent.getSource();
        TreeModel model = (TreeModel)tree.getValue();
        //get selected nodes
        RowKeySet rowKeySet = selectionEvent.getAddedSet();
        Iterator rksIterator = rowKeySet.iterator();
        while (rksIterator.hasNext()) {
            List key = (List)rksIterator.next();
            JUCtrlHierBinding treeBinding = null;
            treeBinding = (JUCtrlHierBinding)((CollectionModel)tree.getValue()).getWrappedData();
            JUCtrlHierNodeBinding nodeBinding = treeBinding.findNodeByKeyPath(key);
            Row rw = nodeBinding.getRow();
            System.out.println("row: " + rw.getAttribute(0)); // You can get any attribute
            System.out.println("View Object name---->" + nodeBinding.getViewObject().getName());

        }
    }
  •  Now run your page and when you will click on any node you will find its value on Console---Cheers Happy Coding!
Sample ADF Application