Oracle ADF 12c中从SelectOneChoice获取ID并触发弹窗的问题
Oracle ADF12C SelectOneChoice值变更弹窗问题解决
问题背景
在Oracle ADF12C的表格列中使用基于自定义查询的SelectOneChoice组件,需求是当组件值变更时打开弹窗。尝试通过值变更监听器和JavaScript获取选中值均失败,现有代码如下:
原JSF代码
<af:selectOneChoice value="#{row.bindings.ProfileId.inputValue}" label="#{row.bindings.ProfileId.label}" required="#{bindings.Assets1.hints.ProfileId.mandatory}" shortDesc="#{bindings.Assets1.hints.ProfileId.tooltip}" id="soc7" binding="#{GenericListenerBean.assetprofileBV}"> <f:selectItems value="#{row.bindings.ProfileId.items}" id="si8"/> <f:validator binding="#{row.bindings.ProfileId.validator}"/> <af:clientListener method="profileLovValue" type="valueChange"/> </af:selectOneChoice>
原JavaScript代码
function profileLovValue() { alert("function called"); var lov_value = document.getElementById('soc8'); alert("Executedd ======"+lov_value); var strUser = lov_value.options[lov_value.selectedIndex].value; alert("value ======"+strUser); }
错误分析
- ID错误:JavaScript中硬编码的
soc8是不存在的组件ID,实际SelectOneChoice的ID是soc7 - ADF组件ID机制:ADF会自动为表格行内的组件添加命名空间前缀(如
pt1:r1:soc7),直接用document.getElementById无法正确获取组件实例 - 未利用ADF客户端API:ADF提供了专门的客户端组件API,无需直接操作DOM
解决方案
方案一:客户端JavaScript修正
使用ADF客户端API获取组件实例及选中值,无需依赖硬编码ID:
- 修改SelectOneChoice,添加
clientComponent="true"以确保生成客户端实例:
<af:selectOneChoice value="#{row.bindings.ProfileId.inputValue}" label="#{row.bindings.ProfileId.label}" required="#{bindings.Assets1.hints.ProfileId.mandatory}" shortDesc="#{bindings.Assets1.hints.ProfileId.tooltip}" id="soc7" binding="#{GenericListenerBean.assetprofileBV}" clientComponent="true"> <!-- 添加此属性 --> <f:selectItems value="#{row.bindings.ProfileId.items}" id="si8"/> <f:validator binding="#{row.bindings.ProfileId.validator}"/> <af:clientListener method="profileLovValue" type="valueChange"/> </af:selectOneChoice>
- 修正JavaScript函数,通过事件源获取组件及选中值:
function profileLovValue(event) { alert("值变更事件触发"); // 获取ADF客户端组件实例 var socComponent = event.getSource(); // 获取选中值 var selectedValue = socComponent.getValue(); alert("选中值:" + selectedValue); // 此处添加打开弹窗的逻辑,例如调用ADF弹窗组件的show方法 // var popup = AdfPage.PAGE.findComponentByAbsoluteId("popupId"); // popup.show(); }
方案二:服务器端值变更监听器
如果需要在服务器端处理选中值后再触发弹窗,可使用服务器端监听器:
- 修改SelectOneChoice,添加服务器端值变更监听器:
<af:selectOneChoice value="#{row.bindings.ProfileId.inputValue}" label="#{row.bindings.ProfileId.label}" required="#{bindings.Assets1.hints.ProfileId.mandatory}" shortDesc="#{bindings.Assets1.hints.ProfileId.tooltip}" id="soc7" binding="#{GenericListenerBean.assetprofileBV}" valueChangeListener="#{GenericListenerBean.onProfileValueChange}"> <!-- 添加监听器 --> <f:selectItems value="#{row.bindings.ProfileId.items}" id="si8"/> <f:validator binding="#{row.bindings.ProfileId.validator}"/> <af:clientListener method="profileLovValue" type="valueChange"/> </af:selectOneChoice>
- 在
GenericListenerBean中实现监听器方法:
import javax.faces.event.ValueChangeEvent; import oracle.adf.view.rich.component.rich.RichPopup; import oracle.adf.view.rich.context.AdfFacesContext; public class GenericListenerBean { private RichPopup assetPopup; // 注入弹窗组件 public void onProfileValueChange(ValueChangeEvent event) { // 获取新选中值 Object newValue = event.getNewValue(); System.out.println("选中的ProfileId:" + newValue); // 触发弹窗显示 if (assetPopup != null) { assetPopup.show(new RichPopup.PopupHints()); } // 通知页面刷新 AdfFacesContext.getCurrentInstance().addPartialTarget(assetPopup); } // getter和setter方法 public RichPopup getAssetPopup() { return assetPopup; } public void setAssetPopup(RichPopup assetPopup) { this.assetPopup = assetPopup; } }
内容的提问来源于stack exchange,提问作者Shaik
相关产品推荐
相关产品推荐

