Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label Programmatically. Show all posts
Showing posts with label Programmatically. Show all posts

Monday 24 November 2014

Populate af:table programmatically from managead bean using POJO

This post is about a common question
How can we populate an af:table programmatically ?

It means that data in af:table is not populated through model layer (Using ViewObject) using binding layer. lets say I have some values in our managed bean and have to show records in tabular format on page

So what we have to do -
  • First you should know the number and data type of columns in table, suppose i have to populate a table for person details (name, mobile number and salary). to get and set value of columns i have created a java bean class , it has 3 variable for 3 columns



  • // Java Class to set and get value for table column
    public class PersonBean {
    
        public PersonBean(String name, String moNo, Integer salary) {
            this.Name = name;
            this.mobNo = moNo;
            this.salary = salary;
        }
        private String Name;
        private String mobNo;
        private Integer salary;
    
        public void setName(String Name) {
            this.Name = Name;
        }
    
        public String getName() {
            return Name;
        }
    
        public void setMobNo(String mobNo) {
            this.mobNo = mobNo;
        }
    
        public String getMobNo() {
            return mobNo;
        }
    
        public void setSalary(Integer salary) {
            this.salary = salary;
        }
    
        public Integer getSalary() {
            return salary;
        }
    }
    

  • Next step is to create a managed bean for referencing af:table , this managed bean makes use of person java bean class to add data in same format for all table rows. A List data structure is used to pass all values in af:table. See code of managed bean 

  • //ArrayList to poplate data in af:table
        List<PersonBean> personList = new ArrayList();
    
        //To Populate default row in table (Code in Constructor)
    
        public ProgTableBean() {
            personList.add(new PersonBean("Ashish Awasthi", "xxxxxxxxxx", 50000));
        }
    
        public void setPersonList(List<PersonBean> personList) {
            this.personList = personList;
        }
    
        public List<PersonBean> getPersonList() {
            return personList;
        }
    

  • Now just drop an af:table on page and set it's properties like value, column header and text values in columns

  •  As i have to show only 3 columns so deleted extra ones

     Set properties -
     value- from where table collection is populated
     columns values- take the var reference of table and refer variable name in List (here 'row' is table var and second is variable name in person bean class)


     See the XML source of af:table-

    <af:table var="row" rowBandingInterval="1" id="t1" value="#{viewScope.ProgTableBean.personList}"
                              partialTriggers="::b1">
                        <af:column sortable="false" headerText="Name" id="c1" width="150">
                            <af:outputText value="#{row.name}" id="ot1"/>
                        </af:column>
                        <af:column sortable="false" headerText="Mobile Number" id="c2">
                            <af:outputText value="#{row.mobNo}" id="ot2"/>
                        </af:column>
                        <af:column sortable="false" headerText="Salary" id="c3" align="right">
                            <af:outputText value="#{row.salary}" id="ot3"/>
                        </af:column>
                    </af:table>
    

  • Now run this application and see there will be one row in table as code is added in constructor of managed to populate one row


  • I have added a form and button in page to add new records in table , see the form source code

  • <af:panelFormLayout id="pfl1">
                        <f:facet name="footer"/>
                        <af:inputText label="Name :" id="it1" binding="#{viewScope.ProgTableBean.nameBind}"/>
                        <af:inputText label="Mobile Number :" id="it2" binding="#{viewScope.ProgTableBean.mobNumBind}"/>
                        <af:inputText label="Salary :" id="it3" binding="#{viewScope.ProgTableBean.salaryBind}">
                            <af:convertNumber/>
                        </af:inputText>
                        <af:button text="Add Record" id="b1" actionListener="#{viewScope.ProgTableBean.addNewRcord}"/>
                    </af:panelFormLayout> 
     

    Code in managed bean for button action-

        /**Method to add new record in table
         * @param actionEvent
         */
        public void addNewRcord(ActionEvent actionEvent) {
            //Get all values using compoenet binding as mobNumBind
            if (mobNumBind.getValue() != null && nameBind.getValue() != null &&
                salaryBind.getValue() !=
                null) {
                // Add new Record in List
                personList.add(new PersonBean(nameBind.getValue().toString(), mobNumBind.getValue().toString(),
                                              Integer.parseInt(salaryBind.getValue().toString())));
            }
        }
    

  • now run and check application- 


 More posts on POJO Based table -

Get selected row (single/multiple) from POJO based table in ADF
Apply sorting to POJO based af:table programmatically , Using custom sort listener in ADF

Thanks , Happy Learning :)
Download-Sample ADF Application

Monday 13 October 2014

Set values in af:selectManyChoice programmatically - Oracle ADF

This post is about a very common question
How to set selected values in af:selectManyChoice component ?
Sometimes we need to set some values in selectManyChoice component on some action

In this post i am using Departments table of HR Schema to create selectManyChoice (Multiple Selection)
Just drag and drop Departments viewObject as ADF Select Many Choice
see- Using Multiple Selection (selectManyListbox & selectManyCheckbox component) in ADF


(Jdev Version- 12.1.3)
dropped a button on page and on this button action ,  setting values in component
See this simple managed bean code -




import java.util.ArrayList;

import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.component.rich.input.RichSelectManyChoice;
import oracle.adf.view.rich.context.AdfFacesContext;

public class SetValueSmcBean {
    private RichSelectManyChoice selectMcBind;

    public SetValueSmcBean() {
    }

    /**Methos to set selected values in SelectManyChoice
     * @param actionEvent
     */
    public void setSelectedValuesAction(ActionEvent actionEvent) {
        ArrayList listVal = new ArrayList(20);
        //Add DepartmentId to list that you want to set as selected
        listVal.add(101);
        listVal.add(102);
        // Set this List as value using component binding
        selectMcBind.setValue(listVal.toArray());
        //Refresh Component on page (partial target)
        AdfFacesContext.getCurrentInstance().addPartialTarget(selectMcBind);
    }

    public void setSelectMcBind(RichSelectManyChoice selectMcBind) {
        this.selectMcBind = selectMcBind;
    }

    public RichSelectManyChoice getSelectMcBind() {
        return selectMcBind;
    }
}

run application and check-

Downoad Sample Application
Thanks , Happy Learning :)

Thursday 28 August 2014

Create taskFlow and region binding at run-time , show n numbers of regions using multiTaskFlow- Oracle ADF

This is very specific development requirement to create taskFlow and region binding at run-time to show n numbers of region in page
In this case initially you don't know how much regions required in page as it depends on user activity .

you can see in http://irctc.co.in/ (Indian Railways) site
when user search for a train and check berth availability then a tab is generated at run-time with berth and fare details and it continues for each action , every time a new tab with new information is generated (n- number of tab and taskFlow)

A very good article is published in Oracle Magazine (July – August 2014) by Frank Nimphius on this requirement , article contains very good description of each and every step and a sample application with whole functionality
I found it very interesting and good so giving a quick overview of TaskFlow on Fly

this functionality is implemented using multiTaskFlow element that uses taskFlow binding from managed bean , taskFlow bindings in managed bean created using TaskFlowBindingAttributes
this class is used to set all properties of taskFlow binding at runtime



See Oracle docs (TaskFlowBindingAttributes)-
Set of attributes that define a TaskFlowBinding object. The taskFlowList attribute of the multiTaskFlow element of the page definition uses a list of object of this type to describe each taskflowBinding that the multiTaskflow binding contains. The order of this list defines the order of the region objects in the multiTaskflow binding. 

So in this post i am using Departments and Employees table of HR Schema(Oracle) to create business components for Model part


Create viewCriteria in both viewObjects (Departments and Employees) to filter data using DepartmentId




Applied viewCriteria to viewObject at AM level (Edit Vo instance and shuttle viewCriteria to selected side)
After this created methods in AMImpl class to set value in both viewCriteria's bind variables


    /**Method to filter Department ViewObject
     * @param deptId
     */
    public void filterDepartmentData(Integer deptId) {
        this.getDepartments1().setNamedWhereClauseParam("BindDeptId", deptId);
        this.getDepartments1().executeQuery();

    }

    /**Method to filter Employees Data
     * @param deptId
     */
    public void filterEmployeesData(Integer deptId) {
        this.getEmployees1().setNamedWhereClauseParam("BindDeptId", deptId);
        this.getEmployees1().executeQuery();

    }

Expose both methods to use in clientInterface

Now viewController part-

Created two bounded taskFlow with one input parameter for DepartmentId (this id will be used to filter Departments and Employess viewObject)
One for Departments and Second for Employees-

First taskFlow has a .jsff (facelets) page that has Departments viewObject as a form , just to show date with navigation buttons
filterDepartmentData method of AMImpl is used as Default Activity of this taskFlow
to filter data before entering in page
 
 
 

Second taskFlow has a .jsff (facelets) page that has Employees viewObject as a table
filterEmployeesData method of AMImpl is used as Default Activity of this taskFlow
to filter data before entering in page



Now basic configuration is complete, model is ready and bounded taskFlows are ready
then create a jsf page and manged bean (pageFlowScope) in adfc-config.xml, this page will make use of these two bounded taskFlows  and managed bean is responsible to generate taskFlow binding at runtime

Next Step is to prepare manged bean to hold taskFlowBinding-
Create a List of type TaskFlowBindingAttributes and it's accessors


import oracle.adf.controller.binding.TaskFlowBindingAttributes;    
private List<TaskFlowBindingAttributes> taskFlowBinding = new ArrayList<TaskFlowBindingAttributes>(5);

    public void setTaskFlowBinding(List<TaskFlowBindingAttributes> taskFlowBinding) {
        this.taskFlowBinding = taskFlowBinding;
    }

    public List<TaskFlowBindingAttributes> getTaskFlowBinding() {
        return taskFlowBinding;
    }

Create multiTaskFlow binding in executables of pgae-

  • Open jsf page, click on bindings tab of page editor
  • click on green plus icon of executables section
  • Select ADF TaskFlow Bindings in category and select multiTaskFlow


  • click on ok and provide an unique value for id attribute and reference of List created in managed bean as value for taskFlowList attribute


  • Configuration of  multiTaskFlow for this page is complete and now time to design page to render multiple regions. For this purpose add af:ForEach and a region inside it, forEach is responsible to add regions at run-time. here a little change i am using panelTabbed  to create tab at runtime and inside tab there will be region 
  • See this xml code- here nothing simple panelTabbed and forEach iterates over to list to identify number of items and varStatus of forEach is used to create id of showDetailItem at runtime as id must be unique. regionModel is referenced from var attributes of forEach as part of taskFlowBinding 

  •  <af:panelTabbed position="above" id="pt1" partialTriggers="b1">
                <af:forEach items="#{bindings.mtf1.taskFlowBindingList}" var="multiTF" varStatus="vs">
                   <af:showDetailItem id="Tab#{vs.index+1}" text="#{multiTF.name}" partialTriggers="b1">
                      <af:region value="#{multiTF.regionModel}" id="r1#{vs.index}" partialTriggers="::b1"/>
                   </af:showDetailItem>
                </af:forEach>
             </af:panelTabbed>
    

  • Now page is ready to show unknown (n) number of regions, here i am using two list and a button on page First List is of all departments and second one is static list to select information type (if user want to see Only Departments or Departments Wise Employees) and button to execute and add taskFlow from managed bean as per selected Department and 
  • Again a map is created in managed bean to store input parameters for taskFlow and it will used while setting and creating taskFlowBinding

  •     HashMap<String, Object> tfParam = new HashMap<String, Object>();
        public void setTfParam(HashMap<String, Object> tfParam) {
            this.tfParam = tfParam;
        }
    
        public HashMap<String, Object> getTfParam() {
            return tfParam;
        }
    

  • finally we will create taskFlow binding and set properties on button click (actionEvent of button), See this code-

  •     /**Method to create and set properties in TaskFlowBinding
         * @param actionEvent
         */
        public void displayDepartmentAction(ActionEvent actionEvent) {
            //Clear List to show newly created regions only
            taskFlowBinding.clear();
            System.out.println("List Cleared -Size>" + taskFlowBinding.size());
            //Check that user selects value in both List (Uses component binding to check)
            if (deptIdBindVal.getValue() != null && showTypeBind.getValue() != null) {
                //Put value in TaskFLow Parameter map, deptIdBindVal is binding of list of departments on page
                tfParam.put("DeptIdParam", deptIdBindVal.getValue());
    
                //Only Shows Departments taskFlow, if user selectes "Only Departments"
                if ("Only Departments".equalsIgnoreCase(showTypeBind.getValue().toString())) {
                    //Setting taskFlow properties
                    TaskFlowBindingAttributes tfAttr = new TaskFlowBindingAttributes();
                    //Creating Unique Id
                    tfAttr.setId("Department_" + deptIdBindVal.getValue());
                    //See bounded taskFlow name in WEB-INF and use here
                    tfAttr.setTaskFlowId(new TaskFlowId("/WEB-INF/DepartmentsBTF.xml", "DepartmentsBTF"));
                    //This EL refers parameter map created in this managedBean
                    tfAttr.setParametersMap("#{pageFlowScope.MultiTaskFlowBean.tfParam}");
                    //Finally add taskFlow to List
                    taskFlowBinding.add(tfAttr);
                } else { // Show both Departments and Employees
                    //Creating Departments TaskFlow binding
                    TaskFlowBindingAttributes tfAttr = new TaskFlowBindingAttributes();
                    tfAttr.setId("Department_" + deptIdBindVal.getValue());
                    tfAttr.setTaskFlowId(new TaskFlowId("/WEB-INF/DepartmentsBTF.xml", "DepartmentsBTF"));
                    tfAttr.setParametersMap("#{pageFlowScope.MultiTaskFlowBean.tfParam}");
                    taskFlowBinding.add(tfAttr);
                    //Creating Employee TaskFlow biniding
                    tfAttr = new TaskFlowBindingAttributes();
                    tfAttr.setId("Employees_" + deptIdBindVal.getValue());
                    tfAttr.setTaskFlowId(new TaskFlowId("/WEB-INF/EmployeesBTF.xml", "EmployeesBTF"));
                    tfAttr.setParametersMap("#{pageFlowScope.MultiTaskFlowBean.tfParam}");
                    taskFlowBinding.add(tfAttr);
                }
            }
        }
    

  • So Application with multiTaskFlow is ready , in this post i have used these two bounded taskFlow to show in two tabs at run-time, in same way you can call multiple TFs or a single taskFlow multiple time. Now runt application and see how it works

Initial page with two lists


Select Department and show type -click on button


Select Department and show type -click on button


  • Refer this post Region Extreme: Multi-Task-Flow Binding to learn more about multiTaskFlow binding. In this Frank also told about how to use dynamic viewObject instance to show different data at run-time, because if we use same instance of viewObject in multiple taskFlow at same time then it will not maintain state for each region to it is necessary to use dynamic instance and it's binding in pageDef
  • Read more about regions and taskFlows- Using Task Flows as Regions
Thanks - Happy Learning :) 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 23 June 2014

Navigating to (open) specific tab in af:panelTabbed programmatically -Oracle ADF

Hello All,
This post is about a development requirement - how to move (navigate or open) to a specific tab in panel tabbed  in Oracle ADF?
Suppose i have to open second tab of af:panelTabbed on a button click, so see how to do this using ADF Faces
  • Create a Fusion Web application and a page to drop panel tabbed and a button


  • now bind panel tabbed and it's showDetailItem to managed bean, in order to use disclosed property and to get client id
  • See the code to open (disclose) a specific tab of af:panelTabbed
        //Binding of Panel Tabbed
        private RichPanelTabbed panelTabBind;
    
        public void setPanelTabBind(RichPanelTabbed panelTabBind) {
            this.panelTabBind = panelTabBind;
        }
    
        public RichPanelTabbed getPanelTabBind() {
            return panelTabBind;
        }
    
        /**
         * @Method to disclose (open) specific tab
         * Pass the binding of af:showDetailItem that you want to open
         */
        public void setDisclosedFirstTab(RichShowDetailItem tabBind) {
            RichPanelTabbed richPanelTabbed = getPanelTabBind();
            for (UIComponent child : richPanelTabbed.getChildren()) {
                RichShowDetailItem sdi = (RichShowDetailItem) child;
                if (sdi.getClientId().equals(tabBind.getClientId())) {
                    sdi.setDisclosed(true);
                } else {
                    sdi.setDisclosed(false);
                }
            }
            AdfFacesContext.getCurrentInstance().addPartialTarget(panelTabBind);
        }
    

  • Now see the code written on button action- here i have checked that which tab is currently disclosed? and based on that i have passed next tab binding to this method



  •     /**Method to be called on Navigate Button
         * @param actionEvent
         */
        public void naviGateButtonAction(ActionEvent actionEvent) {
            if (firstTabBind.isDisclosed()) {
                setDisclosedFirstTab(secTabBind);
            } else if (secTabBind.isDisclosed()) {
                setDisclosedFirstTab(thirdTabBind);
            } else {
                setDisclosedFirstTab(firstTabBind);
            }
        }
    

  • now run your page and see navigation in af:panelTabbed

 Cheers Happy Learning :) Sample ADF Application

Monday 12 May 2014

Getting selected value (not index) & display value of select one choice programmatically in ADF

Hello All,
This post is about a common requirement of getting selected value & display value of af:selectOneChoice in managed bean
normally when we try to get selected value of  selectOneChoice in managed bean (in ValueChange/ Validator or using binding) it returns index of that row
so there is a little piece of code using that we can get selected value of choice component

  • I have used Departments table of HR Schema in sample and created a lov on a transient field


  • Now dropped that ViewObject on page as a table 


  • Created a value change listener in managed bean fro DeptIdTrans but it return index of selected value





  • Then i googled about it and used this method to solve my headache, try to get attributeValue instead of inputValue, see the code written in valueChaneListener in managed bean

  •     /**Value Change Listener of DeptIdTrans (to get selected and display value)
         * @param vce
         */
        public void deptIdVCE(ValueChangeEvent vce) {
            System.out.println("New Value is-" + vce.getNewValue());
            if (vce.getNewValue() != null) {
                this.setvalueToExpression("#{row.bindings.DeptIdTrans.inputValue}",
                                          vce.getNewValue()); //Updating Model Values
                Integer selectedCode =
                    Integer.parseInt(this.getValueFrmExpression("#{row.bindings.DeptIdTrans.attributeValue}").toString());
    
                System.out.println("******** Selected Value in List***** " + selectedCode);
                System.out.println("*******Display Value in List ****" +
                                   getValueFrmExpression("#{row.bindings.DeptIdTrans.selectedValue.attributeValues[1]}"));
    
            }
        }
    

  • There is two methods to set and get value in expression (EL)

  •     /**Method to set value in Expression (EL)
         * @param el
         * @param val
         */
        public void setvalueToExpression(String el, Object val) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ELContext elContext = facesContext.getELContext();
            ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
            ValueExpression exp = expressionFactory.createValueExpression(elContext, el, Object.class);
            exp.setValue(elContext, val);
        }
    
        /**Method to get value from Expression (EL)
         * @param data
         * @return
         */
        public String getValueFrmExpression(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);
            String Message = null;
            Object obj = valueExp.getValue(elContext);
            if (obj != null) {
                Message = obj.toString();
            }
            return Message;
        }
    

  • Again run page and select any value in selectOneChoice (lov) and see the result

Cheers :-) Happy Learning