转自:https://liang-wenfu.iteye.com/blog/1066755
在OAF开发中,LOV的使用频率是很高的,它由两部分构成一是页面上的LOV输入框(如OAMessageLovInputBean),二是弹出的LOV模式窗口(OAListOfValueBean)。用户选择LOV的按钮就会弹出LOV窗口,用户在LOV窗口查询并选择了值,可以返回到页面上的LOV输入框。在这里就不赘述如何创建LOV,只说一些平时会碰到的应用:
1.控制LOV的查询结果
2.LOV相关事件
3.动态LOV
4.LOV Choice
一,控制LOV的查询结果
1,使用Criteria
很多种情况下都会用到用某一个Item或者某几个Item来控制LOV的结果,例如页面上有一个Item的LOV和一个Organization,因为Item是有库存组织的,所以就有这样的需求,我选择了某一个库存组织的时候,Item的LOV只显示该库存组织下面的Item。
要实现这个功能,首先需要将Organization放入LOV查询语句作为结果集(LOV的VO中加入Oraganization_Id这一列),然后在Item的LOV中新建一个Mapping,Mapping中LOV Region Item选择OrganizationId(LOV中的),而Criteria选择页面上的OrganizationId,注意,这两个不是同一个Organization。一个是LOV中的,一个是页面上的。
Criteria设置了相应的Item时,在弹出LOV窗口时,会作为验证字段带入LOV窗口,LOV视图对象会自动绑定该值作为查询条件。因为这个自动绑定是对查询的结果集再进行一次条件查询,所以需要将Organization_Id作为查询结果集。
2,Passive Criteria
LOV的Criteria Item也可以手动绑定,也就是在主页面上的作为Criteria Item的字段在传入LOV Region后并不和LOV的查询自动绑定,而是由开发员动态去绑定。这种方法我认为是为了一些高级的查询所设的,例如需要根据传入的一个Flag字段,在查询条件中加入exists…这样的查询条件。
使用Passive Criteria,和LOV的普通Criteria Mapping一样,选择LOV Region Item以及Criteria Item,然后将Programmatic Query选择为True,这样,LOV就不会动态绑定查询条件了。之后,我们在LOV的Region上创建一个CO,在processRequest中得到验证字段:
-
public
void
processRequest(OAPageContext pageContext, OAWebBean webBean)
-
{
-
super
.processRequest(pageContext, webBean);
-
OAApplicationModule am = pageContext.getApplicationModule(webBean);
-
Dictionary passiveCriteria = pageContext.getLovCriteriaItems();
-
-
String lovCriteria = (String)passiveCriteria.get(
"LookupType"
);
-
-
OAViewObject lovVO = (OAViewObject)am.findViewObject(
"FndLookupTypeLovVO1"
);
-
-
lovVO.setWhereClause(
""
);
-
lovVO.executeQuery();
-
}
二、LOV事件
对于MessageTextInput,CheckBox等,可以使用Client Action来触发事件,假如一个CheckBox,可以为它做一个fireAction来控制比如打勾了以后改变某一个字段的值或者一些类似的控制。这些事件可以在页面CO中的processFormRequest中使用pageContext.getParameter(EVENT_PARAM)获得。但是MessageLovInput是没有fireAction事件的,实际上Lov操作的时候已经存在了一些事件,不需要我们去定义的,可以直接通过pageContext.getParameter(EVENT_PARAM)得到LOV事件。
LOV事件有三种,lovPrepare、lovUpdate、lovValidate(由pageContext.getParameter(EVENT_PARAM)返回),它们都是在页面CO的processFormRequest中触发的。当点了Lov上的手电筒时,会触发事件lovPrepare。当选中了某一个Lov返回到本页面是,会在formRequest中触发事件lovUpdate。当在Lov输入框中输入一个唯一的值时,此时会触发Lov验证,这里需要注意的是如果在输入框中输入一个不唯一的值,那么验证会自动的打开Lov窗口让你进行选择,此时在formRequest中是不会触发lovValidate事件的。当在选择了LOV选择的值进行相应的页面处理(例如控制其他字段是否显示等),就可以在processFormRequest中通过对Lov事件的判断并做相应处理。
-
-
super
.processFormRequest(pageContext, webBean);
-
OAApplicationModule am = pageContext.getApplicationModule(webBean);
-
if
(
"ItemCode"
.equals(pageContext.getLovInputSourceId()))
-
{
-
-
-
if
(
"lovUpdate"
.equals(pageContext.getParameter(EVENT_PARAM))
-
||
"lovValidate"
.equals(pageContext.getParameter(EVENT_PARAM)))
-
{
-
-
am.invokeMethod(
"controlRevSwitcher"
,
new
Serializable[]
-
{pageContext.getParameter(SOURCE_PARAM),
-
pageContext.getParameter(
"OrganizationIdFV"
)});
-
-
-
-
OAAdvancedTableBean tableBean =
-
(OAAdvancedTableBean)webBean.findChildRecursive(
"VenTrxLinesAdvTbl"
);
-
tableBean.queryData(pageContext);
-
}
-
}
在上例的例子中,由于LOV字段是基于VO的,所以得到所选的LOV的值可以在VO中得到。但是对于不基于VO的LOV,如果需要在页面事件发生的时候就得到选择得到的LOV值,需要用以下方法来获取:
-
-
-
-
-
String lovInputSourceId = pageContext.getParameter(SOURCE_PARAM);
-
-
Hashtable lovResults =
-
pageContext.getLovResultsFromSession(lovInputSourceId);
-
if
(lovResults !=
null
)
-
{
-
System.out.println(
"lovResults"
+lovResults);
-
-
}
三、动态LOV
动态LOV的应用一般很少。在之前沈辉写的一个文档中,是通过先创建一个LOV后,然后在页面事件发生时动态的去改变LOV的SQL实现的。而我的方法是用直接动态创建VO去和LOV Region中的Item进行关联来实现的。
LOV是通过页面调用我们创建好的Region来实现的,所以这个LOV Region是LOV最为关键的部分,所以实际上,在LOV VO还不存在的时候,只要有Region,我们的LOV就可以创建起来。所以我们可以先创建一个空壳Region,然后在主页面打开的时候再动态的创建LOV VO,最后将VO与Region中的Table关联。
首先,需要创建一个LOV Region,这个Region并不和任何VO关联,在我的例子中,我创建了5个MessageStyledText,5个FormValue。这些字段字段此时只是设置了Prompt属性,其他属性都是默认,包括Data Type。
接下来,在主页面的ProcessRequest创建LOV Bean(当然也可以在其他页面动作的时候创建LOV)。并且创建LOV VO。
-
import
java.io.Serializable;
-
-
import
java.util.ArrayList;
-
import
java.util.Hashtable;
-
-
import
oracle.apps.fnd.common.VersionInfo;
-
import
oracle.apps.fnd.framework.OAApplicationModule;
-
import
oracle.apps.fnd.framework.webui.OAControllerImpl;
-
import
oracle.apps.fnd.framework.webui.OAPageContext;
-
import
oracle.apps.fnd.framework.webui.beans.OAWebBean;
-
import
oracle.apps.fnd.framework.webui.beans.layout.OAHeaderBean;
-
import
oracle.apps.fnd.framework.webui.beans.message.OAMessageLovInputBean;
-
-
public
void
processRequest(OAPageContext pageContext, OAWebBean webBean)
-
{
-
super
.processRequest(pageContext, webBean);
-
OAApplicationModule am = pageContext.getApplicationModule(webBean);
-
-
-
-
OAHeaderBean headerBean = (OAHeaderBean)webBean.findChildRecursive(
"TestHdRN"
);
-
OAMessageLovInputBean lovInput = (OAMessageLovInputBean)createWebBean(pageContext, LOV_TEXT,
null
,
"InputTest"
);
-
-
headerBean.addIndexedChild(lovInput);
-
-
-
lovInput.setAttributeValue(REGION_CODE,
"/alther/oracle/apps/cux/checkboxtest/webui/CheckBoxTestPG"
);
-
-
lovInput.setAttributeValue(REGION_APPLICATION_ID,
new
Integer(
30001
));
-
-
-
lovInput.setLovRegion(
"/alther/oracle/apps/cux/lov/webui/CommonLovRN"
,
);
-
-
lovInput.setUnvalidated(
false
);
-
lovInput.setPrompt(
"Dynamic Lov"
);
-
-
-
lovInput.addLovRelations(pageContext,
"InputTest"
,
-
"DisplayItem1"
,
-
LOV_RESULT,
-
LOV_REQUIRED_NO);
-
lovInput.addLovRelations(pageContext,
"InputTest"
,
-
"DisplayItem1"
,
-
LOV_CRITERIA,
-
LOV_REQUIRED_NO);
-
-
lovInput.addLovRelations(pageContext,
"TestItem"
,
-
"DisplayItem2"
,
-
LOV_PASSIVE_CRITERIA,
-
LOV_REQUIRED_NO);
-
-
-
ArrayList paramList =
new
ArrayList();
-
String voName =
"FndUserLovVO2"
;
-
String sql =
"SELECT fu.user_id,"
+
-
" fu.user_name,"
+
-
" fu.start_date"
+
-
" FROM fnd_user fu"
;
-
-
-
paramList.add(
new
String[]{
"UserId"
,
"USER_ID"
,
"oracle.jbo.domain.Number"
,
null
,
"Hide"
,
null
});
-
paramList.add(
new
String[]{
"UserName"
,
"USER_NAME"
,
"java.lang.String"
,
"100"
,
"Display"
,
"SearchAllow"
});
-
paramList.add(
new
String[]{
"StartDate"
,
"START_DATE"
,
"oracle.jbo.domain.Date"
,
null
,
"Display"
,
null
});
-
-
am.invokeMethod(
"createVO"
,
new
Serializable[]{voName, sql, paramList},
-
new
Class[]{String.
class
, String.
class
, paramList.getClass()});
-
-
am.getOADBTransaction().putTransientValue(
"LovVOInstance"
, voName);
-
am.getOADBTransaction().putTransientValue(
"LovAttribute"
, paramList);
-
-
}
这是AM中创建VO的方法:
-
import
java.sql.Types;
-
-
import
java.util.ArrayList;
-
-
import
oracle.apps.fnd.framework.server.OAApplicationModuleImpl;
-
import
oracle.apps.fnd.framework.server.OADBTransaction;
-
import
oracle.apps.fnd.framework.server.OAViewDef;
-
-
import
oracle.jbo.AttributeDef;
-
-
public
void
createVO(String voName, String sql, ArrayList list){
-
OADBTransaction dbtx = getOADBTransaction();
-
String[] attribute =
new
String[
6
];
-
int
types = -
9999
;
-
OAViewDef viewDef = dbtx.createViewDef();
-
-
viewDef.setSql(sql);
-
viewDef.setExpertMode(
true
);
-
viewDef.setViewObjectClass(
"oracle.apps.fnd.framework.server.OAViewObjectImpl"
);
-
viewDef.setViewRowClass(
"oracle.apps.fnd.framework.server.OAViewRowImpl"
);
-
-
for
(
int
i =
; i < list.size(); i++){
-
attribute = (String[])list.get(i);
-
if
(
"java.lang.String"
.equals(attribute[
2
])){
-
types = Types.VARCHAR;
-
}
-
else
if
(
"oracle.jbo.domain.Number"
.equals(attribute[
2
])){
-
types = Types.NUMERIC;
-
}
-
else
if
(
"oracle.jbo.domain.Date"
.equals(attribute[
2
])){
-
types = Types.DATE;
-
}
-
-
if
(
"java.lang.String"
.equals(attribute[
2
])){
-
viewDef.addSqlDerivedAttrDef( attribute[
],
-
attribute[
1
],
-
attribute[
2
],
-
types,
-
false
,
-
true
,
-
AttributeDef.UPDATEABLE,
-
Integer.parseInt(attribute[
3
]));
-
}
-
else
{
-
viewDef.addSqlDerivedAttrDef( attribute[
],
-
attribute[
1
],
-
attribute[
2
],
-
types,
-
false
,
-
true
,
-
AttributeDef.UPDATEABLE); }
-
}
-
-
if
(findViewObject(voName) !=
null
){
-
findViewObject(voName).remove();
-
}
-
-
createViewObject(voName, viewDef);
-
}
最后,在LOV Region的CO中,加入关联的代码。这里需要注意一点,由于我们的LOV VO是创建在主页面的AM下的,所以LOV Region的AM必须和主页面的AM一致。否则,在主页面的变量就无法传到LOV Region中。
-
public
void
processRequest(OAPageContext pageContext, OAWebBean webBean)
-
{
-
super
.processRequest(pageContext, webBean);
-
OAApplicationModule am = pageContext.getApplicationModule(webBean);
-
-
String voInstance = (String)am.getOADBTransaction().getTransientValue(
"LovVOInstance"
);
-
ArrayList paramList = (ArrayList)am.getOADBTransaction().getTransientValue(
"LovAttribute"
);
-
String[] attribute =
new
String[
6
];
-
int
dispalyIndex =
1
;
-
int
hideIndex =
1
;
-
-
-
((OAListOfValuesBean)webBean).setViewUsageName(voInstance);
-
-
-
for
(
int
i=
1
; i<=
5
; i++){
-
OAMessageStyledTextBean displayItem =
-
(OAMessageStyledTextBean)webBean.findChildRecursive("DisplayItem"+i);
-
displayItem.setRendered(
false
);
-
}
-
-
-
for
(
int
i=
1
; i<=
5
; i++){
-
OAFormValueBean hideItem =
-
(OAFormValueBean)webBean.findChildRecursive("FormVal"+i);
-
hideItem.setRendered(
false
);
-
}
-
-
for
(
int
i=
; i<paramList.size(); i++){
-
attribute = (String[])paramList.get(i);
-
if
(attribute[
4
] !=
null
&& "Display".equals(attribute[
4
])){
-
OAMessageStyledTextBean displayItem =
-
(OAMessageStyledTextBean)webBean.findChildRecursive("DisplayItem"+dispalyIndex);
-
-
-
displayItem.setViewAttributeName(attribute[
]);
-
-
-
if
("java.lang.String".equals(attribute[
2
])){
-
displayItem.setDataType("VARCHAR2");
-
}
-
else
if
("oracle.jbo.domain.Number".equals(attribute[
2
])){
-
displayItem.setDataType("NUMBER");
-
}
-
else
if
("oracle.jbo.domain.Date".equals(attribute[
2
])){
-
displayItem.setDataType("DATE");
-
}
-
-
displayItem.setRendered(
true
);
-
-
-
if
(attribute[
5
] !=
null
&& "SearchAllow".equals(attribute[
5
])){
-
displayItem.setQueryable(
true
);
-
}
-
-
dispalyIndex++;
-
}
-
else
if
(attribute[
4
] !=
null
&& "Hide".equals(attribute[
4
])){
-
OAFormValueBean hideItem =
-
(OAFormValueBean)webBean.findChildRecursive("FormVal"+hideIndex);
-
-
-
hideItem.setViewAttributeName(attribute[
]);
-
-
if
("java.lang.String".equals(attribute[
2
])){
-
hideItem.setDataType("VARCHAR2");
-
}
-
else
if
("oracle.jbo.domain.Number".equals(attribute[
2
])){
-
hideItem.setDataType("NUMBER");
-
}
-
else
if
("oracle.jbo.domain.Date".equals(attribute[
2
])){
-
hideItem.setDataType("DATE");
-
}
-
-
hideItem.setRendered(
true
);
-
-
hideIndex++;
-
}
-
}
-
}
由于是测试页面,所以Region Table的Prompt和Table中Item的Prompt并没有设上去。
四、LOV Choice
LOV Choice并不常用,实现起来也比较简单,它结合了下拉列表和LOV的特性,实际上就是将LOV常用的一些行放到列表中来:
当点击More的时候,会弹出来LOV Region,在Region选中的行,在之后会保存在列表中(可能是放在IE缓存中),以方便之后选择。
由于有下拉列表的特性,所以LOV Choice在下拉列表的时候只能有两列,而多余的列只能在LOV中显示。
1.创建LOV Region,需要注意的是LOV中用来作为列表返回值的列,长度不超过30
2.在页面中创建一个Item,类型选择messageLovChioce,设置External LOV属性
3.设置messageLovChioce的Picklist Display Attribute属性和Picklist Value Attributes属性,这个和下拉列表差不多,一个作为messageLovChioce真正的值,一个作为返回值。
4.Lov Mapping和平常一样,返回值必须和messageLovChioce相对应,并且,Criteria Item属性必须为空(否则会报错)。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/24627116/viewspace-2653953/
,如需转载,请注明出处,否则将追究法律责任。