暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

APEX 实战笔记:按钮切换报表查询条件

SQL干货分享 2021-08-13
360

(CSDN博主:写代码也要符合基本法)
各位看官老爷大家早上好,今天小刘来和大家分享一下最近开发 APEX 应用工作中遇到的一个比较有趣的需求

需求说明
需要开发的页面主体是一个展示不同生产线产能的报表,其源数据的结构是每条生产线在每个月都要设置好当月的产能,也就是说每行数据都代表某条生产线在某个月的产能,其月份以有效日期起/止两个字段体现
现在对于这个报表,希望通过页面上的一个按钮,能够一键切换其展示的数据:仅看当月或者查看全部数据两种模式

下面说明一下报表的源数据结构,本例使用视图 DEMO_LINE_CAPACITY_V 为数据源,主要所需字段如下
    SQL> SELECT line_name, max_kl_qty, effective_date_from, effective_date_to
    2 FROM demo_line_capacity_v;


    LINE_NAME MAX_KL_QTY EFFECTIVE_DATE_FROM EFFECTIVE_DATE_TO
    ------------ ---------- ------------------- -----------------
    奶茶1#线 3000 2020/10/1 2020/10/31
    奶茶2#线 3000 2020/10/1 2020/10/31
    可乐1#线 3000 2020/10/1 2020/10/31
    可乐2#线 3000 2020/10/1 2020/10/31
    咖啡1#线 3000 2020/10/1 2020/10/31
    咖啡2#线 3000 2020/10/1 2020/10/31
    奶茶1#线 5000 2020/11/1 2020/11/30
    奶茶2#线 5000 2020/11/1 2020/11/30
    可乐1#线 5000 2020/11/1 2020/11/30
    可乐2#线 5000 2020/11/1 2020/11/30
    咖啡1#线 5000 2020/11/1 2020/11/30
    咖啡2#线 5000 2020/11/1 2020/11/30


    12 rows selected
    方案分析
    我们首先分析一下切换报表模式在数据源 SQL 层面的实现方式,小刘选择在 SQL 中引用一个页面变量来实现不同的 WHERE 条件
    比如这个变量叫做 P20_REPORT_MODE,当它的值为 ALL 时,表示要查看全部数据;而当它的值为 CURR 时,表示仅查看本月的数据
    从而报表的数据源 SQL 就要这样写
      SELECT line_name, max_kl_qty, effective_date_from, effective_date_to
      FROM demo_line_capacity_v
      WHERE :p20_report_mode = 'ALL'
      OR :p20_report_mode = 'CURR'
      AND SYSDATE BETWEEN effective_date_from AND effective_date_to

      所以,所谓的“一键切换”,也就是添加一个按钮,使它在每次点击时,将变量的值在 ALL 和 CURR 之间切换即可

      另外,更细致一点,按钮还应该动态变换其标签:当前为查看全部数据模式时,按钮应该显式“仅看本月”;当前为仅看本月数据模式时,其标签应为“查看全部”

      开发实现
      1、采用 Interactive Grid 格式的区域来展示报表,并且在该区域创建一个 Page Item,即报表模式(P20_REPORT_MODE)
      P20_REPORT_MODE 的主要属性设置:
      IG 主要属性设置:
      这里请注意给 IG 规定了静态 ID 为 report,后面会用得到
      2、通过 IG 的 Attributes 中的初始化 JS 脚本来给工具条添加切换按钮
        function (config)
        {
        var $ = apex.jQuery,
        toolbarData = $.apex.interactiveGrid.copyDefaultToolbar(),
        resetButtonGroup = toolbarData.toolbarFind("actions4");

        //在“重置”按钮组添加切换按钮
        //由于按钮的标签将动态展示,故此处不设置icon等属性
        resetButtonGroup.controls.push(
        {
        type: "BUTTON",
        id: "mode", //请关注这个ID
        action: "modeBtnOnclick",
        hot: true
        });

        //绑定按钮的action
        //由于按钮的标签将动态展示,故此处不设置label等属性
        config.initActions = function (actions)
        {
        actions.add(
        {
        name: "modeBtnOnclick",
        action: modeBtnOnclick //为了代码简洁,我们将在页的全局JS中实现这个function
        });
        }

        config.toolbarData = toolbarData;

        return config;
        }

        这里需要注意的是,脚本中虽然指定 BUTTON 的 id 为“mode”,但实际上页面最终生成的这个按钮的 id 会有变化,下图将是我们在页面查看到的原码

        很显然 APEX 应用 IG 的静态 id 等元素将按钮的 id 进行了改造,实际上这个按钮的 id 为 report_ig_toolbar_mode,这个 id 也请关注,后面也会用到
        3、接下来我们在页面的全局 JS(JavaScript/Function and Global Variable Declaration)中实现按钮的功能
          function setBtnLabel()
          {
          var mode = $v("P20_REPORT_MODE");
          //改变按钮的标签
          //利用到按钮的id - report_ig_toolbar_mode
          //如果当前是“查看全部数据”模式,按钮应该显式“仅看本月”
          if (mode == "ALL") $("#report_ig_toolbar_mode").html('<span class="t-Icon t-Icon--right fa fa-search"></span>&nbsp;<span class="a-Button-label">只看本月</span>');
          //如果当前是“仅看本月数据”模式,按钮应该显式“查看全部”
          if (mode == "CURR") $("#report_ig_toolbar_mode").html('<span class="t-Icon t-Icon--right fa fa-reply"></span>&nbsp;<span class="a-Button-label">查看全部</span>');
          }


          function modeBtnOnclick()
          {
          var mode = $v("P20_REPORT_MODE");
          //模式切换,即将变量值在ALL和CURR之间切换
          if (mode == "ALL") $("#P20_REPORT_MODE").val("CURR");
          if (mode == "CURR") $("#P20_REPORT_MODE").val("ALL");
          //静态刷新IG
          //利用到IG的静态ID - report
          apex.region("report").refresh();
          //改变按钮标签
          setBtnLabel();
          }

          众所周知,APEX 是支持 jQuery 的,在实现按钮的触发功能 modeBtnOnclick 时,我们应用到了前面强调过的 IG 的静态 ID 和按钮在页面中的实际id

          4、不要忘了按钮初始化脚本中没有规定其标签,所以我们要在页面加载时便调用 setBtnLabel 功能来设置按钮的标签,具体的方法是在页面设置中的 JavaScript/Excute when Page Loads 中调用 setBtnLabel 即可
            setBtnLabel();

            那么为什么不在按钮初始化时就把标签设置成“只看本月”(对应参数默认值 ALL,即查看全部数据模式)呢?这是为了应对以后的需求变化,例如报表默认模式改变、增加更多报表筛选模式等情形,这些情况将来只需改动很少的地方即可实现了

            效果展示
            查看全部数据模式(默认)
            只看本月数据模式
            是不是肥肠的银杏化?

            文章转载自SQL干货分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论