Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label af:treeTable. Show all posts
Showing posts with label af:treeTable. Show all posts

Tuesday, 8 May 2018

Change Style of ADF TreeTable, Column, Data Cell, Selected Row using ADF Skin

Hello Everyone

In this tutorial, We'll learn to change look n feel of ADF tree table component using Oracle ADF Skin
Here I am using Departments and Employees table HR Schema to prepare the model and created tree Table using view link between Departments and Employees View Object

Saturday, 18 June 2016

Add and delete records (Parent/Child) in POJO Based ADF TreeTable


Hello All

Previously I have posted about creating POJO based ADF TreeTable , Get Selected Record from POJO based TreeTable and Traverse POJO based TreeTable

Recently a developer asked me about adding and deleting records in POJO based TreeTable so here goes a new blog post

To add records in af:treeTable first we have to check that if user has selected any parent node then new record will be added under it and if there is no selection then new record will be added as parent node, This is the core concept of this post and all these posts uses same sample application and same 2-Level Tree


Thursday, 19 May 2016

Traverse POJO based ADF treeTable, Get Child nodes of selected parent


Previosuly I have posted about populating af:treeTable programmatically and getting selected records from POJO based treeTable

This post is next in that series and here I am extending same sample application that show a tree of Seasons and it's characters
First we will see How to traverse a POJO based treeTable (Iterate through all nodes of treeTable)

Basic idea is to get treeTable Collection Model and iterate over it to get all nodes value, To get CollectionModel created treeTable component binding in managed bean

Friday, 13 May 2016

Get Selected records (Child/Parent) from POJO based ADF treeTable

Hello All
Previously I have posted about creating af:treeTable programmatically using POJO and this the next post in series

In this post I am talking about a very common requirement while using POJO based treeTable
How can we get selected records (child/parent) from POJO based treeTable ?

For this post I am extending same sample application, Till now we have seen that how can we create POJO based treeTable
Now we'll see that how to get it's selected records


Wednesday, 1 October 2014

Using Drag-Drop functionality in af:treeTable to move data between nodes -Oracle ADF

This is a very common question and development requirement - How to drag drop records inside treeTable to perform some kind of operation ?
This post is an answer,here i am using Departments and Employees table of HR Schema to create treeTable and Jdeveloper 12.1.3

First Step-
Create business components using Departments and Employees table of HR Schema and create association and viewLink using DepartmentId (here Departments is parent and Employee is child viewObject)




now drop Departments viewObject as treeTable on page from data-control
see- Tree Table Component in Oracle ADF(Hierarchical Representation)  (How to create treeTable in ADF)

So after creating simple treeTable, added  two columns other than nodeStamp to show DepartmentName and EmployeeName in a better way
see-Tree Table Component with declarative presentation in ADF

Finally it looks like this-


Now my requirement is - when drag an Employee to any Department node it should become child of that Department ,means attach Employee to Departments using drag-drop

So to drag Employee Name filed i added af:attributeDragSource under this field and to get corresponding EmployeeId added an af:clientAttribute component




This clientAttribute stores value of EmployeeId for each node and dragSource refers clientAttribute to identify node value
Now to handle dropEvent on DepatmentName node , dropped an af:dropTarget under this field and created a dropListener in managed bean that will handle desired operation on dropEvent


See complete af:treeTable xml source-

<af:treeTable value="#{bindings.Departments1.treeModel}" var="node"
                  selectionListener="#{bindings.Departments1.treeModel.makeCurrent}" rowSelection="single" id="tt1"
                  binding="#{pageFlowScope.DragDropBean.treeTabBind}">
      <f:facet name="nodeStamp">
        <af:column id="c1" width="10">
          <af:outputText value="#{node}" id="ot1"/>
        </af:column>
      </f:facet>
      <f:facet name="pathStamp">
        <af:outputText value="#{node}" id="ot2"/>
      </f:facet>
      <af:column id="c2" width="150">
        <af:outputText value="#{node.DepartmentName}" id="ot3"
                       inlineStyle="font-weight:bold;color:red;font-size:small;">
          <af:dropTarget dropListener="#{pageFlowScope.DragDropBean.treeDropListener}">
            <af:dataFlavor flavorClass="java.lang.Object"/>
          </af:dropTarget>
        </af:outputText>
      </af:column>
      <af:column id="c3">
        <af:outputText value="#{node.FirstName}" id="ot4" inlineStyle="font-weight:bold;color:darkgreen;">
          <af:clientAttribute name="DragEmployeeId" value="#{node.EmployeeId}"/>
          <af:attributeDragSource attribute="DragEmployeeId"/>
        </af:outputText>
      </af:column>
    </af:treeTable>

Now see the code of drop listener written in managed bean that gets EmployeeId value from dropEvent and DepartmentId from expression and calls a business logic to move employee under that Deaprtment

DropListener in ManagedBean to handle dropEvent-

    /**Method to move Employee Under Department
     * @param dropEvent
     * @return
     */
    public DnDAction treeDropListener(DropEvent dropEvent) {

        Object empId = null;
        Integer dropVal = null;
        //Get Value from dragSource (EmployeeId of dragged node)
        DataFlavor<Object> df = DataFlavor.getDataFlavor(Object.class);
        empId = dropEvent.getTransferable().getData(df);
        if (empId != null) {
            System.out.println("Dropped value is -" + empId);
            try {
                dropVal = new Number(empId).intValue();
            } catch (SQLException e) {
            }
            //Get DepartmentId where Employee is dropped (resolve Expression langusge)
            Object droppedUnderDept = resolvElDC("#{node.DepartmentId}");
            System.out.println("Dropped under-" + droppedUnderDept);
            //Method Call to mode Employee under Department
            OperationBinding ob = executeOperation("moveEmployeeToDepartment");
            ob.getParamsMap().put("deptId", Integer.parseInt(droppedUnderDept.toString()));
            ob.getParamsMap().put("empId", dropVal);
            ob.execute();
        }
        /*Method to expand treeTable to show all nodes
         * see-http://www.awasthiashish.com/2013/10/expand-and-collapse-aftreetable.html
         * */
        expandTreeTable();
        //Refreshing treeTable after all operation, here treeTabBind is component binding of treeTable
        AdfFacesContext.getCurrentInstance().addPartialTarget(treeTabBind);
        return DnDAction.NONE;

    }

Helper methods to get BindingContainer and resolve expression-

    /*****Generic Method to call operation binding**/
    public BindingContainer getBindingsCont() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

    /**
     * Generic Method to execute operation Binding
     * */
    public OperationBinding executeOperation(String operation) {
        OperationBinding createParam = getBindingsCont().getOperationBinding(operation);
        return createParam;

    }



    /**Method to resolve Expression
     * @param data
     * @return
     */
    public Object resolvElDC(String data) {
        FacesContext fc = FacesContext.getCurrentInstance();
        Application app = fc.getApplication();
        ExpressionFactory elFactory = app.getExpressionFactory();
        ELContext elContext = fc.getELContext();
        ValueExpression valueExp = elFactory.createValueExpression(elContext, data, Object.class);
        return valueExp.getValue(elContext);
    }

Now run your application and check -
Dragged Prabhakar from Purchase Department and dropped it on Finance-

 Result-
Thanks, Happy learning :)
Download Sample App
See other post on Drag-Drop functionality- Adding Drag and Drop Functionality for collections in page fragments to create insert

Wednesday, 23 July 2014

Search on (Filtering) child nodes of af:treeTable using viewCriteria in Oracle ADF (11g,12c)

Hello all
this post is about filtering treeTable on basis of child nodes in Oracle ADF
in this tutorial i have used Departments and Employees table of HR schema to create treeTable
see how to create treeTable-
http://www.awasthiashish.com/2012/11/tree-table-component-in-oracle.html
http://www.awasthiashish.com/2013/08/tree-table-component-with-declarative.html

treeTable look like this-


now next is to search on Employee Names



  • i have dropped a input text for search string and a button to search on page , here i am searching on first name of employees 


  • now created a view Criteria in Employee viewObject to search on first name


  • This viewCriteria doesn't work directly on Employee viewObject, to search in treeTable we have to override createViewLinkAccessorRS method in Departments (master vo) VOImpl class, and in this method we have to call Employees ViewCriteria explicitly , this will filter Employee Vo Rowset as per bind-variable value when a node is disclosed at runtime

  •     /**
         * @param associationDefImpl
         * @param viewObjectImpl
         * @param row
         * @param object
         * @return
         */
        protected ViewRowSetImpl createViewLinkAccessorRS(AssociationDefImpl associationDefImpl,
                                                          ViewObjectImpl viewObjectImpl, Row row, Object[] object) {
    
    
            ViewRowSetImpl viewRowSetImpl = super.createViewLinkAccessorRS(associationDefImpl, viewObjectImpl, row, object);
    
            String firstName = getFirstNm();
            ViewCriteriaManager vcm = viewObjectImpl.getViewCriteriaManager();
            ViewCriteria vc = vcm.getViewCriteria("EmployeesVOCriteria");
            VariableValueManager vvm = vc.ensureVariableManager();
            vvm.setVariableValue("BindFirstNm", firstName);
            viewObjectImpl.applyViewCriteria(vc);
            return viewRowSetImpl;
    
    
            // return super.createViewLinkAccessorRS(associationDefImpl, viewObjectImpl, row, object);
        }
    

  • to pass bind-variable value i have created a variable and it's accessors in VoImpl and exposed set method to client that is further used by managed bean

  •     private String firstNm;
        public void setFirstNm(String firstNm) {
            this.firstNm = firstNm;
        }
    
        public String getFirstNm() {
            return firstNm;
        }
    

  • now this setter method is called in managed bean search button action to set bind variable value

  •     /**Method to search in treeTable childs
         * @param actionEvent
         */
        public void searchAction(ActionEvent actionEvent) {
            if (firstNmBind.getValue() != null) {
                OperationBinding ob = executeOperation("setFirstNm");
                // firstNmBind is binding of inputText
                ob.getParamsMap().put("firstNm", firstNmBind.getValue().toString());
                ob.execute();
                /* Method Expand treeTable after Search see- 
                 http://www.awasthiashish.com/2013/10/expand-and-collapse-aftreetable.html*/
                expandTreeTable();
                AdfFacesContext.getCurrentInstance().addPartialTarget(treeTabBind);
    
            }
        }
    

  • Run your application and see-
    Cheers- Happy Learning
    Download Sample ADF Application

Saturday, 5 July 2014

Populate af:treeTable programatically using POJO in Oracle ADF (11g & 12c)

Hello All
This post is about creating & populating af:treeTable programmatically in ADF 11g and 12c
treeTable is basically a hierarchical representation of data, using ADF model layer we can create treeTable very easily by defining master-detail relation between viewObjects
see my previous posts on treeTable-
Tree Table Component in Oracle ADF(Hierarchical Representation)
Tree Table Component with declarative presentation in ADF, Access childs without custom selection listener
Expand and Collapse an af:treeTable programmatically in ADF Faces (Oracle ADF)
Refreshing Child Nodes of an af:treeTable / af:tree in Oracle ADF



to populate treeTable programmatically we need to configure data set that fits to tree hierarchy
thanks to Chris Muir's post about programmatic creation of treeTable
http://one-size-doesnt-fit-all.blogspot.in/2007/05/back-to-programming-programmatic-adf.html

there is 4-5 simple steps to do-
  • Create a fusion web application and drop a af:treeTable on page , in treeTable creation wizard select "bind later" 


  • now create managed bean to populate data in treeTable, create a simple List in managed bean of type POJO class (a java class that contains attributes and their accessor  )
  • so in this app i am going to Tv Serial and respective character names in treeTable, for that i have created a class that contains POJO for treeTable

  • import java.util.ArrayList;
    import java.util.List;
    
    
    public class Seasons {
        public Seasons(String name) {
            this.name = name; // To Store Header Values (Storing Seasons Name :))
            characters = new ArrayList<Seasons>(); // To Store Detail Values (Storing Season's Charatcers)
        }
    
        public void setCharacters(List<Seasons> empDet) {
            this.characters = empDet;
        }
    
        public List<Seasons> getCharacters() {
            return characters;
        }
        private String name;
        private List<Seasons> characters;
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    // This methods directly add characters value in list
        public void addEmp(Seasons employee) {
            characters.add(employee);
        }
    
    }
    

  • In this class the characters list behaves as child of seasons, so in managed bean define a top-level list (that contains both master and detail) and add values

  • See managed Bean Code-
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.myfaces.trinidad.model.ChildPropertyTreeModel;
    
    public class ProgrammaticTreeTabBean {
        List<Seasons> seasonList = new ArrayList<Seasons>();
    
        ChildPropertyTreeModel charatcerVal;
    
        public ProgrammaticTreeTabBean() {
            super();
            // Creating tree for Seasons and Characters details
            // Adding Master Values (seasons)
            Seasons season1 = new Seasons("Game of Thrones");
           // Adding Detail Values (Child Node-Characters)
            Seasons character = new Seasons("Tywin Lannister");
            season1.addCharaters(character);
            character = new Seasons("Tyrion Lannister");
            season1.addCharaters(character);
            character = new Seasons("Jaime Lannister");
            season1.addCharaters(character);
            character = new Seasons("Cersie Lannister");
            season1.addCharaters(character);
            character = new Seasons("Ned Stark");
            season1.addCharaters(character);
    
            // Adding Master Values (seasons)
            Seasons season2 = new Seasons("Arrow");
            // Adding Detail Values (Child Node-Characters)
            character = new Seasons("Oliver Queen");
            season2.addCharaters(character);
            character = new Seasons("Moira Queen");
            season2.addCharaters(character);
            character = new Seasons("Laurel Lance");
            season2.addCharaters(character);
            character = new Seasons("Sara Lance");
            season2.addCharaters(character);
    
            // Adding Master Values (seasons)
            Seasons season3 = new Seasons("Vikings");
          // Adding Detail Values (Child Node-Characters)
            character = new Seasons("Ragnar Lothrak");
            season3.addCharaters(character);
    
            // Adding all list to topList
            seasonList.add(season1);
            seasonList.add(season2);
            seasonList.add(season3);
            // Filtering Child Data, ChildPropertyTreeModel creates a TreeModel from a List of beans, see
            // https://myfaces.apache.org/trinidad/trinidad-api/apidocs/org/apache/myfaces/trinidad/model/ChildPropertyTreeModel.html
            charatcerVal = new ChildPropertyTreeModel(seasonList, "characters");
        }
    
        public ChildPropertyTreeModel getCharatcerVal() {
            return charatcerVal;
        }
    }
    

  • Now code part is complete, now configure your treeTable to show data, see XML source of af:treeTable

  • <af:treeTable rowBandingInterval="0" id="tt1"
                                  value="#{pageFlowScope.ProgrammaticTreeTabBean.charatcerVal}" var="node"
                                  rowSelection="single" initiallyExpanded="true">
                        <f:facet name="nodeStamp">
                            <af:column headerText="Node Stamp" id="c1" width="250">
                                <af:outputText value="#{node.name}" id="ot1" inlineStyle="font-weight:bold;"/>
                            </af:column>
                        </f:facet>
                    </af:treeTable>
    

  • Now run your application and check , what you have done ;)
Happy Learning :) Sample ADF Application (12.1.3)

Monday, 21 October 2013

Expand and Collapse an af:treeTable programmatically in ADF Faces (Oracle ADF)

Hello all,
this is simple tutorial about expanding and collapsing an af:treeTable using managed bean code (programmatically)
sometimes we need to expand or collapse treeTable on some button action or on valueChangeEvent.

Steps-

  • Create binding of treeTable in managed bean
  •  private RichTreeTable soTreeTableBind;
         public void setSoTreeTableBind(RichTreeTable soTreeTableBind) {
            this.soTreeTableBind = soTreeTableBind;
        }
    
        public RichTreeTable getSoTreeTableBind() {
            return soTreeTableBind;
        }
    

  • Now Call this method on any action to expand treeTable

  • private RowKeySet disclosedTreeRowKeySet = new RowKeySetImpl();
    



        /***Method to expand all tree table nodes*/
        private void expandTreeTable() {
            if (this.soTreeTableBind != null) {
                disclosedTreeRowKeySet = new RowKeySetImpl();
                CollectionModel model = (CollectionModel)soTreeTableBind.getValue();
                JUCtrlHierBinding treeBinding = (JUCtrlHierBinding)model.getWrappedData();
                JUCtrlHierNodeBinding rootNode = treeBinding.getRootNodeBinding();
                disclosedTreeRowKeySet = soTreeTableBind.getDisclosedRowKeys();
                if (disclosedTreeRowKeySet == null) {
                    disclosedTreeRowKeySet = new RowKeySetImpl();
                }
                List<JUCtrlHierNodeBinding> firstLevelChildren = rootNode.getChildren();
                for (JUCtrlHierNodeBinding node : firstLevelChildren) {
                    ArrayList list = new ArrayList();
                    list.add(node.getRowKey());
                    disclosedTreeRowKeySet.add(list);
                    expandTreeChildrenNode(soTreeTableBind, node, list);
                }
                soTreeTableBind.setDisclosedRowKeys(disclosedTreeRowKeySet);
            }
        }
    /**Method to expand childs*/
        private void expandTreeChildrenNode(RichTreeTable rt, JUCtrlHierNodeBinding node, List<Key> parentRowKey) {
            ArrayList children = node.getChildren();
            List<Key> rowKey;
            if (children != null) {
                for (int i = 0; i < children.size(); i++) {
                    rowKey = new ArrayList<Key>();
                    rowKey.addAll(parentRowKey);
                    rowKey.add(((JUCtrlHierNodeBinding)children.get(i)).getRowKey());
                    disclosedTreeRowKeySet.add(rowKey);
                    if (((JUCtrlHierNodeBinding)(children.get(i))).getChildren() == null)
                        continue;
                    expandTreeChildrenNode(rt, (JUCtrlHierNodeBinding)(node.getChildren().get(i)), rowKey);
                }
            }
        }
    

  • To collapse treeTable ,use this code snippet on any event

  •     /**Collapse TreeTable
         * @param actionEvent
         */
        public void collapseTreeTableAction(ActionEvent actionEvent) {
            soTreeTableBind.getDisclosedRowKeys().clear();
            AdfFacesContext.getCurrentInstance().addPartialTarget(soTreeTableBind);
        }
    

Friday, 27 September 2013

Refreshing Child Nodes of an af:treeTable / af:tree in Oracle ADF

Hello All,
A very common problem in ADF treeTable and tree is to refresh child nodes after any DML operation on tree.
to avoid this refresh problem developer can pragmatically refresh treeTable's child node.


  • First get the master ViewObject on that treeTable is based
  • if viewObject has any key attribute then filter it against a key for that you want to refresh child nodes
  • if viewObject doesn't have any key attribute, then filter it using any unique key to get header(master) row
  • get the rowset of child rows for that key, using viewlink accessor
  • and execute query for Child Rows rowset
  • see the refreshed child node :-)

Code- Using Key Attribute


// Get Master ViewObject
    ViewObjectImpl viewObj = masterViewObject;  
    // Filter It Using Key Attribute
  Row[] grpRow = vo.findByKey(new Key(new Object[] { keyAttribute Value }), 1);  
       // Get Child Rows using ViewLink Accessor
        if(grpRow.length>0){
        RowSet childRows = (RowSet)grpRow[0].getAttribute("viewLink AccessorName");  
  //Execute Child Rowset
        childRows.executeQuery();  
        }

Using Unique Key






      // Get Master ViewObject
    ViewObjectImpl viewObj = masterViewObject;  
    // Filter It Using Key Attribute
   Row[] grpRow=viewObj.getFilteredRows("uniqueKey", uniqueKey Value); 
       // Get Child Rows using ViewLink Accessor
        if(grpRow.length>0){
        RowSet childRows = (RowSet)grpRow[0].getAttribute("viewLink AccessorName");  
  //Execute Child Rowset
        childRows.executeQuery();  
        }
  

Somo more blogs on tree table
Programmatically refreshing the child nodes of an <af:tree>
Tree Table Component in Oracle ADF(Hierarchical Representation)
Implementing master/detail tree relation using af:Iterator and af:forEach for better UI designs - Oracle ADF 
Tree Table Component with declarative presentation in ADF, Access childs without custom selection listener
CRUD operations on a tree table
Tree Table Component in Oracle ADF

Cheers :-)

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 -