対応バージョン

  • Oracle APEX 19.1 – 19.2

更新履歴

  • 2019/11/27: 新規投稿

こんにちは!代表の亀井です。

最近APEXユーザー会の記事を書いていなくて申し訳ないのですが、Oracle APEXの新機能や、機能の例、導入事例が紹介されています。前回は以前もセッションをして下さった、Oracle APEX 開発チームのShakeebさん、Christinaさんがいらっしゃって、新機能についてお話頂きました。19.2ではファセット検索が大きな機能としてありましたが、 私としては 標準でオリジナルのロゴ表示に対応したのが地味にうれしかったです。

Oracle APEXの最新技術が気になる方は是非参加ください。ちなみに私は毎回出ています!
https://orclapex-jp.connpass.com/

前段が長くなりましたが、本題のクラシック・レポート(又は対話モード・レポート)にボタンを追加する件について記載したいと思います。試した環境はOracle APEX 19.1ですが、基本的に前後のバージョンで動くと思いますので、参考にしてみてください。

ボタン動作の概要

今回実施する方法では、レポートの1つの列をボタン用の列として定義します。列のタイプをリンクとしてjavascript:void(0);を定義し、CSSでボタンのように見せます。このままだと何も動作しませんが、HTMLタグに特定のclassを定義し、動的アクションで操作します。( classに指定した値のイベントをリスニングします。aタグをクリックした時に、特定のclassに対して動的アクションが動作し、PL/SQL等を動かします。)

サンプルの準備

今回はDYNAMIC_A_TESTという動作確認用テーブルを作成します。削除フラグの列 (IS_DELETED) を定義し、フラグのON/OFFを実行してみます。
Create table文をAPEXでよく見るシーケンス、トリガーとのセットで以下に記載します。

CREATE SEQUENCE "DYNAMIC_A_TEST_SEQ"
  MINVALUE 1 MAXVALUE 9999999999999999999999999999
  INCREMENT BY 1 START WITH 1 CACHE 20
  NOORDER NOCYCLE NOKEEP
/

CREATE TABLE "DYNAMIC_A_TEST" (
    "ID" NUMBER
  , "COL1" VARCHAR2(100)
  , "IS_DELETED" VARCHAR2(3)
  , CONSTRAINT "DYNAMIC_A_TEST_PK" PRIMARY KEY ("ID")
  USING INDEX  ENABLE
)
/

CREATE OR REPLACE EDITIONABLE TRIGGER  "BI_DYNAMIC_A_TEST" 
  before insert on "DYNAMIC_A_TEST"               
  for each row  
begin   
  if :NEW."ID" is null then 
    select "DYNAMIC_A_TEST_SEQ".nextval into :NEW."ID" from sys.dual; 
  end if; 
end;
/

ALTER TRIGGER  "BI_DYNAMIC_A_TEST" ENABLE
/

上記にて作成したテーブルを基に、フォーム付きのクラシック・レポート又は対話モード・レポートを作ってください。ここについては割愛します。

ページ・デザイナの設定

1.一時的にPKを保存するアイテムの追加

レポートページに 以下のアイテムを追加します。

Pn_DELETE_TEMP_ID
識別 > タイプ: 非表示
設定 > 保護された値 : いいえ

2.ソースの設定

レポートのソースをSQLとして以下のように変更します。

select "ID"
     , decode("IS_DELETED"
          , 'YES', '元に戻す'
          , '削除する'
       ) as "IS_DELETED"
     , decode("IS_DELETED"
          , 'YES', 'recoverRowData'
          , 'deleteRowData t-Button--danger'
       ) as "CLASS_ACTION"
      , "COL1"
  from "DYNAMIC_A_TEST"

3.レポート列の設定

IS_DELETED

識別 > タイプ: リンク
リンク > ターゲット:
タイプ: URL
URL: javascript:void(0);
リンク > リンク・テキスト: #IS_DELETED#
リンク > リンク属性 : data-id=”#ID#” class=”#CLASS_ACTION# t-Button t-Button–stretch”

javascript:void(0)により、リンクの無効化を行い、リンク属性にプライマリキー( data-id=”#ID#” )と動的アクションと紐づけるclassの値( #CLASS_ACTION# )を定義します。

CLASS_ACTION

識別 > タイプ: 非表示

classに指定する値以外で利用していないため、非表示としておきます。

4.動的アクションの設定

最後に動的アクションを設定します。

ソースで設定しているSQLのCLASS_ACTIONに合わせて動的アクションを設定します。以下ソースに記載したSQLの対象列抜粋部分ですが、IS_DELETEDがYESの場合はrecoverRowData、それ以外はdeleteRowData のクラスが生成されるように設定しています。(IS_DELETED列の リンク > リンク属性 で設定していた内容)

 , decode("IS_DELETED"
      , 'YES', 'recoverRowData'
      , 'deleteRowData t-Button--danger'
   ) as "CLASS_ACTION"

削除する(削除フラグをYESにする)動的アクション

まずは deleteRowData の動的アクションから作成します。この動的アクションでは、削除フラグをYESに変更します。
以下の画面のように動的アクションタブへ移動し、適当に動的アクションを作成します。 (動的アクションは既に作成済みの画面となります。)
ここでは、値の設定(PKの取得)、PL/SQLコードの実行(値のアップデート)、リフレッシュ(レポートの更新)を定義します。

作成した動的アクションには以下の値を設定します。
識別 > 名前: deleteRowData
タイミング > イベント: クリック
タイミング > 選択タイプ: jQueryセレクタ
タイミング > jQueryセレクタ : .deleteRowData
詳細 > イベント有効範囲: 動的

タイミング > jQueryセレクタ は頭にドット(.)がついていますので、注意してください。また、詳細 > イベントの有効範囲を動的にしないと、レポートのリフレッシュ後にjQueryセレクタの追跡(jQueryイベントのリスニング)が出来ずに、ボタンが動作しなくなります。必ず動的にしてください。

各Trueアクションについて以下のように定義します。

識別 > アクション: 値の設定
設定 > タイプの設定: Javascript Expression
設定 > JavaScript式: $(this.triggeringElement).data(‘id’)
影響を受ける要素 > 選択タイプ : アイテム
影響を受ける要素 > アイテム: Pn_DELETE_TEMP_ID
実行オプション > 初期化時に実行: いいえ

識別 > アクション: PL/SQLコードの実行
設定 > PL/SQLコード: update “DYNAMIC_A_TEST” set “IS_DELETED” = ‘YES’ where “ID” = :”Pn_DELETE_TEMP_ID”;
設定 > 送信するアイテム: Pn_DELETE_TEMP_ID
実行オプション > 初期化時に実行: いいえ

識別 > アクション: リフレッシュ
影響を受ける要素 > 選択タイプ : リージョン
影響を受ける要素 > リージョン: ..Dynamic A Test
実行オプション > 初期化時に実行: いいえ

削除から元に戻す動的アクション

次にrecoverRowData の動的アクションを作成します。削除フラグをYESにしたデータをNOにします。削除の場合と同じような動作となります。

識別 > 名前: recoverRowData
タイミング > イベント: クリック
タイミング > 選択タイプ: jQueryセレクタ
タイミング > jQueryセレクタ : .recoverRowData
詳細 > イベント有効範囲: 動的

各Trueアクションについて以下のように定義します。

識別 > アクション: 値の設定
設定 > タイプの設定: Javascript Expression
設定 > JavaScript式: $(this.triggeringElement).data(‘id’)
影響を受ける要素 > 選択タイプ : アイテム
影響を受ける要素 > アイテム: Pn_DELETE_TEMP_ID
実行オプション > 初期化時に実行: いいえ

識別 > アクション: PL/SQLコードの実行
設定 > PL/SQLコード: update “DYNAMIC_A_TEST” set “IS_DELETED” = ‘NO’ where “ID” = :”Pn_DELETE_TEMP_ID”;
設定 > 送信するアイテム: Pn_DELETE_TEMP_ID
実行オプション > 初期化時に実行: いいえ

識別 > アクション: リフレッシュ
影響を受ける要素 > 選択タイプ : リージョン
影響を受ける要素 > リージョン: ..Dynamic A Test
実行オプション > 初期化時に実行: いいえ

5.設定のパフォーマンス向上について

jQueryセレクタを設定する際に、イベント有効範囲を動的 と設定した場合、静的IDの指定する項目が出ます。複数のレポートを1ページに表示するなどしている場合、こちらの項目に静的IDを設定することで、イベントのリスニング対象を絞り、パフォーマンスが向上できます。レポート・リージョンに設定した静的IDの値を登録します。(列ではなくレポート・リージョン側の静的IDとなります。また、動的アクション側に記載する静的IDは、#staticReportのように頭に#を付けて指定します。)