Oracle Apex 21.1 如何为交互报表动态生成的按钮添加Dynamic Action
提问内容
基于我之前的动态值修改图标需求,我正在Oracle Apex (v21.1)上搭建一款仪表盘,用于展示各部门的库存状态。我在列表末尾添加了一个仅当状态为“Validated”(绿色行)时才会显示的按钮。

我的Interactive Report代码如下:
SELECT PK_DASHBOARD, FK_SERVICE_DASHBOARD, ETAT_DASHBOARD, DATE_DASHBOARD, CASE WHEN etat_dashboard = 1 THEN '<button>Libérer</button>' END as bt_dashboard, CASE WHEN etat_dashboard = 0 THEN '<a href="mailto:'||email_dashboard||'?Subject=RAPPEL - Inventaire communal"><span aria-label="Mail"><span class="fa fa-envelope-o" aria-hidden="true" title="Mail"></span></span></a>' WHEN etat_dashboard = 1 THEN '<span aria-label="Mail"><span class="fa fa-check-circle-o" aria-hidden="true" title="Mail"></span></span>' END as ico_dashboard FROM inv_tb_dashboard
我希望在用户点击该按钮时触发Dynamic Action,不清楚如何将Dynamic Action绑定到这种方式创建的按钮上:是使用类似getElementById的JavaScript函数实现,还是直接给按钮添加onClick=""属性?
我的Dynamic Action仅需执行服务端代码,例如UPDATE inv_tb_dashboard SET etat_dashboard = 0,逻辑并不复杂。
希望能够获得可行的实现思路,如需更多细节可以随时告知,谢谢。
Thomas
解决方案
给你两种在Oracle Apex 21.1中实现需求的可行方案:
方案1:事件委托绑定动态动作(推荐,符合Apex开发规范)
- 修改SQL查询,给按钮加专属标识
调整bt_dashboard列的CASE逻辑,给按钮添加自定义类名,同时把当前行主键存入data属性方便后续取值:
CASE WHEN etat_dashboard = 1 THEN '<button class="release-inventory-btn" data-pk="'||PK_DASHBOARD||'">Libérer</button>' END as bt_dashboard,
修改完成后,找到bt_dashboard列的属性设置,将转义特殊字符选项改为「否」,否则按钮会以文本形式展示。
- 创建动态动作
- 新建动态动作,触发条件选择「点击」,触发方式选择「jQuery选择器」,选择器内容填
.release-inventory-btn - 第一个真操作选择「设置值」,源类型选「JavaScript表达式」,填写代码
this.triggeringElement.dataset.pk,目标项选择你提前在页面创建的隐藏项(例如P1_SELECTED_PK) - 第二个真操作选择「执行服务器端代码」,填写更新逻辑:
同时在「要提交的项」里填写UPDATE inv_tb_dashboard SET etat_dashboard = 0 WHERE pk_dashboard = :P1_SELECTED_PK;P1_SELECTED_PK,确保主键值能传递到服务端 - 第三个真操作选择「刷新」,目标选你的Interactive Report区域,点击按钮后自动刷新报表更新状态
方案2:直接绑定onClick事件(实现更快捷)
- 修改SQL查询的按钮代码
直接给按钮添加onClick事件,传入当前行主键:
CASE WHEN etat_dashboard = 1 THEN '<button onclick="releaseInventory('||PK_DASHBOARD||')">Libérer</button>' END as bt_dashboard,
同样要把该列的转义特殊字符设为「否」。
- 添加页面级JS函数
打开页面属性,在「函数和全局变量声明」中添加如下代码:
function releaseInventory(pk) { apex.server.process( 'RELEASE_INVENTORY', {x01: pk}, { success: function() { // 替换为你自己的报表静态ID apex.region('INVENTORY_REPORT').refresh(); } } ) }
- 创建按需执行的服务端进程
新建页面级进程,名称填RELEASE_INVENTORY,进程点选「按需执行」,进程代码填写:
UPDATE inv_tb_dashboard SET etat_dashboard = 0 WHERE pk_dashboard = apex_application.g_x01;
注意事项
- 两种方案都建议给Interactive Report设置静态ID,方便刷新操作调用
- 可根据需求给服务端更新逻辑添加权限校验,避免越权操作
内容的提问来源于stack exchange,提问作者ThomasT
相关产品推荐
相关产品推荐

