Cognos报表复选框联动取消选中的JavaScript问题排查
Cognos报表复选框联动JS问题排查与解决
问题背景
在Cognos报表中,有两个复选框提示:ChoicesIndicator1_VALUE和ChoicesIndicator1_VALUE_b1,需求是当第一个复选框被取消选中时,第二个复选框同步取消选中。因原生功能无法实现,采用JavaScript开发,但遇到以下问题:
初始代码问题
初始代码逻辑判断可正常执行,但myList.checked = false;语句无效(替换为alert("hello");可正常弹窗),同时希望优先通过提示名称而非ID关联元素。
初始代码:
<script> var form = getFormWarpRequest(); var myList = form._oLstChoicesIndicator1_VALUE var myListb1 = form._oLstChoicesIndicator1_VALUE_b1 myList.onclick = function() {myFunction()}; function myFunction() { if(myList.checked == true) { myList.checked = false; } } </script>
2024年5月7日更新:方案仍未生效
尝试修改后的代码如下,点击第一个复选框时弹窗正常,但复选框无法取消选中,且第二个复选框也未同步取消:
<script> var form = getFormWarpRequest(); var myList = form._oLstChoicesIndicator1_VALUE; var myListb1 = form._oLstChoicesIndicator1_VALUE_b1; myList.onclick = function() {myListOnclick()}; function myListOnclick() { myListb1.checked = false; } </script>
Cognos生成的两个复选框HTML代码:
第一个复选框:
<input name="pOpt_N00000183677D8300x000001835420DB38_NS_" id="N00000183677D8300x000001835420DBE8_NS_" type="checkbox" role="checkbox" value="EVOL" dv="% evol" class="dijitCheckBoxInput" onclick="return PRMTUtils.F_OnChange(event, this);" onkeypress="return PRMTUtils.F_OnChange(event, this);" onfocus="return PRMTUtils.f_CheckboxOnFocus(this);" onblur="return PRMTUtils.f_CheckboxOnBlur(this);" tabindex="0" aria-checked="true">
第二个复选框:
<input name="pOpt_N00000183677D8300x000001835420E168_NS_" id="N00000183677D8300x000001835420E1C0_NS_" type="checkbox" role="checkbox" value="YES" dv="Block 1" class="dijitCheckBoxInput" onclick="return PRMTUtils.F_OnChange(event, this);" onkeypress="return PRMTUtils.F_OnChange(event, this);" onfocus="return PRMTUtils.f_CheckboxOnFocus(this);" onblur="return PRMTUtils.f_CheckboxOnBlur(this);" tabindex="0" aria-checked="false">
解决方案
核心问题分析
Cognos的复选框基于Dojo框架渲染,直接修改checked属性会被Cognos自带的PRMTUtils.F_OnChange事件覆盖;同时原生DOM元素的状态需要同步Dojo组件状态才能生效。另外,直接绑定onclick事件会和Cognos内置事件冲突,导致状态无法正确更新。
代码实现
方法1:通过提示名称关联(优先方案)
利用Cognos提示API获取提示对象,操作对应的复选框组件:
<script> // 等待Cognos页面完全加载 document.addEventListener('DOMContentLoaded', function() { // 获取第一个提示对象 var prompt1 = cognos.Report.getReport("_THIS_").getPromptByName("ChoicesIndicator1_VALUE"); // 获取第二个提示对象 var prompt2 = cognos.Report.getReport("_THIS_").getPromptByName("ChoicesIndicator1_VALUE_b1"); // 监听第一个提示的变化事件 prompt1.addEventListener("change", function() { var values = prompt1.getValues(); // 当第一个复选框被取消选中(值为空) if (values.length === 0) { // 清空第二个复选框的选中值 prompt2.setValues([]); // 触发第二个提示的变化事件,同步Cognos内部状态 prompt2.fireEvent("change"); } }); }); </script>
方法2:通过DOM元素关联(备选方案)
如果提示名称方式失效,可通过DOM元素的dv属性(显示值)定位,调用Dojo API更新状态:
<script> // 等待Dojo和Cognos加载完成 require(["dojo/query", "dojo/domReady!"], function(query) { // 通过dv属性定位第一个复选框的Dojo组件 var checkbox1 = query('input.dijitCheckBoxInput[dv="% evol"]')[0]; // 通过dv属性定位第二个复选框的Dojo组件 var checkbox2 = query('input.dijitCheckBoxInput[dv="Block 1"]')[0]; if (checkbox1 && checkbox2) { // 获取Dojo复选框实例 var dijitCheckbox1 = dijit.byNode(checkbox1); var dijitCheckbox2 = dijit.byNode(checkbox2); // 监听第一个复选框的变化 dijitCheckbox1.on("change", function(isChecked) { if (!isChecked) { // 取消第二个复选框的选中状态 dijitCheckbox2.set("checked", false); } }); } }); </script>
关键说明
- 必须等待Cognos/Dojo完全加载后再执行代码,否则无法获取正确的提示对象或DOM元素;
- 直接操作原生DOM的
checked属性无效,需通过Cognos提示API或Dojo组件API更新状态,确保同步Cognos内部报表参数; - 避免直接覆盖Cognos内置的
onclick事件,改用change事件监听,避免事件冲突。
内容的提问来源于stack exchange,提问作者user26041991
相关产品推荐
相关产品推荐

