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

Wednesday 6 May 2015

Get Value from programmatically created components , Iterate over parent component to get child values in ADF Faces

Sometimes we need to create and add ADF Faces components at runtime , we can do it programmatically
I have posted about this before
Creating dynamic layout (form and UI Component) using ADF Faces

Now this post talks about getting value from programmatically created component, means when user enters value in those component then how to access that value in managed bean

Here i am using Jdev 12.1.3 , Let's see the implementation part

Created a page and added two buttons , one to create component at run time and second one to get values from those components
See page XML source code -

<af:document title="ProgComponent.jspx" id="d1">
            <af:form id="f1">
                <af:spacer width="10" height="10" id="s3"/>
                <af:button text="Create Components " id="b1"
                           actionListener="#{viewScope.GetValueProgCompBean.createComponentsAction}"/>
                <af:spacer width="10" height="10" id="s1"/>
                <af:button text="Get Value" id="b2"
                           actionListener="#{viewScope.GetValueProgCompBean.getValueOfCompAction}"/>
                <af:panelGroupLayout id="pgl1" layout="vertical"
                                     binding="#{viewScope.GetValueProgCompBean.parentGroupBind}">
                    <af:spacer width="10" height="10" id="s2"/>
                </af:panelGroupLayout>
            </af:form>
        </af:document>

To create components at run time i have used same approach described in above blog post
Check the code written on Create Components button



import javax.faces.component.UIComponent;
import javax.faces.event.ActionEvent;

import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.component.rich.layout.RichPanelGroupLayout;
import oracle.adf.view.rich.context.AdfFacesContext;


    //Binding of panel group layout , it will be parent of prog. created components
    private RichPanelGroupLayout parentGroupBind;

    public void setParentGroupBind(RichPanelGroupLayout parentGroupBind) {
        this.parentGroupBind = parentGroupBind;
    }

    public RichPanelGroupLayout getParentGroupBind() {
        return parentGroupBind;
    }

    /**Method to add child components to parent
     * @param parentUIComponent
     * @param childUIComponent
     */
    public void addComponent(UIComponent parentUIComponent, UIComponent childUIComponent) {
        parentUIComponent.getChildren().add(childUIComponent);
        AdfFacesContext.getCurrentInstance().addPartialTarget(parentUIComponent);
    }

    /**Method to create Input text at run time
     * @param actionEvent
     */
    public void createComponentsAction(ActionEvent actionEvent) {
        //Create an Object of desired UI Component
        RichInputText ui = new RichInputText();
        //Set properties
        ui.setId("rit1");
        ui.setLabel("Input text 1");
        ui.setContentStyle("font-weight:bold;color:red");
        //Now add this component to any parent component
        addComponent(getParentGroupBind(), ui);

        RichInputText ui1 = new RichInputText();
        ui1.setId("rit2");
        ui1.setLabel("Input text 2");
        ui1.setContentStyle("font-weight:bold;color:red");
        addComponent(getParentGroupBind(), ui1);
    }

Now run application and click on button , you will see two inputText are created


Now to get value of these components follow the steps
1. Get Parent layout
2. Iterate over parent to get all child components
3. Get Value of every child

See the code written on get value button in managed bean

    /**Method to Iterate over parent and get value of all child components
     * @param actionEvent
     */
    public void getValueOfCompAction(ActionEvent actionEvent) {
        RichPanelGroupLayout PF = getParentGroupBind(); // Get Parent Layout
        List<UIComponent> listcomp = PF.getChildren(); // Get all child
        Iterator iter = listcomp.iterator(); // Create an Iteraotr to iterate over childs
        while (iter.hasNext()) {
            UIComponent comp = (UIComponent) iter.next(); // Get next Child Component
            System.out.println("Component is-" + comp + " and value is-" +
                               comp.getAttributes().get("value")); //Get Component detial and it's value
        }
    }

Again check , enter value in both inputText and click on button to get value


Output on console-

Sample ADF Application- Download
Cheers :) Happy Learning

Thursday 16 April 2015

Build selectOneChoice to show hierarchical (tree style) data programmatically in ADF

This post is based on an old article from Frank Nimphius How - to build a select one choice displaying hierarchical selection data

This article is about showing tree structure data in af:selectOneChoice component using ADF BC , it makes use of tree binding and af:forEach
Same concept i have used to populate data from managed bean using List data structure

Let's see the implementation part - how to populate tree style selectOneChoice programatically ?

First we have to design a Java Bean class in such a way that it can hold  master -detail type of data

A class that represents a List for Parent Values
                          ======> A list of same type to hold Child Values

See bean class code-

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 :))
    }
    // Season and Charater Name
    private String name;
    // To Store Detail Values (Storing Season's Charatcers)
    private List<Seasons> characters = new <Seasons>ArrayList();

    public void setCharacters(List<Seasons> empDet) {
        this.characters = empDet;
    }

    public List<Seasons> getCharacters() {
        return characters;
    }


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    // This methods directly add characters value in list
    public void addCharaters(Seasons employee) {
        characters.add(employee);
    }
}

Now how to use this bean in managed bean to add records, i have written code in constructor to populate values on class load




    // Master List to populate data in selectOnce choice
    List<Seasons> seasonList = new ArrayList<Seasons>();

    public void setSeasonList(List<Seasons> seasonList) {
        this.seasonList = seasonList;
    }

    public List<Seasons> getSeasonList() {
        return seasonList;
    }
    //Constructor of Managed Bean to populate data on page load (you can move this code )
    public TreeStyleLovBean() {
        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 Master Values (seasons)
        Seasons season4 = new Seasons("The Flash");

        // Adding Detail Values (Child Node-Characters)
        character = new Seasons("Barry Allen");
        season4.addCharaters(character);
        character = new Seasons("Harisson Wells");
        season4.addCharaters(character);
        character = new Seasons("Iris West");
        season4.addCharaters(character);
        character = new Seasons("Joe");
        season4.addCharaters(character);

        // Adding all list to topList
        seasonList.add(season1);
        seasonList.add(season2);
        seasonList.add(season3);
        seasonList.add(season4);

    }
how to bind this managed bean to selectOneChoice ? i have used same concept as described in Frank's article using af:forEach


<af:selectOneChoice id="selectBox" label="Choose Character" valuePassThru="true"
                                        styleClass="employeeSelectBox" contentStyle="width:150px;"
                                        binding="#{viewScope.TreeStyleLovBean.selectOneValueBind}">
                        <af:forEach items="#{viewScope.TreeStyleLovBean.seasonList}" var="seasonNm">
                            <af:selectItem label="#{seasonNm.name}" disabled="true" id="si1"/>
                            <af:forEach items="#{seasonNm.characters}" var="characterNm">
                                <af:selectItem label="#{characterNm.name}" value="#{characterNm.name}" id="si2"/>
                            </af:forEach>
                        </af:forEach>
                    </af:selectOneChoice>

you can see here that first forEach is populated from master list and iterates over list of seasons and first selectItem show season's name
the inner forEach makes used of character list that is defined in Java Bean class and stores season wise character's name
Rest is same - a CSS is used to differentiate color and alignment of parent and child records (same as Frank's article)


<f:facet name="metaContainer">
                <af:group>
                    <![CDATA[
<style>
.employeeSelectBox option{text-indent:15px;color:darkgreen;}
.employeeSelectBox option[disabled]{color:red; background-color:#dddddd; 
font-weight: bold; text-indent:0px}
</style>
]]>
                </af:group>
            </f:facet>

Now run this application - see how it appears on page



It looks quite good :) to get selected value in bean just use componentBinding.getValue();

Sample ADF Application-Download (Jdev 12.1.3)
Cheers , Happy Learning 

Sunday 22 March 2015

ADF Basics: Apply and Change WHERE Clause of ViewObject at runtime programmatically

This post is about applying or changing WHERE clause of ViewObject programmatically, it can be also used in case we need a specific data(row) from database, suppose you are using Department table of HR Schema and on a button click you need to show records of department id 5

It means you want to filter viewObject on that particular event, you can do this using setWhereClause mehtod of ViewObjectImpl class.
See the image below , all rows shown in this


Now when we click the button, it will filter (apply WHERE Clause in Departments ViewObject) rows and refresh ViewObject , returns desired rows.




For Department_Id 4-



For Department_Id 5-



To apply WHERE Clause , see this simple snippet of code

ViewObject v1 = am.getDepartment1();
v1.setWhereClause("DEPARTMENT_ID=4"); // Pass Where Clause String as Method Parameter
v1.executeQuery();

This code snippet fetch the Row with Deprartment_id=4 and returns back to page. setWhereClause sets the Query's (SQL) Where Clause and doesn't take effect until executeQuery method of ViewObjectImpl is called

To reset Where Clause we have to set null value in method used

ViewObject v1 = am.getDepartment1();
v1.setWhereClause(null); // To Remove Where Clause
v1.executeQuery();


Thanks , Happy Learning :)

Monday 16 February 2015

Working with af:iterator and af:forEach programmatically (Add and delete records using List)

In previous post Working with af:iterator and af:forEach programmatically (Populate values using POJO from Managed Bean) we saw that how can we populate record from a List to af:iterator and af:forEach (ADF Faces Component)

So this post is about adding and deleting of records from List while List is presented using af:iterator.
here i am extending previous post and using same sample application



Added two fields and button on page to add records 


<af:panelFormLayout id="pfl1" rows="1">
                    <af:inputText label="Name" id="it1" binding="#{viewScope.PopulateIteratorBean.nameBind}"/>
                    <af:inputText label="Department" id="it2" binding="#{viewScope.PopulateIteratorBean.deptNameBind}"/>
                    <af:button text="Add" id="b1"
                               actionListener="#{viewScope.PopulateIteratorBean.addNewRecordAction}"/>
                </af:panelFormLayout>




and on this button action simply added both attributes to List and added partial trigger of button to af:iterator to refresh it


    // Component binding to access inputValue from page
    
    private RichInputText nameBind;
    private RichInputText deptNameBind;
    
    public void setNameBind(RichInputText nameBind) {
        this.nameBind = nameBind;
    }

    public RichInputText getNameBind() {
        return nameBind;
    }

    public void setDeptNameBind(RichInputText deptNameBind) {
        this.deptNameBind = deptNameBind;
    }

    public RichInputText getDeptNameBind() {
        return deptNameBind;
    }

    /**Method to add record in List and show on page using af:iterator and af:forEach
     * @param actionEvent
     */
    public void addNewRecordAction(ActionEvent actionEvent) {
        if (nameBind.getValue() != null && deptNameBind.getValue() != null) {
            EmployeeDet obj = new EmployeeDet(nameBind.getValue().toString(), deptNameBind.getValue().toString());
            employeeDetail.add(obj);
            
        }
    }


On page - add a new record (record added in List and appeared in iterator as well)


So it is quite simple to add records but deletion of record is a bit tricky but not difficult at all :)
Let's see this-
For deleting record i have added a delete link inside iterator so that it should appear for each record as you can see in snap (above)
Here question is that how to know that which record should be deleted  ?

So for this i have added a f:attribute tag to link , this attribute contains the value of current item of iterator



f:attribute derives it's value from var of af:iterator/af:forEach, this var represents each item of List
Now on delete button's action - get the current item and remove it from List


    /**Method to delete selected record
     * @param actionEvent
     */
    public void deleteRecordAction(ActionEvent actionEvent) {
        //Get value from f:attribute (current item)
       Object itemVal= actionEvent.getComponent().getAttributes().get("itemVal");
       //Remove selected item from List
       employeeDetail.remove(itemVal);
    }

After deleting records

Sample ADF Application- Download

Tuesday 10 February 2015

Working with af:iterator and af:forEach programmatically (Populate values using POJO from Managed Bean)


This is another post about Working programmatically with ADF (populating af:iterator and af:forEach programmatically )

Previously i have posted about populating af:iterator and af:forEach using ADF BC and binding layer to show master-detail relation
Implementing master/detail tree relation using af:Iterator and af:forEach for better UI designs - Oracle ADF

For this post i am populating employee name and it's department name using List datastructure ,to get and set value of attributes

Created a java bean class , it has 2 variable for both attributes




public class EmployeeDet {
    public EmployeeDet(String name, String deptName) {
        this.name = name;
        this.deptName = deptName;
    }
    //Attribute to display EmployeeName and Department Name
    private String name;
    private String deptName;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public String getDeptName() {
        return deptName;
    }
}

Next step is to create a managed bean to populate data in af:iterator and af:forEach , this managed bean makes use of
EmployeeDet 
java bean class to add data in same format for all items of iterator and forEach. A List data structure is used to pass all values to iterator. See code of managed bean 




    //Constructor-populate default records
    public PopulateIteratorBean() {

        EmployeeDet obj = new EmployeeDet("Ashish Awasthi", "Oracle ADF");
        employeeDetail.add(obj);
        obj = new EmployeeDet("Alex Smith", "Java");
        employeeDetail.add(obj);
        obj = new EmployeeDet("James S", "PHP");
        employeeDetail.add(obj);
    }
    //ArrayList to poplate data in af:iterator and af:forEach
    private List<EmployeeDet> employeeDetail = new ArrayList();

    public void setEmployeeDetail(List<EmployeeDet> employeeDetail) {
        this.employeeDetail = employeeDetail;
    }

    public List<EmployeeDet> getEmployeeDetail() {

        return employeeDetail;
    }

Now drop af:iterator on page and set it's properties like value, var etc


using var reference of iterator , set value in output text to show Employee Name and DepartmentName , see XML source of af:iterator


<af:panelGroupLayout id="pgl1" layout="horizontal">
                        <af:iterator id="i1" value="#{viewScope.PopulateIteratorBean.employeeDetail}" var="item">
                            <af:panelBox id="pb2" showDisclosure="false">
                                <f:facet name="toolbar"/>
                                <af:panelGroupLayout id="pgl3" layout="horizontal">
                                    <af:outputText value="#{item.name}" id="ot1"
                                                   inlineStyle="font-weight:bold; font-size:medium; color:#0572ce;;"/>
                                    <af:spacer width="2" height="0" id="s1"/>
                                    <af:outputText value="(#{item.deptName})" id="ot2"
                                                   inlineStyle="font-weight:bold;font-size:small;color:red;"/>
                                </af:panelGroupLayout>
                            </af:panelBox>
                        </af:iterator>
                    </af:panelGroupLayout>  

on running it looks like this-


do same for af:forEach


<af:panelGroupLayout id="pgl2" layout="horizontal">
                        <af:forEach items="#{viewScope.PopulateIteratorBean.employeeDetail}" var="feach">
                            <af:showDetailHeader text="#{feach.deptName}" disclosed="true" id="sdh1">
                                <af:outputText value="#{feach.name}" id="ot3"
                                               inlineStyle="font-weight:bold; font-size:medium; color:#0572ce;;"/>
                            </af:showDetailHeader>
                        </af:forEach>
                    </af:panelGroupLayout>

on running it looks like this-
 Sample ADF Application-Download
Thanks, Happy Learning :)

Monday 9 February 2015

Custom selection listener for af:listView, Invoke selectionListener programmatically

In the last post (Better UI for data collection using af:listView, Enable selection in ADF Faces List component ) about af:listView, we saw that how can we present data collection in a better way using af:listView and enable selection using EL (same as used for af:table)

Now in this post i will describe about defining custom selection listener for af:listView
Suppose you have to do some task on selection of an item in list other than making it current row, for this you have to override default selection listener and define own custom selection listener in managed bean
So next step is to define a method in managed bean for handling selection event of af:list view



  • Select af:listView, goto properties and click on edit menu of selectionListener property and create a method in managed bean



  • now see what we have to do in custom selection listener, first invoke default selection listener EL (#{bindings.Departments1.collectionModel.makeCurrent}) to make selected row as current and then get current row from iterator as selected row is now current row
    See the managed bean code -

  • //Import these packages
    
    import javax.el.ELContext;
    import javax.el.ExpressionFactory;
    import javax.el.MethodExpression;
    import javax.el.ValueExpression;
    
    import javax.faces.application.FacesMessage;
    import javax.faces.context.FacesContext;
    
    import oracle.jbo.Row;
    
    import org.apache.myfaces.trinidad.event.SelectionEvent;   
    
    
     /**
         * Programmatic invocation of a method that an EL evaluates to.
         *
         * @param el EL of the method to invoke
         * @param paramTypes Array of Class defining the types of the parameters
         * @param params Array of Object defining the values of the parametrs
         * @return Object that the method returns
         */
        public static Object invokeEL(String el, Class[] paramTypes, Object[] params) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ELContext elContext = facesContext.getELContext();
            ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
            MethodExpression exp = expressionFactory.createMethodExpression(elContext, el, Object.class, paramTypes);
    
            return exp.invoke(elContext, params);
        }
    
        /**
         * Programmatic evaluation of EL.
         *
         * @param el EL to evaluate
         * @return Result of the evaluation
         */
        public static Object evaluateEL(String el) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ELContext elContext = facesContext.getELContext();
            ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
            ValueExpression exp = expressionFactory.createValueExpression(elContext, el, Object.class);
    
            return exp.getValue(elContext);
        }
    
        /**Custome Selection Listener for af:listView
         * @param selectionEvent
         */
        public void listSelectionListener(SelectionEvent selectionEvent) {
            //invoke this EL to set selected row as current row, if it is not invoked then first row will be current row
            invokeEL("#{bindings.Departments1.collectionModel.makeCurrent}", new Class[] { SelectionEvent.class }, new Object[] {
                     selectionEvent });
            // get the selected row , by this you can get any attribute of that row
            Row selectedRow = (Row) evaluateEL("#{bindings.Departments1Iterator.currentRow}");
            FacesMessage msg = new FacesMessage(selectedRow.getAttribute("DepartmentName").toString());
            msg.setSeverity(FacesMessage.SEVERITY_INFO);
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    

  • Now run application and check

Download Sample ADF Application here
Thanks , Happy Learning :)

Wednesday 7 January 2015

Programmatically populate values in ADF Faces multiSelect component (af:selectManyCheckbox, af:selectManyChoice, af:selectManyListbox, af:selectManyShuttle)

ADF Faces provides some component to support multiple selection as af:selectManyListbox, af:selectManyCheckbox, af:selectManyChoice, af:selectManyShuttle
In this post we will see how to populate values in these component from managed bean using POJO
You can read my previous post on multiple selection that was about populating multiselect component using ADF BC and binding layer
Using Multiple Selection (selectManyListbox & selectManyCheckbox component) in ADF
Shuttle Component in Oracle ADF (Allow Multiple Selection)

See the step by step implementation-



  • Create a Fusion Web Application and a managed bean in viewController


  • Create a variable of type java.util.List in managed bean, and generate its accessors

  •     //List to show records in selectMany components
        List<SelectItem> allValuesList;
    
        public void setAllValuesList(List<SelectItem> allValuesList) {
            this.allValuesList = allValuesList;
        }
    
        public List<SelectItem> getAllValuesList() {
            return allValuesList;
        }
    

  • This list contains value of type javax.faces.model.SelectItem; that is supported by af:selectManyCheckbox, af:selectManyChoice, af:selectManyListbox compoent

  •     //List to show records in selectMany components
        List<SelectItem> allValuesList;
    
        public void setAllValuesList(List<SelectItem> allValuesList) {
            this.allValuesList = allValuesList;
        }
    
        public List<SelectItem> getAllValuesList() {
            if (allValuesList == null) {
                allValuesList = new ArrayList<SelectItem>();
                allValuesList.add(new SelectItem(1, "India"));
                allValuesList.add(new SelectItem(2, "Australia"));
                allValuesList.add(new SelectItem(3, "America"));
                allValuesList.add(new SelectItem(4, "United Kingdom"));
            }
            return allValuesList;
        }
    

  • See how to add this list reference to  af:selectManyCheckbox component, just drag n drop component on page


  • Set managed bean list reference to selectManyCheckbox component, records stored in this list will be populated in component


  • Suppose I have to show some record as selected by default on page load so for this requirement created another List in managed bean and added it to value property of selectManyCheckbox component
    Value property of component refers only selected records but selectItems component refers all records of component

  •     //List to show selected values in selectMany Component
        List selectedValues;
    
        public void setSelectedValues(List selectedValues) {
            this.selectedValues = selectedValues;
        }
    
        public List getSelectedValues() {
            if (selectedValues == null) {
                selectedValues = new ArrayList();
                selectedValues.add(1);
                selectedValues.add(3);
                System.out.println("List is-" + selectedValues);
            }
            return selectedValues;
        }
    

    See af:selectManyCheckbox source -

    <af:selectManyCheckbox id="smc1" value="#{viewScope.ProgSelectManyComp.selectedValues}">
                                        <f:selectItems value="#{viewScope.ProgSelectManyComp.allValuesList}" id="si1"/>
                                    </af:selectManyCheckbox>
    

  • Now run this application and see component on page


  • Following same steps i have three more component on page , all 3 adf faces component support multiple selection
    af:selectManyChoice-

    <af:selectManyChoice label="Label 1" id="smc2"
                                                         value="#{viewScope.ProgSelectManyComp.selectedValues}"
                                                         simple="true">
                                        <f:selectItems value="#{viewScope.ProgSelectManyComp.allValuesList}" id="si2"/>
                                    </af:selectManyChoice>
    


    af:selectManyListbox-

    <af:selectManyListbox label="Label 1" id="sml1"
                                                          value="#{viewScope.ProgSelectManyComp.selectedValues}"
                                                          simple="true">
                                        <f:selectItems value="#{viewScope.ProgSelectManyComp.allValuesList}" id="si3"/>
                                    </af:selectManyListbox>
    


    af:selectManyShuttle-

     <af:selectManyShuttle label="Label 1" id="sos1" simple="true"
                                                           value="#{viewScope.ProgSelectManyComp.selectedValues}"
                                                           contentStyle="width:50px;">
                                        <f:selectItems value="#{viewScope.ProgSelectManyComp.allValuesList}" id="si4"/>
                                    </af:selectManyShuttle>
    

  • All 4 components on page are populated using same List, this is just an example to show that all 4 components share same strucutre, run this application and see 


  • Thanks, Happy Learning :)
    Download- Sample ADF Application