Thursday, June 21, 2012

ADF Dynamic Region | Working with Oracle ADF Dynamic Regions

ADF Region is used to render a bounded taskflow in a JSF page . The primary use of ADF Region is u can put  various pieces of application functionality in a bounded task flow. A single JSF page can contain many taskflows added as regions and each region may contain different content.


The sections pointed with arrows are different taskflows added as as a regions in a single JSF Page.The Taskflow which is added as ADF Region must contain at least one view activity.

Difference between ADF Region and Dynamic Region ?

Region added in a JSF Page can be invoked based on some action like button click or link that renders specific taskflow in which the region formed . various regions can also be displayed as a stand by at a time when the page loads.In Dynamic Region you do not need to drag and drop the required regions on to the JSF page instead your taskflows will be identified by using the taskflow ID on some action. The task flow binding dynamically determines the values of its ID at run time . In the above picture i have dragged and dropped four taskflows as a region in a JSF Page . But Dynamic Region simplifies this and allows us to swap between taskflows using Dynamic Region link where it store the task flow id in a managed bean and render the pages based on the task flow ID it gets at runtime .

Hope this gives you the basic idea on the concept and we will move ahead for creating one .

Download sample application with this post 

we are not going to alter our Model project as we will use the existing VOs which we created in earlier posts .Those who want to continue with the workspace that contains all model components can download from here AdfDemoApps.

Create two taskflows :
AdfDemoApps\AdfDemoUi\public_html\WEB-INF\TaskFlows\CountriesFlow.xml,
AdfDemoApps\AdfDemoUi\public_html\WEB-INF\TaskFlows\EmployeesFlow.xml

Create two page fragments :
AdfDemoApps\AdfDemoUi\public_html\pages\CountriesRegionPage.jsff
AdfDemoApps\AdfDemoUi\public_html\pages\EmpRegionPage.jsff


Drag & drop the CountriesRegionPage.jsff in CountriesFlow.xml and  EmpRegionPage.jsff in EmployeesFlow.xml.We need a jsp page to run these taskflows. Create a JSF Page DynamicRegionMain.jspx under AdfDemoApps\AdfDemoUi\public_html\pages. In the Create JSF Page dialog under Initial Page Layout and Content section i have selected Oracle Three Column Layout for the rich look and to split the user screen into two so that we can have action links at one side and actual pages at other side.

Now Drag and drop the EmployeesFlow.xml into the DyamicRegionMain.jspx we just created and select Dynamic Region. In the Next step it will ask you to specify Managed Bean . Click Add symbol  and create one .  Bean name is DynamicRegionBean under package bean and click ok. you can also create managed bean separately and  choose from the drop down. click ok in the Edit Task Flow Binding dialog.





The next two steps are important

Drag and drop the EmployeesFlow.xml  in the left panel of the page and choose Dynamic Region Link > dynamicRegion1.
Drag and drop the CountriesFlow.xml  in the left panel of the page and choose Dynamic Region Link > dynamicRegion1.
As we already have one Dynamic Region we are appending our taskflows to the same region link .

When you drop a taskflow onto a JSF page to create an ADF dynamic region , JDeveloper adds an af:region tag to the page . This tag contains a reference to a task flow binding


<f:facet name="center">
            <af:region value="#{bindings.dynamicRegion1.regionModel}" id="r1"
                       partialTriggers="::cl1 ::cl2"/>
 </f:facet>



An ADF dynamic region link swaps the taskflows within an ADF dynamic region . Look at the below code snippet in the DynamicRegionBean. java
 
Jspx :

     <af:commandLink text="EmployeesFlow"
                              action="#{viewScope.DynamicRegionBean.employeesFlow}"
                              id="cl1"/>
              <af:spacer width="10" height="10" id="s1"/>
      <af:commandLink text="CountriesFlow"
                              action="#{viewScope.DynamicRegionBean.countriesFlow}"
                              id="cl2"/>
Bean :

    private String taskFlowId =
        "/WEB-INF/TaskFlows/EmployeesFlow.xml#EmployeesFlow";

    public DynamicRegionBean() {

        super();

    }

    public TaskFlowId getDynamicTaskFlowId() {

        return TaskFlowId.parse(taskFlowId);
    }

    public String employeesFlow() {

        taskFlowId = "/WEB-INF/TaskFlows/EmployeesFlow.xml#EmployeesFlow";
        return null;
    }

    public String countriesFlow() {

        taskFlowId = "/WEB-INF/TaskFlows/CountriesFlow.xml#CountriesFlow";
        return null;
    }

The Managed bean stores the value of the task flow ID that displays inside the dynamic region
when a user click on any link its corresponding method will be called and thus taskFlowId will be changed and corresponding page will be rendered.

Note :
you can add an ADF Dynamic Region Link if you already have at least one ADF Dynamic Region on a page. a menu displays all of the dynamic regions currently on the page

Save All .  Right Click on DynamicRegionMain.jspx and choose Run . The Output

 

Wednesday, June 20, 2012

Creating a Master-Detail Relationship Using Oracle ADF

Master Detail Relationships using Oracle ADF allows you to view data from related tables at same time. we often face a situation in Software Development where we need to display some rows based on a row data from some other table . To put it more simple ,  in a page you have the first table that holds countries information and a table below to it contains the locations information . when you click on a row in countries table then automatically all the locations pertaining to the country should display. There are various ways in various J2EE frameworks provides this functionality. what is so special about ADF in giving this functionality.Yes, it is . ADF Model along with View Controller does many things for you .  Lets see how this works

Pre-requisites:

HR Schema in Oracle database with tables

For those who are new to ADF can go through this link Oracle ADF Model Sample Application download and can find a sample application to start with this post or else can simply download the complete application Oracle ADF Master-Detail Relationship Sample Application.

ADF Model project holds all the View Objects and View Links, and ADF View Controller project holds all the UI Pages like jsff, jspx etc ..

Right Click on mode.entity package under AdfDemoModel and create two entity objects

CountriesEO
LocationsEO

Right Click on mode.viewpackage under AdfDemoModel and create two view objects

CountriesVO
LocationsVO

Note : (when you create EO and VO for Locations table, Association LocCIdFkAssoc, ViewLink LocCIdFkLink will be created by ADF for you)  But why a View link is needed ? Look at the picture





ViewLink is a join condition between two view objects. Read ADF View Link. Now go back to your ADF Application Module AppModule and see the Data Models section

 
 LocationsVO via LocCIdFkLink has come under CountriesVO automatically . This means LOCATIONS table in the Database already has a foreign key reference to the COUNTRIES table and when we try to create a LocationsVO , ADF understood the relation and created a View Link for us . So based on this relationship, Locations Information can be retrieved based on the country id with the use of View Link . we will see this later how did this happen in UI part.

Open model.applicationmodule >> AppModule >> Data Model

Shuttle CountriesVO to the right side.
Being CountiesVO1 selected at right side, shuttle LocationsVO via LocCIdFkLink to the right side
Now shuttle the CountriesVO to the right side in the AM .



 Save All.
 You can test it using  Business component Browser which is useful to check the business logic and relation in your Application without creating any User Interface,Right  click on AppModule and choose Run 

 ..












                             All to set start with building UI Components ..what we need to have in the UI Project.
Right Click on Web Content > > AdfDemoUi From New Gallery , select JSF from categories section which is in the left side and select ADF Task Flow in the right side and click OK


MasteDetailFlow.xml being opened in the editor, drag and drop  View component from Components Palette on to the MasteDetailFlow.xml diagram . Change the name from view1 to MasterDetailView. Double click on view and enter the filename and path as such in the screen shot













Drag Panel Stretch Layout from Layout under Component Palette on to the jsff page we just created. Now Drag LocationsVO1 under CountriesVO1 and drop on to the jsff page and select ADF Master Table ,  Detail Table.
Save All..









     In Order to run this , we need to have jspx page . we cannot able to run jsff pages bcoz it is not a runnable target for ADF Controller. so I created a jspx page called MasteDetailMain.jspx under pages package,drag & drop the MasterDetailFlow.xml on to the jspx page as a Region . Save All . Now Right Click on the page and Run











Click on any country in the countries table to get its  locations only in the locations table.Later you can customize your page to look rich like labeling with proper header names, surrounding with table borders and many more . 

Logical Questions : 

How did the Detail table rendered based on the Master Data or How Master-Detail Table Relationships works in ADF ?

The  Parent tag of the detail component automatically has the partialtriggers attribute set to the id of the master component . At Runtime the partial trigger attribute  causes only the detail component tobe rendered when the user makes a selection  in the master component . In our MasterDetailView.jsff source

<af:table partialTriggers="::md1"
                    rows="#{bindings.LocationsVO1.rangeSize}"
                    fetchSize="#{bindings.LocationsVO1.rangeSize}"
                    emptyText="#{bindings.LocationsVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
                    var="row" value="#{bindings.LocationsVO1.collectionModel}"
                    rowBandingInterval="0"
                    selectedRowKeys="#{bindings.LocationsVO1.collectionModel.selectedRow}"
                    selectionListener="#{bindings.LocationsVO1.collectionModel.makeCurrent}"
                    rowSelection="single"
                    binding="#{backingBeanScope.backing_pages_MasterDetailView.t1}"
                    id="t1" inlineStyle="width:500.0px;">




where md1 is the ID of parent table , so whenever user makes a selection in the master table will also cause the detail table to change which is called partial rendering 

what if i want to have ADF Master - Detail on separate pages ?

Create two jsff pages . One page contains master table and another contains child table . Create a button in the master table which navigates to the child page on the button click and Vice Versa. You may wonder how do we get the Child records based on a row selected in the master table which is in diff page. Yes ADF does automatically based on the partial triggers set . You do not need to set any variable or attribute in some scope to retrieve information.