Please disable your adblock and script blockers to view this page

Search this blog

Tuesday, 26 November 2013

Apply Filter on af:table column programmatically ,Invoke 'FilterableQueryDescriptor' through managed bean

Hello All
This tutorial is about a requirement of filtering af:table column through code,
to achieve this we can invoke FilterableQueryDescriptor (FilterableQueryDescriptor is an abstract subclass of QueryDescriptor. It adds support for filtering of data and is typically used by the table component to filter data from a query )

Suppose i have department table and i have to filter on department column-
  • Create a Fusion Web Application and business components for Departments (HR Schema) table
  • now drag table on page and bind it to bean
  • Now drop a input text and button on page to enter Department Name
  • bind input text to bean and create ActionListener on button to filter Department Table
See XML source of Page-




<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="filterPage.jspx" id="d1">
            <af:messages id="m1"/>
            <af:form id="f1">
                <af:inputText label="Department Name" id="it5"
                              binding="#{pageFlowScope.FilterProgrammaticBean.deptNmBind}"/>
                <af:commandButton text="Filter" id="cb1"
                                  actionListener="#{pageFlowScope.FilterProgrammaticBean.filterTableAction}"/>
                <af:table value="#{bindings.DepartmentsView1.collectionModel}" var="row"
                          rows="#{bindings.DepartmentsView1.rangeSize}"
                          emptyText="#{bindings.DepartmentsView1.viewable ? 'No data to display.' : 'Access Denied.'}"
                          fetchSize="#{bindings.DepartmentsView1.rangeSize}" rowBandingInterval="1"
                          selectedRowKeys="#{bindings.DepartmentsView1.collectionModel.selectedRow}"
                          selectionListener="#{bindings.DepartmentsView1.collectionModel.makeCurrent}"
                          rowSelection="single" id="t1" styleClass="AFStretchWidth"
                          binding="#{pageFlowScope.FilterProgrammaticBean.deptTabBind}"
                          filterModel="#{bindings.DepartmentsView1Query.queryDescriptor}"
                          queryListener="#{bindings.DepartmentsView1Query.processQuery}" filterVisible="true"
                          varStatus="vs">
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.DepartmentId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.DepartmentId.label}" id="c1"
                               filterable="true">
                        <af:inputText value="#{row.bindings.DepartmentId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.DepartmentId.label}"
                                      required="#{bindings.DepartmentsView1.hints.DepartmentId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.DepartmentId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.DepartmentId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.DepartmentId.tooltip}" id="it1"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.DepartmentId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.DepartmentId.format}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.DepartmentName.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.DepartmentName.label}" id="c2"
                               filterable="true">
                        <af:inputText value="#{row.bindings.DepartmentName.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.DepartmentName.label}"
                                      required="#{bindings.DepartmentsView1.hints.DepartmentName.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.DepartmentName.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.DepartmentName.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.DepartmentName.tooltip}" id="it2"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.DepartmentName.validator}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.ManagerId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.ManagerId.label}" id="c3"
                               filterable="true">
                        <af:inputText value="#{row.bindings.ManagerId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.ManagerId.label}"
                                      required="#{bindings.DepartmentsView1.hints.ManagerId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.ManagerId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.ManagerId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.ManagerId.tooltip}" id="it3"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.ManagerId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.ManagerId.format}"/>
                        </af:inputText>
                    </af:column>
                    <af:column sortProperty="#{bindings.DepartmentsView1.hints.LocationId.name}" sortable="true"
                               headerText="#{bindings.DepartmentsView1.hints.LocationId.label}" id="c4"
                               filterable="true">
                        <af:inputText value="#{row.bindings.LocationId.inputValue}"
                                      label="#{bindings.DepartmentsView1.hints.LocationId.label}"
                                      required="#{bindings.DepartmentsView1.hints.LocationId.mandatory}"
                                      columns="#{bindings.DepartmentsView1.hints.LocationId.displayWidth}"
                                      maximumLength="#{bindings.DepartmentsView1.hints.LocationId.precision}"
                                      shortDesc="#{bindings.DepartmentsView1.hints.LocationId.tooltip}" id="it4"
                                      readOnly="true">
                            <f:validator binding="#{row.bindings.LocationId.validator}"/>
                            <af:convertNumber groupingUsed="false"
                                              pattern="#{bindings.DepartmentsView1.hints.LocationId.format}"/>
                        </af:inputText>
                    </af:column>
                </af:table>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

Managed Bean Code-


package filter.view;

import java.util.Map;

import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.context.AdfFacesContext;
import oracle.adf.view.rich.event.QueryEvent;
import oracle.adf.view.rich.model.FilterableQueryDescriptor;


public class FilterProgrammaticBean {
    private RichInputText deptNmBind;
    private RichTable deptTabBind;

    public FilterProgrammaticBean() {
    }

    public void setDeptNmBind(RichInputText deptNmBind) {
        this.deptNmBind = deptNmBind;
    }

    public RichInputText getDeptNmBind() {
        return deptNmBind;
    }

    public void setDeptTabBind(RichTable deptTabBind) {
        this.deptTabBind = deptTabBind;
    }

    public RichTable getDeptTabBind() {
        return deptTabBind;
    }

    /**Method to invoke FilterableQueryDescriptor and Filter Department table
     * @param actionEvent
     */
    public void filterTableAction(ActionEvent actionEvent) {
        RichTable tbl = this.getDeptTabBind();
        FilterableQueryDescriptor filterQD = (FilterableQueryDescriptor)tbl.getFilterModel();
        Map filterCriteria = filterQD.getFilterCriteria();
        filterCriteria.put("DepartmentName", deptNmBind.getValue());
        getDeptTabBind().queueEvent(new QueryEvent(getDeptTabBind(), filterQD));
        AdfFacesContext.getCurrentInstance().addPartialTarget(this.getDeptTabBind());
    }
}

Run your Application-





Cheers- Download Sample App

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 :-)