Professional Documents
Culture Documents
Oracle Application Framework Training Material
Oracle Application Framework Training Material
All pages within EBS are almost similar in look and feel. Based on this
fact, below is some common functionality which is already provided by
this framework so that we can mainly concentrate on implementing
business logic:
Inbuilt support for Apps specific features like flex fields, menus
etc..
main thing here is that OAF allows somewhat skilled functional user
to apply these changes.
Since OAF is used only for creating EBS pages, copyright links
and global links are provided by this framework by default.
Nodes can have parents and children, and multiple nodes together
form a tree-like structure used to represent a pages logical
structure.For example, left part below figure shows a logical hierarchy
of UI nodes and right part shows the same hierarchy rendered as an
HTML page.
Now in UIX, there is a java class for each UI nodes. These classes
implement the UINode interface in the oracle.cabo.ui package. The
UINode interface contains methods for the characteristics of nodes,
such as:
public int getIndexedChildCount(RenderingContext context);
public UINode getIndexedChild(RenderingContext context, int
childIndex);
public Enumeration getAttributeNames(RenderingContext context);
public Object getAttributeValue(RenderingContext context,
AttributeKey attrKey);
About Model
is
implemented
using
Oracle
Business
About View
About Controller
3. OA Framework Essentials
Key JSP Application Components
1)
The Browser communicates with the middle tier using HTTP which involves
sending a request message to which the middle tier replies with a response
message.
2)
A JSP is a file with some HTML and JAVA code that executes top to bottom.
At runtime, it is compiled into a Java class which is actually a Servlet.
3)
A Servlet is a Java web based application server extension program that
implements a Standard API.
4)
A Servlet Session is a mechanism for maintaining state between HTTP
requests during a period of continuous interaction between Browser and Web
Application. A Session may be initiated at any time by the application and
terminated by the application, by the user closing the browser, or by a period
of inactivity.
A session usually corresponds to an application login/logout cycle.
5)
A JavaBean (Bean for short) is simply a reusable component that
implements specific design patterns to make it easy for programmers and
development tools to discover the objects properties and behavior.
6)
Any objects in the middle tier that communicate with the database use a
JDBC (Java DataBase Connectivity).
Diagram to understand the above points
4. Implement the MODEL in OAF
This chapter describes how to implement your model objects in generic
terms.
Business Components Packages
All BC4J (Business components for Java) model components must belong to a
Business Components Package.
Business logic/data handling (Model) is done using BC4J.
The below objects are BC4J Objects.
1) Entity Object
Entity Objects encapsulate business logic and DML operations for application
tables.
i) EmployeeEO.xml
ii) EmployeeEOImpl.java
2) View Objects
3) .xml file
objects.
object.
Example: A purchase order header is automatically locked even if you make
changes only to its lines. Child is deleted when parent is deleted.
Reference: - The source entity object simply references the destination
object.
Example: A purchase order header references a supplier, but the supplier
can still exist regardless of whether a purchase order references it or not.
4) Application Modules
o
o
o
OAF Key Do's and Don'ts (Part 1) - "Top 10" Golden Rules
I don't know how many of you have come across this in the OAF Devguide, it
was only by change that I found it, thought I'd share:
There's a lot to learn when getting started with the OA Framework, but the
following list of rules are so universal -- and so fundamental -- they should
be familiar to anyone who's doing Framework development.
1) ALWAYS try to declaratively define your UI. Resort to a programmatic
layout only if the UI cannot be implemented declaratively. Programmatic
layouts are difficult to customize (they don't leverage the Personalization
Framework) and may diverge from the UI Guidelines over time.
2) NEVER change your UI layout properties in processFormRequest().
ALWAYS make changes in processRequest(), even if that means handling an
event in processFormRequest() and then redirecting back to the same page.
This ensures that the web bean hierarchy is in a stable state when the page
renders.
3) NEVER use index numbers to find beans when you want to change their
properties. ALWAYS search by name. Index numbers can change during
processing.
4) NEVER change the properties of a parent bean from a child bean. This is a
poor design practice that hampers reuse while introducing fragile code
(particularly if the child code executes too late in the page rendering cycle to
properly affect the parent).
5) NEVER instantiate Beans using "new OA Bean()". ALWAYS use the
createWebBean() factory methods available on the OAControllerImpl class.
Not all Bean properties are initialized correctly when you use "new."
6) NEVER create Form Beans in code (this means NEVER add nested Form
beans to a page; your Page Layout region should be the only form region).
Multiple form Beans on a page are not supported and can result in strange
runtime behaviors.
7) NEVER count on your Application Module using the same database
connection in subsequent requests. For example, NEVER post and commit in
separate requests. For performance reasons, the Framework will start pooling
and reusing connections in 5.7 instead of holding onto a single connection
throughout the life of an Application Module.
8) NEVER use JDBC directly unless you're calling a PL/SQL routine (you
should use a view object instead, and if possible, the view object should be
defined declaratively and not programmatically).
9) NEVER add member variables UNLESS THEY ARE TRANSIENT OR FINAL to
view objects, Controllers, entity object, view rows and Application Modules.
10) ALWAYS adhere to the Self-Service Performance Guidelines
8.
Create Simple OAF WELCOME Page
Step 1: Open JDeveloper tool, Create New OAworkspace.
Navigation: - right click on Workspaces option in system-navigator Window
and select New OAWorkspace
Step 2: i) Enter workspace name in file name column as
XXXOAWorkspace.jws, and press OK button.
ii) Press Next button
iii) Enter project Name in file name column as XXXOAProject.jpr
iv) Enter Default package name as
xxx.oracle.apps.ak.welcome.webui and press Next button twice.
We can see the package structure (train.oracle.apps.ak.welcome.webui) in
myprojects folder. The package structure is used to place EO, VO, AM and
Pages.
Step 3: Enter .dbc file location in DBC File Name column
[Location:
E:\p4045639_11i_GENERIC\jdevhome\jdev\myhtml\OA_HTML\Secur
e\ xxxxx.dbc]
Note: If you do not have .dbc file, then import the .dbc file from server
($ cd %APPL_TOP/fnd/11.5.0/secure/.dbc) and place in above path in your
local system.
Enter User Name: operations5 (oracle application user name)
Enter Password : xxxxxxxxx
Application Short Name: AK
Responsibility Key
: FWK_TBX_TUTORIAL
Press Finish button.
Now, creation of OAWorkspace, OAProject and front-end connections
successfully completed.
Value
MainRN
PageLayout
Welcome Window
Welcome Page
oracle.apps.fnd.framework.server.OAApplicationModule
Note: we are not yet creating Application Module. So,
this
application module is using which is default.
Property Name
ID
Region Style
Value
SubRN
Messagecomponentlayout
Property Name
ID
Region Style
Prompt
Additional Text
Value
WelcomeTxt
messageTextInput
Enter Your Name
Enter any string to display it
on the page
(It is like Tooltip text)
Value
ButtonLayout
Value
Go
submitButton
Go
Click the button
Logic to display the message Welcome <value of text item> on OAF page.
Add below code in the method processFormRequest.
Code:
if (pageContext.getParameter("Go")!=null)
{
String str=pageContext.getParameter("WelcomeTxt");
String message="Welcome "+str;
throw new OAException(message,OAException.INFORMATION);
}
In above code, Go is button name (not prompt) which is used in if
condition. WelcomeTxt is also text item id (not prompt).
When user press the Go button, the browser will send the request to
middle tier and after processing the middle tier responds to browser.
The OAException class is used to display the message on the OAF page. The
second parameter is exception type INFORMATION.
There
1)
2)
3)
4)
Note: The exception types ERROR and SEVERE terminate the program.
The exception types INFORMATION, CONFIRMATION and
WARNING are
continue the execution of the program.
Now, run the page WelcomePG.xml and see output like below.
Output: Enter the text OAF students in text item and press the Go
button, then display the message on MainRN (Root region).
Message: WELCOME OAF students
(Exception type: INFORMATION)
Product Branding:
The productBranding is used to place image beside corporate branding
image ORACLE.
Select pageLayout components and click right mouse button, and select the
productBranding option.
Set the below properties for productBranding item
Property Name
Value
ID
Item1 (as you like)
Item Style
Image
ImageURI
/OA_MEDIA/FNDTAPPBRAND.gif
Additional Text
Click the button
Set the system profile FND: Branding Size as Medium at site level.
If you change menus or profile values etc, then we have to terminate the
OAF page.
Navigation: RUN->Terminate->Embedded OC4J Server (Menu bar)
Compile and run the OAF page (.xml), check the output from below
screenshot.
In above screenshot, Tutorial Application image is productBranding image.
In-Context Branding:
The in-context branding includes corporate branding and product branding
images. Additionally, contextual information renders below corporate and
product branding images.
Select pageLayout Components region and click right mouse button, then
select the InContextBranding option.
Value
Item2 (as you like)
formattedText
Customer SUN MicroSystems-Menlo
Park
We can use html tags to change font styles or display font in bold etc.
Example: Customer <b> SUN MicroSystems-Menlo Park</b>
Output:
How do display default string in Text Item when page is
rendered
Code:
OAMessageTextInputBean fieldHelloTxt=
(OAMessageTextInputBean)webBean.findChildRecursive(WelcomeTxt);
fieldHelloTxt.setText(pageContext, welcome to OAF students);
Where WelcomeTxt is a Text Item ID. Write above code in processRequest
method of CONTROLLER.
Important Note:
We have to import the class OAMessageTextInputBean.
import oracle.apps.fnd.framework.webui.beans.message.
OAMessageTextInputBean;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
How do hide Text item at runtime
Code:
The Method setRendered is used to hide the text item. Pass the value
false for this method.
import oracle.apps.fnd.framework.webui.beans.message.
OAMessageTextInpuBean;
import oracle.apps.fnd.framework.webui.beans.OAWebBean;
OAMessageTextInputBean hellotxt=
(OAMessageTextInputBean)webBean.findChildRecursive(WelcomeTxt);
Hellotxt.setRendered(false);
Write above code in processRequest Method or processFormRequest of
CONTROLLER according to condition.
Like setRendered method, there are so many methods are available in text
item Bean.
The method setReadonly (true) is used to convert the item to read-only.
How do disable the button at runtime
Code:
We have to use OASubmitButtonBean to change behavior of buttons at
runtime.
import oracle.apps.fnd.framework.webui.beans.form.OASubmitButtonBean;
OASubmitButtonBean goButton =
(OASubmitButtonBean)webBean.findChildRecursive("Go");
goButton.setDisabled(true);
How do display message in different colour problem
Code:
We can do it by using rawText style (Item property under MainRN).
In Text property, we can use html tags. (Display message in red color)
<b><i><font color="red"> Hello World Page</font></i></b>
Dynamically, display the rawText by using OARawTextBean
OARawTextBean rawtxt =
(OARawTextBean)webBean.findChildRecursive("item3");
rawtxt.setText("Inventory Details are Transferred");
rawtxt.setText ("<b><i><font color= red> Inventory Details are
Transferred</font></i></b>");
Display the message in red color. See below screenshot.
How do call the specified page from another page
I have two pages. One page is security page, if user enters the login details
correct then open the other specific page.
Solution:
The API pageContext.SetForwardURL is used to open the other specific
page.
Design the security page with two text items and one button like below
screen shot.
(Note: This is not related to database. Just check the user name and
password with static text like username=Venky and password=Venky)
Code:
(Write in Controller processFormRequest Method)
if (uname.equals("Venky")&&pwd.equals("Venky"))
{
pageContext.setForwardURL("OA.jsp?
page=/train/oracle/apps/ak/welcome/webui/WelcomePG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
true,
OWebBeanConstants.ADD_BREAD_CRUMB_YES,
OAWebBeanConstants.IGNORE_MESSAGES);
}
Enter user name and password correct, and then press Go button.
Note: Set text item property secret as True when enter password.
User could not see the password while entering.
The below page WelcomePG will be opened.
How do display the Return Navigation link on the page
Suppose, if user call second page from first page and perform some actions
on the second page. Later, the user wants to go back to first page, then we
have to use Return Navigation link.
Select the region pageLayoutRN and click right mouse button, and then
select the option returnNavigation.
Set the properties for returnNavigation item.
Value
Property
Name
returnLink
ID
link
Item
Style
OA.jsp?
Destinati page=/train/oracle/apps/ak/security/webui/SecurityPG&retainAM=Y
on URI
Text Return to Security Page
Output for returnNavigation link (Return to Security Page):See the below screenshot.
When user presses the Return to Security Page link, then the security
page will be opened.
How do add a returnLink dynamically
Code:processRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processRequest(pageContext, webBean);
OALinkBean returnLink =
(OALinkBean)createWebBean(pageContext,
OAWebBeanConstants.LINK_BEAN, null,"returnLink");
returnLink.setDestination("OA.jsp?
page=/oracle/apps/dem/employee/webui/EmpSearchPG&retainAM=Y");
// Retrieve and set the translated link text.
String linkText =
pageContext.getMessage("AK","FWK_TBX_T_RETURN_TO_POS", null);
returnLink.setText(linkText);
// Add the return link to the page.
((OAPageLayoutBean)webBean).setReturnNavigation(returnLink);
}
Following problems are related to work on Database data
Connect to Database and return number of suppliers on the
page
import oracle.apps.fnd.framework.webui.OAWebBeanConstants;
import oracle.apps.fnd.framework.server.OADBTransaction;
import java.sql.*;
// Rebind parameters
delproc.setString(1,"rahul");
delproc.executeUpdate();
} catch(Exception sqle)
{
pageContext.writeDiagnostics(am, sqle.getMessage(), 4);
}
//CallableStatement deleteSt=conn.prepareCall(deleteStmt);
}
Code:
pageContext.forwardImmediatelyToForm("form:PO:PURCHASING_OPERATIO
NS:STANDARD:PO_POXPOEPO");
Result:
Write above code in controller for button. Opens the PO Form when click the
button.
Right click > New View Object (This will open a wizard having 7
steps).
Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeSearchVO
Choose the radio button Read-only Access (as we are not performing
any DML operation). Click Next.
Step 2
Enter the below query in Query Statement:
SELECT empno, ename, job, mgr, hiredate, sal, deptno FROM
employee
Keep defaults for step3, 4, 5, 6
Step 7
Select check boxes for Generate Java File for both View Object Class
and View Row Class. Click Finish.
4) Create a new Application Module (AM):
Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeAM. Click Next.
Step 2
Here we will add an instance of the VO created in (3). Select
XxEmployeeSearchVO from Available View Objects and shuttle it to
Data Model using > button.
Keep defaults for all other steps (3, 4). Click Finish.
5) Create a new Controller class :
Step 1
Select XxEmployeeSearchPG in navigator tab. Declarative form of page
will be visible in structure tab.
Step 2
Right click on pageLayout region > set new controller (This will open
a popup window). Enter the below details:
package Name: xxcus.oracle.apps.fnd.emprec.webui
Class Name: XxEmployeeSearchCO
Creating the Page Layout & Setting its Properties
==========================
Page will appear as below:
ID: pageLayoutRN
AM Definition: xxcus.oracle.apps.fnd.emprec.server.XxEmployeeAM
Window Title: Employee Search Page
Title: Employee Search
Step 4
Change the style to messageStyledText for each row. Also modify the
prompt to make it more user friendly (like empName to Employee
Name).
The declarative page structure in jDev will be similar to as shown
below:
User will enter search criteria (emp num or name) and click on
Go button.
OAWebBean webBean) {
super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getRootApplication
Module();
if (pageContext.getParameter("goBtn") != null) {
if ((!
("".equals(pageContext.getParameter("empNum").trim()))) ||
10.
(!
("".equals(pageContext.getParameter("EmpName").trim())))) {
11.
String empNum = pageContext.getParameter("
empNum");
12.
String empName = pageContext.getParameter(
"EmpName");
13.
if (("".equals(pageContext.getParameter("e
mpNum").trim()))) {
14.
empNum = null;
15.
}
16.
17.
Serializable[] param = { empNum, empName }
;
18.
am.invokeMethod("searchEmployee", param);
19.
} else {
20.
throw new OAException("Please Enter Search
Criteria.",
21.
OAException.ERROR);
22.
23.
24.
}
}
}
try {
XxEmployeeSearchVOImpl vo = getXxEmployeeSearchVO1();
vo.setMaxFetchSize(-1);
vo.setWhereClause(null);
vo.setWhereClauseParams(null);
vo.setWhereClause("EMPNO = nvl(" + empNum + ",EMPNO)" +
8.
')");
9.
System.out.println("search query - " + vo.getQuery());
10.
vo.executeQuery();
11.
12.
} catch(Exception e) {
13.
e.printStackTrace();
14.
}
15.
}
Package -- prajkumar.oracle.apps.fnd.searchdemo.server
4. Create Test Table and insert data some data in it (For Testing
Purpose)
CREATE TABLE xx_search_demo
( -- --------------------- Data Columns
-- -------------------column1
VARCHAR2(100),
column2
VARCHAR2(100),
-- --------------------- Who Columns
-- -------------------last_update_date DATE
NOT NULL,
last_updated_by
NUMBER NOT NULL,
creation_date
DATE
NOT NULL,
created_by
NUMBER NOT NULL,
last_update_login NUMBER
);
INSERT
0);
INSERT
0);
INSERT
0);
INSERT
0);
Right click on SearchDemo > New > ADF Business Components > Entity
Object
Name SearchEO
Package -- prajkumar.oracle.apps.fnd.searchdemo.schema.server
Database Objects -- XX_SEARCH_DEMO
Note By default ROWID will be the primary key if we will not make any
column to be primary key Check the Accessors, Create Method, Validation
Method and Remove Method
Name -- SearchPG
Package -- prajkumar.oracle.apps.fnd.searchdemo.webui
Select QueryRN right click > New > Region using Wizard
In BC4J Objects page, Select your SearchAM and then select your SearchVO1
Select Next button, and observer Query. We can change query, if you select
the check box Expert Mode.
13) Now, I want to include some other condition in the above query.
QUERY:
SELECT EmpSearchEO.EMPLOYEE_ID,
EmpSearchEO.FULL_NAME AS EMPLOYEE_NAME,
EmpSearchEO.EMAIL_ADDRESS AS EMPLOYEE_EMAIL,
EmpSearchEO1.EMPLOYEE_ID AS MANAGER_ID,
EmpSearchEO1.FULL_NAME AS MANAGER_NAME,
EmpSearchEO1.EMAIL_ADDRESS AS MANAGER_EMAIL,
Flkp.meaning POSITION_DISPLAY
FROM FWK_TBX_EMPLOYEES EmpSearchEO,
FWK_TBX_EMPLOYEES EmpSearchEO1,
FWK_TBX_LOOKUP_CODES_VL flkp
WHERE EmpSearchEO.MANAGER_ID = EmpSearchEO1.EMPLOYEE_ID(+)
AND EmpSearchEO.POSITION_CODE=flkp.lookup_code
AND flkp.lookup_type=FWK_TBX_POSITIONS
Select Next button, and check mapping between Query Columns and
Attribute names. Select Finish button.
14) Add the ViewObject (EmployeeSummaryVO) to Application Module.
15) Select the application module (already created), and press right mouse
button and select the option Edit EmpSearchAM, then select the
ViewObject.
16) Attach the Application Module (EmpSearchAM) to your OApage.
17) Create the item under PageLayout Region. The item style is
StaticStyledText.
Set the below properties for the item.
Property
Value
ID
PageHelp
Item Style
StaticStyledText
DataType
Varchar2
CSS Class
OraInstructionText
Message Appl Short Name
AK
Message Name
FWK_TBX_T_PAGE_GENERAL
Test the page once and check the output on the page. Some text will be
displayed on the page above.
Configure RESULT-BASED Search.
18) Create region with style query under pageLayout Region.
Set the below properties for the region queryRN.
Property
Value
ID
queryRN
Item Style
Query
Construction Mode
Result Based Search
Include simple panel
True
Include View panel
True
True
Code:
import oracle.jbo.domain.Number;
import oracle.apps.fnd.framework.OAException;
public void initQuery(String employeeNumber)
{
If (employeeNumber! =null)
{
Number empNum=null;
Try
{
empNum=new Number(employeeNumber);
}
Catch(Exception e)
{
Throw new OAException(AK, FWK_TBX_INVALID_EMP_NUMBER);
}
setWhereClause(EMPLOYEE_ID=:1);
setWhereClauseParams(null);
setWhereClauseParam(0,empNum);
executeQuery();
}
}
10) From applicationModule, we can call view object procedure.
Code:
public void initDetails(String employeeNumber)
{
EmployeeFullVOImpl empvo=getEmployeeFullVO1();
Empvo.initQuery(employeeNumber);
}
11) Create the CONTROLLER and call the procedure initDetails.
12) Write code in processRequest method
Code:
String empnum=pageContext.getParameter(employeeNumber);
OAApplicationModule am=pageContext.getApplicationModule(webBean);
Serializable[] parameters={empnum};
Am.invokeMethod(initDetails, parameters);
Result: we can get the details of employee according to employee
ID.
import oracle.apps.fnd.framework.OAApplicationModule;
import
oracle.apps.fnd.framework.webui.beans.message.OAMessageTextInputBean;
import
oracle.apps.fnd.framework.webui.beans.message.OAMessageLovInputBean;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Date;
import java.text.ParseException;
import oracle.apps.fnd.framework.server.OADBTransaction;
import java.sql.*;
Method: processRequest ()
**********************************
public void processRequest(OAPageContext pageContext, OAWebBean
webBean)
{
super.processRequest(pageContext, webBean);
OAApplicationModule am=pageContext.getApplicationModule(webBean);
am.invokeMethod("initQuery",null);
}
Method: processFormRequest ()
****************************************
public void processFormRequest(OAPageContext pageContext, OAWebBean
webBean)
{
super.processFormRequest(pageContext, webBean);
if (pageContext.getParameter("Apply")!=null)
{
try
{
OAApplicationModule am=pageContext.getApplicationModule(webBean);
//
//
Date update_date=pageContext.getCurrentUserDate();
System.out.println("current date="+update_date);
OAMessageTextInputBean supplier_id =
(OAMessageTextInputBean)webBean.findChildRecursive("Supplie
rId");
String sup_id_txt=supplier_id.getText(pageContext);
int sup_id=Integer.parseInt(sup_id_txt);
OAMessageLovInputBean sup_name =
(OAMessageLovInputBean)webBean.findChildRecursive("Supplier
Name");
String supname_txt=sup_name.getText(pageContext);
OAMessageTextInputBean onhold_flag =
(OAMessageTextInputBean)webBean.findChildRecursive("OnH
oldFlag");
String onhold_txt=onhold_flag.getText(pageContext);
String sdate=pageContext.getParameter("StartDate");
// Date startdate_txt=sdate;
//System.out.println("start date="+df.format(startdate_txt));
String edate=pageContext.getParameter("EndtDate");
// Insert row into the table FWK_TBX_SUPPLIERS
String task2Info = null;
PreparedStatement psProType = null;
ResultSet rsProType = null;
int task2Type = 0;
Connection conn = am.getOADBTransaction().getJdbcConnection();
task2Info = "INSERT INTO
FWK_TBX_SUPPLIERS(SUPPLIER_ID,NAME,ON_HOLD_FLAG,START_DATE,EN
D_DATE,LAST_UPDATE_DATE,LAST_UPDATED_BY,CREATION_DATE,CREATED
_BY) VALUES(:1,:2,:3,:4,:5,SYSDATE,0,SYSDATE,0)";
psProType = conn.prepareStatement(task2Info);
psProType.setInt(1,sup_id);
psProType.setString(2,supname_txt);
psProType.setString(3,onhold_txt);
psProType.setString(4,sdate);
psProType.setString(5,edate);
// psProType.setString();
psProType.executeUpdate();
am.invokeMethod("apply");
}
catch(Exception e)
{
System.out.println("error="+e.getMessage());
}
//psProType.setDate(4,startdate_txt);
// psProType.setDate(5,edate);
}
}
Write below methods in Application Module which is corresponding
to view object.
// it is used to create row in view object cache, and then user can
enter and insert data into table.
public void initQuery()
{
SuppliersVOImpl vo=getSuppliersVO1();
Row row=vo.createRow();
vo.insertRow(row);
}
// it is for commit the transaction; otherwise not inserted the record
into table.
public void apply()
{
getTransaction().commit();
}
Please find the below screen shot. The below data will be inserted into table
when press the Apply button.
See below screenshot for output.
How do refresh the same page after the data has been entered
There is API forwardImmediatelyToCurrentPage used to refresh the
same page when the user presses the submit button.
Write below code in processFormRequest() method
*************************************************************
***
import com.sun.java.util.collections.HashMap;
HashMap params = new HashMap();
pageContext.forwardImmediatelyToCurrentPage(params,true,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
How do set the values in poplist
Solution:1)
Create View Object(VO) and write query to display the values
in poplist.
VO Name: SuppliersListVO
Query:SELECT 'YES' MEANING,'Y' CODE FROM DUAL
UNION
SELECT 'NO' MEANING,'N' CODE FROM DUAL
YES is used to show for user on the OAF page. Y is used for internal
purpose. The value Y will be stored into database when user selects YES.
Set the properties for an item:Property
Item Style
Picklist view
Definition
Picklist Display
Attribute
Picklist Value
Attribute
Value
messageChoice
train.oracle.apps.ak.suppliers.list.webui.SuppliersListVO
Meaning
Code
How do hide the specified item when user selects the particular
value from Poplist
Solution:The concepts partial page rendering and SPEL should be used to get
this solution.
I have one poplist in OAF page and the list has two values YES and
NO. If the user selects the value NO, then the specified item
should be invisible on OAF page at runtime.
Note: This example followed above screen shot page.
Steps:
1) Create properties view object (PVO) and create two attributes.
i) RowKey (Set the properties like below screenshot)
ii) EndDateRender (Set the properties as per below screenshot)
2) Select the option Tuning for the same properties VO and select the
check box like below screenshot.
3)
Attach the propertiesVO (SuppliersListPVO) to application module
(SuppliersAM).
4)
Configure the list item (onholdflag item). Set the below properties.
Property
Disable Server Side Validation
Disable Client Side Validation
Action
Event
Submit
Value
True
True
firePartialAction
onholdflagChange
True
5)
Configure the item which is invisible according to value of the list
item. Here, the invisible item is EndDate. So, set the below property for
the item EndDate.
Property
Rendered
Value
${oa.SuppliersListPVO1.endDateRender}
6)
Write below methods in application module (SuppliersAMImpl.java)
public void onholdflagChange()
{
OAViewObject vo = (OAViewObject)findViewObject("SuppliersListPVO1");
OARow row=(OARow)vo.first();
OAViewObject suppvo=(OAViewObject)findViewObject("SuppliersVO1");
OARow supprow=(OARow)suppvo.getCurrentRow();
String onhold=(String)supprow.getAttribute("OnHoldFlag");
if ((onhold==null)||("N".equals(onhold)))
{
row.setAttribute("EndDateRender",Boolean.FALSE);
}
else
{
row.setAttribute("EndDateRender",Boolean.TRUE);
}
}
public void init()
{
OAViewObject
appPropsVO=(OAViewObject)findViewObject("SuppliersListPVO1");
if (appPropsVO!=null)
{
if (appPropsVO.getFetchedRowCount()==0)
{
appPropsVO.setMaxFetchSize(0);
appPropsVO.executeQuery();
appPropsVO.insertRow(appPropsVO.createRow());
OARow row=(OARow)appPropsVO.first();
row.setAttribute("RowKey",new Number(1));
}
}
onholdflagChange();
}
7)
8)
if
("onholdflagChange".equals(pageContext.getParameter(OAWebBeanConstant
s.EVENT_PARAM)))
{
am.invokeMethod("onholdflagChange");
}
In the above code, the onholdflagChange is event name. The event of the
item will be worked as form-submit. So, the above code (event related) has
been written in processFormRequest.
Run the OAF page and change the value of the list item. The item EndDate
will not be rendered if the value of the list item is NO.
How do fire event? To display supplier name according to
supplier id.
There are two text items on OAF page. They are
I) SupplierId II) SupplierName
Steps:1)
Set the below properties for item SupplierId.
Property
Action
Event
Submit
2)
Value
firePartialAction
supplierNameEvent
True
if("supplierNameEvent".equals(pageContext.getParameter(OAWebB
eanConstants.EVENT_PARAM)))
{
int supp_id =
Integer.parseInt(pageContext.getParameter("SupplierId"));
if (supp_id==195)
{
am.invokeMethod("supplierNameEvent");
}
}
3)
*ID - set the shuttle's ID property in accordance with the OA Framework File
/ Package/ Directory Standards.
*Region Style - set the region style to shuttle.
Add Indexed Children - make sure this property is set to True, so that OA
Framework automatically generates the web beans under this web bean
hierarchy. The default is True.
Available Header - specify the header text of the first (leading) list.
Selected Header - specify the header text of the second (trailing) list.
If you want to implement just one list for Reordering, that is, you do not
want to shuttle items between two lists, then leave this property blank.
Ordering Allowed - set to True if you want to enable ordering of the
contents of the Selected (second or trailing) list.
If you implement only one (leading) list in the shuttle region to create a
Reordering region, then setting this property to True enables ordering on that
leading list. The default is False.
Step 3: The Shuttle region can have a maximum of two list web beans,
referred to as the leading and trailing lists. The trailing list is omitted when
you want to implement a shuttle region with a single list for the purpose of
reordering the contents of that list.
When you define a shuttle region, OA Extension automatically creates a
leading component for you, which contains a single list item.
Be sure to set the following properties on the list item (Required properties
are marked with *):
*ID - set the list's ID property in accordance with the OA Framework File /
Package/ Directory Standards.
*Multi-Select Allowed - set to True to allow the multiple selection of items
in the list. The default is False.
Picklist View Definition - specify the fully qualified view object name that
is the data source to the List web bean.
(For example, oracle.apps.fnd.framework.server.FndApplicationVO)
*Picklist View Instance - alternately specify a view instance name for the
data source of the list, if the Picklist View Definition is not available. Note
that setting this property overrides the Picklist View Definition property.
(For example, FndApplicationVO, which needs to be present in the
ApplicationModule.)
*Picklist Display Attribute - specify the view attribute name that serves as
the displayed values of the list's content.
*Picklist Value Attribute - specify the view attribute name that serves as
the internal values of the list's content. This property, and not the Picklist
Display Attribute property, uniquely identifies the elements in the list.
Picklist Description Attribute - specify the view attribute name that serves
as the descriptions of the list's content.
Rendered - specify True to render this list.
*List Height - specify the suggested display height of the list, in characters.
The default is null. If this property is not set, the height is determined based
on the lengths of both lists and their minimum and maximum values. The
value should be in the range of 10 to 20.
Note: The List Height is only a suggested value. Your browser application
and UIX determines the final 446 height of the list based on the number of
items in the list and the size of the browser window.
Step 4: To create an optional trailing list, select the shuttle region in the
Structure pane and choose New >trailing from the context menu. OA
Extension automatically creates a trailing component for you, which
contains a single list item.
Refer to Step 3 for the list of properties that you should also set on the
trailing list item. Make sure you specify names for the Picklist Display
Attribute, Picklist Value Attribute and Picklist Description Attribute properties
that match the corresponding property of the leading list item.
Note: If you do not want to pre-populate the trailing list when the page
initially renders, you can leave the Picklist View Definition, Picklist View
Instance, Picklist Display Attribute, Picklist Value Attribute and
PicklistDescription Attribute blank. OA Framework takes care of retaining
user selected values in the trailing list when the page refreshes.
Note: The Picklist Value Attribute uniquely identifies the elements in a list, so
if you want to pre-populate both the leading list and trailing list with data, be
sure to set the Picklist Value Attribute property to a different value for each
list. Setting this property to the same value for both lists will result in
undesirable behaviour, such as causing the values in the leading list to
disappear.
Step 5: You can include buttons or icons in the footer of each list, as shown
in Figure 2. Select the shuttle region in the Structure pane, and choose New
> leadingFooter (for a footer in the leading list) or New > trailingFooter
(for a footer in the trailing list). OA Extension automatically creates a
leadingFooter or trailingFooter component, respectively, each containing a
flowLayout region. You can then add your buttons or icons to this flowlayout
region.
Note: If you set the Rendered property to False for either the leading or
trailing list, the leading or trailing footer also does not render, respectively.
Since the footer is directly linked to its respective list, if the list is not
rendered, the footer is irrelevant.
About StackLayout, rowLayout, cellFormat region styles
We can design layout like below screen shot by using the stackLayout,
rowLayout and cellFormat region styles.
pageLayoutRegion
|-----stackLayout region
|----rowLayout region
|---------cellFormat region
|-------spacer (item style)
|
(width: 400)
|-------item (style: formattedText)
(Text: <b>Authority For Expenditure</b>
(Please look above screenshot for result)
|------stackLayout region
|----rowLayout region
|----cellFormat region
|-----spacer (item style)
|
(width: 400)
|-----item (style: formattedText)
(Property Text: <b>Co: 101 XXX Energy Inc</b>)
|--------stackLayout region
|-----rowLayout region
|-----cellFormat region
|------ table region
|----- item1 (style: messageStyledText)
|-----cellFormat region
|------ table region
|----- item2 (style: messageStyledText)
|-----cellFormat region
|------ table region
|----- item3 (style: messageStyledText)
Set the properties for item1, item2 and item3. The properties are
Prompt
View Instance
View Attribute
(Please see table region in above screenshot for result)
How to display text items side by side
Solution:pageLayoutRegion
|-----stackLayout region
|----rowLayout region
|---------cellFormat region
|-------item (messageTextInput)
|---------cellFormat region
|-------item (style: spacer; width: 50)
Set the item properties for messageTextinput.
The properties are prompt, view Instance and view Attribute
(Please see above screenshot for result).
Example:
OA.jsp?
page=/train/oracle/apps/ak/employee/webui/EmpDetailsPG&employeeNumbe
r={@EmployeeId}&retainAM=Y&addBreadCrumb=Y&OALAF=minimal
Call the page EmpDetailsPG from any another page and observe
appearance of the EmpDetailsPG. Please find the below screen shot.
(OALAF=minimal)
From above screenshot, some text is showing in green color. Try for blaf
and oaText LAFs like above.
About AdvancedTable Bean
Previously, OA Framework used
oracle.apps.fnd.framework.webui.beans.table.OATableBean, an Oracle
Application implementation of UIX oracle.cabo.ui.beans.table.TableBean, to
render tables. Now
oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean extends
OATableBean to provide declarative support for existing table features that
previously required programmatic control. OAAdvancedTableBean also
provides declarative support for features not available with OATableBean,
such as column span in a table column header. As of Release 11.5.10, oracle
corp. recommend new tables be implemented as "advanced tables" based on
oracle.apps.fnd.framework.webui.beans.table.OAAdvancedTableBean.
You can create a table by specifying appropriate information in Oracle 9i
JDeveloper OA Extension. Currently, you can declaratively specify the
following features/components/attributes on a table:
Number of rows to display in a table
Width of a table
Header text for individual table columns
Column span in column headers
Table formatting
Single selection and multiple selection on a table and adding other
controls to a selection bar
Sorting and initial sorting of a table on up to three columns
Totalling a column
Adding new rows
Detail Disclosure
Row Headers
Wrap Settings
{
EmployeeFullVoImpl empvo=getEmployeeFullVo1();
Row row=empvo.createRow();
empvo.insertRow(row);
empvo.executeQuery();
}
In above code, the EmployeeFullVo1 is view object instance.
Compile the code and run the page.
How do display Add another row button and totalling on column
In AdvancedTable, this is good feature to add row dynamically and display
total on footer without write code.
Declarative implementation
Select the advancedTable region and press right mouse button and select
the option footer.
After select the footer option, the footer and tableFooter1 components
will be created. See below screenshot.
Select the tableFooter1 and press right mouse button and select the
option addTableRow. See below screenshot.
Run the page once and you will get Add another Row button at the footer
of advancedTable.
Select total option to display total of particular column (salary). The
option total showing in above screen shot.
We need to set one property Total Value as True for salary column
(column4 in below screen shot) and run the page.
See the below screenshot to know the final output of advancedTable. (Add
Another Row button, Recalculate button and total value for salary
column)
After press the Add Another Row button, one blank record will be
created. See below screen shot.
User selects the Recalculate button to update the column total.
Note: The total displays a double precision summation of all visible rows in
the table.
The total reflects only the current visible records and not all the
records queried.
How do iterate the number(Serial Number) in OAF by using
Transient Attribute
Code:
public void setItemDetailsSno()
{
OAViewObject vo = (OAViewObject)getCMCostchangeVO();
CMCostchangeVORowImpl row = null;
int fetchedRowCount = vo.getRowCount();
// we use a separate iterator -- even though we could step
through the
// rows without it -- because we don't want to affect row
currency.
RowSetIterator insertIter = vo.createRowSetIterator("insertIter1");
if (fetchedRowCount > 0)
{
insertIter.setRangeStart(0);
insertIter.setRangeSize(fetchedRowCount);
for (int i = 0; i < fetchedRowCount; i++)
{
row = (CMCostchangeVORowImpl)insertIter.getRowAtRangeIndex(i);
// For performance reasons, we generate ViewRowImpls for all
// View Objects. When we need to obtain an attribute value,
// we use the named accessors instead of a generic String
lookup.
row.setAttribute("SNo", new Integer(i+1));
//SNo is transient attribute in VO
}
}
insertIter.closeRowSetIterator();
}
See below screenshot and check the values of serial number
Check the values of serial number in above screen shot.
How do display latest serial number dynamically while creating
row
Write below code in proecessFormRequest Method of Controller.
Code:
oracle.apps.fnd.framework.OAApplicationModule
am=pageContext.getApplicationModule(webBean);
OAAdvancedTableBean tableBean =
(OAAdvancedTableBean)webBean.findChildRecursive("AdvancedtblRN
");
if
(tableBean.getName().equals(pageContext.getParameter(SOURCE_PARAM))
&&
ADD_ROWS_EVENT.equals(pageContext.getParameter(EVENT_PARAM)))
{
am.invokeMethod("setSequenceNum");
}
Note: From above code, ADD_ROWS_EVENT is event name for Add
Another Row button.
Write below code in Application Module which is added to your
pagelayout region.
Imp: Set the property insert rows automatically as False in
addTableRow1 object at footer of advanced table.
public void setSequenceNum()
{
SequenceNumberVOImpl seqvo=getSequenceNumberVO1();
int fetchedRowCount=seqvo.getRowCount();
RowSet rowset=seqvo.createRowSet("dd");
rowset.last();
rowset.next();
Row row=seqvo.createRow();
rowset.insertRow(row);
row.setAttribute("SERIALNUM",new Integer(fetchedRowCount+1));
rowset.closeRowSet();
}
Result: Display Serial Number (transient attribute) according to current row
position dynamically after pressing the Add Another Row button.
See below screen shot, after press the Add Another Row button
New row is created and added onto table, and SerialNumber is also
incremented (from 6 to 7) and displayed on table. See below screenshot.
How do delete a selected record of Advanced Table using Delete
Switcher
Solution:-
===================
Right click on emprec package and create a new entity object (This
will open a wizard having 5 steps).
Step 1
Package: xxcus.oracle.apps.fnd.emprec.schema.server
Name: XxEmployeeEO
Schema Object (in Database Object): EMPLOYEE
Click Next.
Step 2
Keeps default (all attributes selected). Click Next.
Step 3
If there is any primary key in DB table, then keep all defaults else
select a primary key (like empno). Click Next.
Step 4
Keep defaults and click on Next.
Step 5
Keep Generate Default View Object uncheked and click on Finish.
2) Create a new View Object (VO) based on EO created in (1):
====================
Right click > New View Object (This will open a wizard having 7
steps).
Step 1
Package: xxcus.oracle.apps.fnd.emprec.server
Name: XxEmployeeVO
Choose the radio button Updatable access through Entity Objects.
Click Next.
Step 2
Select the xxcus.oracle.apps.fnd.emprec.schema.server.XxEmployeeEO
from Available list and shuttle it to Selected list. Click Next.
Step 3
Move all the columns except WHO columns (lastUpdateLogin,
createdBy) to Selected list from Available list attributes.
Click Next.
Keep defaults for step 4, 5 & 6.
Step 7
Select check boxes for Generate Java File for both View Object Class
and View Row Class. Click Finish.
Double Click on XxEmployeeAM and shuttle XxEmployeeVO from
Available view objects to Data Model.
(now there are two VO instances in AM :XxEmployeeSearchVO1
& XxEmployeeVO1).
3) Edit Employee Search Page (XxEmployeeSearchPG):
====================
(This includes adding a create button at top & update icon on every
row in search result. Modified page will appear as below:)
Step 1
Right click on pageLayoutRN and add a new region. Set properties as
below:
Region Style: pageButtonBar
ID: pageBtnBarRN
Right click on pageBtnBarRN region and add a new item:
Item Style: submitButton
ID: createBtn
Prompt: Create Employee
Step 2
Right click on XxEmployeeSearchVO1 table region and add an item.
Set the below properties:
Item Style: Image
ID: updateImg
Prompt: Update
Image URI: updateicon_enabled.gif
Action Type: fireAction
Event: updateEvent
Right click emprec > New > Web Tier > OA Components > select
Page item. Click OK. (This will open a popup window)
We are creating Employee Create Update Page, so specify the details
of page as below:
Name: XxEmployeeCreateUpdatePG
Package: xxcus.oracle.apps.fnd.emprec.webui
Create a new region under pageLayout of type header
Create another region under the header region using wizard
(This will open a wizard window having 4 steps):
ID: empCreateRN
1. // XxEmployeeSearchCO :: PFR
2. if (pageContext.getParameter("createBtn") != null) {
3.
4.
5.
6.
7.
8.
9. if ("updateEvent".equals(pageContext.getParameter(EVENT_PAR
AM))) {
10.
String p_empNum = pageContext.getParameter("p_empN
um");
11.
HashMap hm = new HashMap();
12.
hm.put("event", "update");
13.
hm.put("empNum", p_empNum);
14.
pageContext.forwardImmediately("OA.jsp?
page=/xxcus/oracle/apps/fnd/emprec/webui/XxEmployeeCreateUp
datePG",
15.
null, (byte)0, null, h
m, false, null);
16.
}
1. // XxEmployeeCreateUpdateCO :: PR method
2. public void processRequest(OAPageContext pageContext, OAWeb
Bean webBean) {
3.
super.processRequest(pageContext, webBean);
4.
am = pageContext.getRootApplicationModule();
5.
6.
if ("create".equals(pageContext.getParameter("event")))
{
7.
am.invokeMethod("initCreateEmp");
8.
}
9.
10.
if ("update".equals(pageContext.getParameter("even
t"))) {
11.
String empNum = pageContext.getParameter("empN
um");
12.
Serializable[] param = { empNum };
13.
am.invokeMethod("initUpdateEmp", param);
14.
}
15.
}
1. // XxEmployeeAMImpl ::
2. public void initCreateEmp() {
3.
try {
4.
XxEmployeeVOImpl empCreateVO = getXxEmployeeVO1();
5.
6.
7.
8.
empCreateVO.setMaxFetchSize(0);
XxEmployeeVORowImpl row = (XxEmployeeVORowImpl)empC
reateVO.createRow();
30.
Finally, user can click on Save button to commit the data or Cancel
to return back to search page.
1.
2.
25.
/fnd/emprec/webui/XxEmployeeSearchPG", null, (byte)
0, null, hm, false, null);
26.
}
27. }
getOADBTransaction().commit();
return savedEmp;
} catch (Exception e) {
e.printStackTrace();
}
49. }
Step 1
Package: xxcus.oracle.apps.fnd.dpndntlov.lov.server
Name: XxPoLinesLovVO
Choose the radio button Read-only Access. Click Next.
Step 2
Enter the below query in Query Statement:
select PO_HEADER_ID, PO_LINE_ID from po_lines_all
Keep defaults for step3, 4, 5, 6 & 7 and click Finish. Save All.
3) Create a new Application Module (AM):
==========================
Step 1
Package: xxcus.oracle.apps.fnd.dpndntlov.server
Name: XxDemoDependentLovAM. Click Next.
Step 2
Here we will add an instance of the VOs created in (2).
Select XxPoHeaderLovVO & XxPoLinesLovVO from Available View
Objects and shuttle it to Data Model using > button.
Keep defaults for all other steps (3, 4). Click Finish.
4) Creating the Page Layout & Setting its Properties:
==========================
Page will appear as below :
lovMap2:
LOV region item: PoLineId
Return item: poLineLov
Criteria item: poLineLov
Here, in lovMap3, we are making this dependent on first LOV by
setting criteria item as value of first LOV field.
lovMap3:
LOV region item:PoHeaderId1
Criteria item: poHearderLov
The declarative page structure in jDev will be similar to as shown
below:
Now select a value (PO Header Id) from LOV1 such as 4 (as shown in
above screenshot).
Perform a search on PO Line ID LOV. This will show only those lines
whose header Id is 4.
Framework
provides
solution
for
this: Partial
Page
be
re-rendered.
The second difference between partial page events an full page events
is how the events are sent. Unlike full page events, partial page events
must be sent in a way which does not force the browser to reload the
current page. To implement this capability, UIX PPR uses a hidden
iframe as a communication channel between the browser and the web
application running on the middle-tier. Partial page events are sent by
forcing a navigation in the hidden iframe, which in turns causes a
request to be sent to the application on the middle-tier. Since the
iframe is hidden, the process of sending a partial page event and
rendering partial page contents can take place behind the scenes,
without discarding the contents of the current page.
2) Partial Page Rendering Pass
When the partial page event is received by the application, the
application responds by determining the set of partial targets to render
and performing the partial page rendering pass. The partial page
rendering pass is similar to a full page rendering pass. In both cases,
the UINode tree is traversed by calling render() on each node in the
tree. However, in the PPR case, only the contents generated by the
partial targets are actually sent back to the browser. All other contents
are dropped. So, the partial page response is generally much smaller,
since only the modified contents are sent back to the browser.
3) Partial Page Replacement
When the browser receives the partial page response, the new
contents for each partial target node are copied from the hidden
iframe into the main browser window, replacing the existing contents
for each target node. For example, in the table navigation case, rather
than replacing the entire page, just the contents of the table itself are
replaced.
Now lets create a simple page to implement PPR. In this page, there
are 3 items (employee number, employee name & job). I have attach a
PPR event on employee number field. Hence, user will enter the emp
number and as soon as he tabs out, name and job will populate on
their respective fields without refreshing the page.
1) Create a new OA page:
==========================
Right click on project (xxcus) > New > Web Tier > OA Components
> select Page item. Click OK. (This will open a popup window)
We are creating a page for implementing PPR, so specify the details of
page as below:
Name: XxPprDemoPG
Package: xxcus.oracle.apps.fnd.pprdemo.webui
2) Create a new view objects (VO):
==========================
Right click > New View Object (This will open a wizard having 7
steps).
Step 1
Package: xxcus.oracle.apps.fnd.pprdemo.server
Name: XxPprDemoVO
Choose the radio button Read-only Access (as no DML
operation).
Click Next.
Step 2
2)
Create
items
under
defaultSingleColumn
region
Definition:
publicvoidprocessFormRequest(OAPageContext
pageContext,
OAWebBeanwebBean){
super.processFormRequest(pageContext,webBean);
OAApplicationModuleam=
pageContext.getRootApplicationModule();
if
("populateFields".equals(pageContext.getParameter(EVENT
_PARAM))){
StringempNum=pageContext.getParameter("Empno");
if(!("".equals(empNum.trim()))){
Serializable[]param={empNum};
Stringresult=
am.invokeMethod("firePprEvent",
param).toString();
if("N".equals(result)){
thrownewOAException("Pleaseentervalid
employeenumber.",
OAException.ERROR);
}
}else{
Stringempnum=null;
Serializable[]param={empnum};
am.invokeMethod("firePprEvent",param);
thrownewOAException("Pleaseenteremployee
number",
OAException.ERROR);
}
}
}
Code for firePprEvent method in XxPprDemoAMImpl.java file:
publicStringfirePprEvent(StringempNum){
try{
XxPprDemoVOImplvo=getXxPprDemoVO1();
vo.setWhereClause(null);
vo.setWhereClauseParams(null);
vo.setWhereClause("EMPNO=:1");
vo.setWhereClauseParam(0,empNum);
vo.setMaxFetchSize(1);
vo.executeQuery();
XxPprDemoVORowImplrow=
(XxPprDemoVORowImpl)vo.first();
if(row==null){
return"N";
}
}catch(Exceptione){
e.printStackTrace();
}
return"Y";
}
User will enter employee number and tabs out. This will auto-populate
the other two fields without full page refresh as shown below: