Please disable your adblock and script blockers to view this page

Search this blog

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

Saturday, 1 August 2015

ADF Baiscs: Define and remove named bind variable in viewObject at runtime programmatically

This post is about creating named bind variable in viewObject at run time and filter viewObject using this bind variable in WHERE Clause of ViewObject programmatically .

Defining WHERE Clause and Bind Variable name and default value -

        //Get ViewObject
        ViewObject vo = iter.getDepartments();

        //Apply desired WHERE Clause and declare bind variable name
        vo.setWhereClause("DEPARTMENT_NAME=:BindDepartmentName");

        //Define this variable as ViewObject Bind Variable , You can also set default value for this
        vo.defineNamedWhereClauseParam("BindDepartmentName", "Purchase", null);

        // Execute ViewObject to finally apply where clause
        vo.executeQuery();




Setting value of Bind Variable-


        //Setting Value of Bind Variable
        vo.setNamedWhereClauseParam("BindDepartmentName", "Finance");
        vo.executeQuery();


Getting value of Bind Variable-


        //Get value of Bind Variable
        vo.getNamedWhereClauseParam("BindDepartmentName");


Removing WHERE Clause and Bind Variable after use-


        //Remove where clause
        vo.setWhereClause(null);
        //Remove Bind Variable
        vo.removeNamedWhereClauseParam("BindDepartmentName");
        vo.executeQuery();

Cheers :) Happy Learning

Saturday, 4 July 2015

ADF Basics: How to invoke model layer methods from managed bean (Best Practice to write business logic in ADF)

Again a post about ADF Basics for those who are starting with ADF
This topic is posted multiple times and one of the most asked question on OTN

How to access AM method in bean ?
How to pass parameters to model from managed bean (viewController) ?
How to pass taskFlow parameter to model ?

Or sometimes I have to tell user that you should not access ApplicationModule or not update model from managed bean and then i post a link about this
I often post a link of Frank's blog
Best practice invoking business services methods from JSF beans
It is well explained but still user not able to do because he/she doesn't know about clientInterface, pageDef etc

So i thought to write a step by step implementation of this and if you want to know why it is best to call method through binding layer ?
Then please refer Frank's blog :)

What i am going to explain is How to call a method defined in ApplicationModule Impl class in managed bean ?
So for this first i need to define a method in ApplicationModule Impl class




Here i am using Departments table of HR Schema and i have created a method to create new row in Departments viewObject
See implementation part -

  • To create AMImpl class--> Open ApplicationModule in editor--> Goto Java tab--> Click on edit (pencil) icon and check the checkbox to generate class



  • Now write your logic and create method here so i have created a method to create department record and this method takes a parameter i;e DepartmentId

  •     /**
         *Custom Method to create row in departments viewObject
         */
        public void createDepartmentRecord(Integer deptId) {
            ViewObject deptVo = this.getDepartmentsVO1();
            Row newRow=deptVo.createRow();
            newRow.setAttribute("DepartmentId", deptId);
            deptVo.insertRow(newRow);
        }
    

  • Next step is to add this method to client interface so that we can access this , Again open AM in editor -->Go to Java tab--> Click on edit icon of clientInterface--> Shuttle method to selected side


  • Now to add this method in pageDef , Open page in editor--> Click on Bindings tab (bottom of editor)--> Click on green plus icon of bindings section--> Select methodAction and click on ok



  • Now select method name here and click ok


    Now you can see this method is added in pageDef


  • Now time to call this method in managed bean so for that added a button in page and created actionListener in bean . See the code 

  •     /**Method to get Binding Container of page
         * @return
         */
        public BindingContainer getBindings(){
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**Calling method defined in AMImpl class to create new Department
         * @param actionEvent
         */
        public void callAMMethodToCreateDepartmentAction(ActionEvent actionEvent) {
            //Get OperationBinding of method
            OperationBinding ob=getBindings().getOperationBinding("createDepartmentRecord");
            //Passing parameter to method -Get parameter map and use paramater name as key
            ob.getParamsMap().put("deptId", 9999);
            //Execute this method
            ob.execute();
            //Check for errors
            if(ob.getErrors().isEmpty()){
                // Successfully Executed
            }
        }
    

  • Now run application and check , is it working ? ;)

On click a new row is inserted in table with DepartmentId 9999


All done :)
In same way you can call method defined in any model implementation class, remember don't access ApplicationModule or viewObject directly , make use binding layer
and again why it is best practice ?? to know this read Frank's blog :)

Cheers :) Happy Learning 

Saturday, 27 June 2015

ADF Basics: Using contentStyle and inlineStyle property to change basic styling of component in ADF Faces

Hello All,
Again a post about ADF Basics for beginners
I have seen lots of thread on OTN about changing basic styles of component . for example,

How to change font size of inputText ?
How to change color of inputText/outputText ?
How to change color of link or button ?

and everyone starts creating a css/skin for these minor changes but there is no need of that
Skin should be used for complex styles or you have apply same style to all components of your application

If you will read API docs then you will know this, See what docs says about inlineStyle property-

The CSS styles to use for this component. This is intended for basic style changes; you should use the skinning mechanism if you require any complex style changes. The inlineStyle is a set of CSS styles that are applied to the root DOM element of the component. Be aware that because of browser CSS precedence rules, CSS rendered on a DOM element takes precedence over external stylesheets like the skin file. Therefore skins will not be able to override what you set on this attribute.



Difference between contentStyle and inlineStyle -


contentStyle property used to style content part of component like if you want to change color of inputText or any other input component then you have to specify this in contentStyle property of that component

inlineStyle is about whole component and also available in output (outputText) or collection (table, tree etc) component's property where contentStyle is not there. This can be use to set width, height ,border or color of output components etc.

So this is enough about theory , no one likes theory ;) , Everyone is looking for some code that is ready to use
Let's see some practical usage of both properties -

Change font, color, size(width), padding of input components (af:inputText, af:inputDate, af:selectOneChoice etc)-


Used this in contentStyle property of components
width:150px;color:white;font-weight:bold;font-size:small;background-color:red;padding:5px;
and check the output


you can also change input text to uppercase , lowercase, Initcap using contentStyle property, just use any of this -
text-transform:uppercase; // To change in uppercase
text-transform:lowercase; //To change in lowercase
text-transform:capitalize; //To change in initcap

Change properties of output components , color of link/button -

Output components doesn't have contentStyle property as there is not content part in component , here we make use of inlineStyle property
See what happens on applying same style in outputText and link using inlineStyle


It looks good :) , but same style doesn't work for button because button has multiple root element (we can only change width, color of text and font of button but background color and other styling can not be changed using inlineStyle property)
For more detail about button skinning check - Customize af:button (font, shape, size, color etc) using skinning -Oracle ADF (12.1.3)

Change data collection components (af:table, af:treeTable,etc) height, width -


just write in inlineStyle property like this
width:600px;height:200px;background-color:lightyellow;color:red;
background color will be applied on empty area of table and color will be applicable on column header and EmptyText
Remember to set table's height using inlineStyle ensure that autoHeightRows should be set to -1


In same way we can change color of columns too, see i have used different background colors (set background-color:colorName; in inlineStyle of af:column) for columns and it looks like this


Now it's your turn , try more combination on different components. you can do a lot using contentStyle and inlineStyle property. Remember all these changes can be done using skin also but if have some minor changes then why use skin , when framework provides these wonderful properties

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

Thursday, 19 March 2015

ADF Basics: Disable user input in af:inputListOfValues

Sometimes we need to disable user input in input Lov as there is requirement of selecting value only from Lov popup

By default af:inputListOfValues provides feature to select value from popup or type a value as input


To disable user input there is a property -EditMode
From Oracle Docs-



editMode String Yes Valid Values: input, select

the mode that controls how the user specifies a value. This attribute is only applicable when the 'readOnly' attribute is set to false.
  • input: this mode allows the user to type in a value as well as browse and select from a list of available values.
  • select: this mode allows the user only to browse and select from a list of available values.


Set it's value to select
Happy Learning , Thanks :)

Tuesday, 3 February 2015

ADF Basics: Set multiple LOV's on attribute and conditionally switch using LOV Switcher

This post is about a very basic and common use case
Suppose we have to show different values in our List depending on some condition but all values must be stored in same attribute so for this type of requirement ADF BC framework provides concept of LOV Switcher
Framework allows us to define multiple LOV on same attribute, I hope you all know about defining LOV(List of Values) so move ahead and see how to use lov switcher

 See the implementation part-
  • Created a Fusion Web Application and a viewObject to show LOV on viewport (Used dual to create view object for this example , you can use use your own)





  • Created 2 more viewObject to apply LOV on first viewObject's attribute, One ViewObject is for Departments and other one is for Employees


  • Open dual viewObject select LovAppl attribute and goto ListOfValues tab and add both LOV
    For Department - DepartmentId is List Attribute and DepartmentName will be shown on UI


  • For Employees- EmployeeId is List Attribute and FirstName,LastName will be shown on UI



  • Now click on green plus icon of List Of Values Switcher and add a transient attribute , this will be further used to switch lov on base of some condition


  • So created LovSwitcher attribute , and remember this switcher attribute value should be one of the LOV Name that are applied on attribute.
    Here i am using a condition - if LovType attribute of Dual viewObject is 'D' the LovAppl should show Departments Lov and if it is 'E' then LovAppl should show Employees Lov
    For this i have written expression for lov switcher attribute
    LovType=='D' ? 'LOV_LovAppl' : LovType=='E' ? 'LOV_LovAppl1' : null


  • Now run Application Module and check it


Thanks , Happy Learning :)

Monday, 5 January 2015

ADF Basics: Delete child records on delete of parent record, Overriding remove() in EntityObject class

This post is about one basic question of Master-Detail relation between business components
How to delete all child records on delete of parent record ?
So answer is quite simple , see the steps how to achieve this?

  • Create a Fusion Web Application and prepare model project using Departments and Employees table of HRSchema.
    you can see multiple associations and viewLinks are created automatically due to foreign key relation in database


  • Here Departments is parent table and Employees is child, so there is an association between both entity objects , open this association and goto Association Properties . Now you can see source and destination accessor name that are created in both entity objects




  • Next step is to create EntityObject java class. To do this open Departments entity object -- go to java section-- click on edit icon and check the box to create class and required methods
    See Accessors and Remove Method will be created in this class


  • Open DepartmentsEOImpl class and check there is a method that returns RowIterator of Employees (this is Accessor)

  •     /**
         * @return the associated entity oracle.jbo.RowIterator.
         */
        public RowIterator getEmployeesEO1() {
            return (RowIterator)getAttributeInternal(EMPLOYEESEO1);
        }
    

  • Now locate remove method in EOImpl, this method is called every time when delete operation for Departments is executed so add this code to remove(); method

  •     /**
         * Add entity remove logic in this method.
         */
        public void remove() {
            //Get all Employees of currenlty selected Department
            RowIterator employees = getEmployeesEO1();
            while (employees.hasNext()) {
                //Delete all Employees
                employees.next().remove();
            }
            //Delete Department itself after deleting all Employees associated with it
            super.remove();
        }
    


This is how we can make use EntityObject class and Association accessors, in the same way other operation can be performed as updating all child rows, sum of a column of child records etc
Thnaks , Happy Learning :)

Wednesday, 10 September 2014

Dynamic (parameterize) model level validation using message token -Oracle ADF

Hello all
This post falls under ADF Basics category (about a little trick in model layer) but about a common development requirement
How can we create dynamic ADF BC validation ? means it takes a parameter at run time and append it to validation message

Read previous post on model level validation-
Conditional Execution of Model (EO) level Validation- Oracle ADF
ViewObject Validation rules for transient attributes (Model level validation in ADF)

In this post I am using Departments table of oracle HR Schema



  • First step is same , prepare model (EO,VO and AM) using Departments table



  • Creating a business rule that DepartmentName can not be duplicate, for this created a alternate key in EntityObject 



  • Nnow creating unique key business rule for this alternate key and message that appears on validation failure (this is how we apply EO level validations)




  • Run AM and check in BC4J tester, create a new row and on entering duplicate DepartmentName this validation message appears -"Duplicate Department Name"


  • now my requirement is this message should be like - Duplicate Department Name <Administration> , so for this i have to pass parameter in message that shows entered DepartmentName on run-time. ADF provides built in feature to pass tokens in message and on run time it is replace with groovy expression value

  •  On running see desired output



  • to pass more than one parameter just add another token and set groovy for it, see the screens
 Output-


Thanks - Happy Learning :)

Wednesday, 13 August 2014

Use View Link Accessor to call aggregate functions, set attribute value , set bind variables value (Oracle ADF)


Hello All

This post is about various usage of view link accessor  , when we create viewLink between two viewObjects , destination accessor is created by default in master viewObject, there is check box to create source accessor also at same time

We can use this view link accessor for calculating attribute's sum, setting value of attributes etc



here Departments is master viewObject and Employees is it's detail, after creating viewLink you can see in viewObject xml source there accessor is present

In Departments ViewObject- 




<ViewLinkAccessor
    Name="Employees"
    ViewLink="sample.model.view.link.DeptTOEmpVL"
    Type="oracle.jbo.RowIterator"
    IsUpdateable="false"/>

In EmployeesViewObject- 
 

<ViewLinkAccessor
    Name="Departments"
    ViewLink="sample.model.view.link.DeptTOEmpVL"
    Type="oracle.jbo.Row"
    Reversed="true"
    IsUpdateable="false"/>

So what is the use of these view link accessors ?
Master accessor in detail viewObject returns current Row of master viewObject, when you generate RowImpl class for detail viewObject , it also has a method for this accessor


    /**
     * Gets the associated <code>Row</code> using master-detail link Departments.
     */
    public Row getDepartments() {
        return (Row) getAttributeInternal(DEPARTMENTS);
    }

    /**
     * Sets the master-detail link Departments between this object and <code>value</code>.
     */
    public void setDepartments(Row value) {
        setAttributeInternal(DEPARTMENTS, value);
    }

Detail accessor in master viewObject returns a row set of all row of details viewObject that are currently referenced by master record

    /**
     * Gets the associated <code>RowIterator</code> using master-detail link Employees.
     */
    public RowIterator getEmployees() {
        return (RowIterator) getAttributeInternal(EMPLOYEES);
    }

Now see what we can do with viewLink Accessor

1. Get master attribute value in detail viewObject

suppose i have to get a attribute's value from Master viewObject (Departments) in a attribute of detail viewObject (Employee)
in this example i am getting managerId from Departments ViewObject so for this just write in expression of Employee's ManagerId field
viewLinkAccesorName.AttributeName


now run BC4J tester and check - create new record in Employee and see managerId from Departments is auto populated

 on creating new record-


2. Call aggregate function to calculate sum of an attribute of detail viewObject

suppose now i have to calculate total salary of a Department (sum of Employees salary of that department)
for this purpose just call sum function to calculate sum of all rows of detail RowSet 
take a transient attribute in Departments ViewObject and write in it's expression
viewLinkAccesorName.sum("AttributeName")


 Run ApplicationModule and see-


3. Set bind variable value as per master viewObject's attribute (pass value from master viewObject)

This  is tricky part as we can not set bind variable value through expression as it doesn't recognize view link accessor name.
created a viewCriteria and bind variable for managerId in Employee viewObject




applied this criteria to Employees viewObject instance in Application Module (Just Shuttle criteria to selected side)


now to set bind variable's value we have to override prepareRowSetForQuery method in Employees VOImpl class

this method gets the value of managerId from currentRow of master ViewObject (Departments)and sets in bind variable of Employees viewObject


    @Override
    public void prepareRowSetForQuery(ViewRowSetImpl viewRowSetImpl) {
        RowSetIterator[] masterRows = viewRowSetImpl.getMasterRowSetIterators();
        if (masterRows != null && masterRows.length > 0 && masterRows[0].getCurrentRow() != null &&
            masterRows[0].getCurrentRow().getAttribute("ManagerId") != null) {
            Integer managerId = (Integer) masterRows[0].getCurrentRow().getAttribute("ManagerId");
            viewRowSetImpl.ensureVariableManager().setVariableValue("BindManagerId", managerId);
            System.out.println("ManagerID in bind Var-" + managerId);

        }
        super.prepareRowSetForQuery(viewRowSetImpl);
    }

now run AM and check it-

Happy Learning :)

Sunday, 8 June 2014

ADF Basics: Using CSS to change appearance of application (Skins and Styles in ADF Faces)

Hello All
This is a basic post about using CSS in ADF applications, how can you change appearance of ADF application using Skins (.css file)
See the steps to create and apply css in your ADF applications
  • Create a Fusion Web Application and create a page
  • Add Some ADF Faces component (input text,button,panel box, panel collection etc)
  • Now to change appearance of default ADF Faces components , create an ADF Skin
  •  Right click on ViewController--->New--->Web Tier--->JSF/Facelets--->ADF Skin 


  • By default ADF Skin name is like skin1,2 etc



  • After creating ADF Faces skin open it and, on left you will see all components as Button, Layouts, Output text and so on. this is ADF Skin Editor


  • Now expand the components that you want to change , change it's color(on active, focus , hover etc) and other properties. See in image below


  • After creating your ADF Skin ,open trinidad-config.xml file in Jdeveloper editor and your will see like this

  • <skin-family>skin1</skin-family>
    
    This means that skin1 is applied on Application

  • now if you another ADF Skin file- skin2 then in trinidad-config.xml, it will be changed to

  • <skin-family>skin2</skin-family>
    

  • ADF automatically choose the most recent skin, so here this is done , now create and configure your ADF Skin and customize appearance of application
  • For more details see Oracle Docs- http://docs.oracle.com/cd/E16764_01/web.1111/b31973/af_skin.htm
Cheers :-) Happy Learning