You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}

错误分析

  1. ID错误:JavaScript中硬编码的soc8是不存在的组件ID,实际SelectOneChoice的ID是soc7
  2. ADF组件ID机制:ADF会自动为表格行内的组件添加命名空间前缀(如pt1:r1:soc7),直接用document.getElementById无法正确获取组件实例
  3. 未利用ADF客户端API:ADF提供了专门的客户端组件API,无需直接操作DOM

解决方案

方案一:客户端JavaScript修正

使用ADF客户端API获取组件实例及选中值,无需依赖硬编码ID:

  1. 修改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>
  1. 修正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();
}

方案二:服务器端值变更监听器

如果需要在服务器端处理选中值后再触发弹窗,可使用服务器端监听器:

  1. 修改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>
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:48:20