2023年5月18日木曜日

対話モード・レポートの列を動的アクションで更新する

対話モード・レポートの列にチェックボックスを配置し、その値をページを送信せずに更新するにはどうしたら?という相談がありました。APEX_ITEM.CHECKBOX2の使用を考えていて、その場合、ページを送信する必要があります。

ページを送信せずにデータベースに保存されているデータを更新するには、動的アクションを使えます。下のレイヤーで考えると、ページの送信はHTTPのPOSTリクエストの発行による更新、動的アクションはAjaxコールの発行による更新です。

ただし、動的アクションによる更新の場合、失われた更新の防止(Lost Write Protection)が行われません。

単に動的アクションで更新するだけであれば、それほど実装は難しくありません。ロスト・ライト・プロテクションについても実装してみようと思います。

以下の動作するアプリケーションを作成します。上の画面でチェックボックスをチェックしたり外したりします。すでに上の画面でデータを変更しているため、下の画面で同じ行のチェックボックスを操作しようとするとエラーが発生します。

エラーが発生したら、一旦、ページをリロードします。ページをリロードすると直前のデータベースの状態がレポートに反映されるため、チェックボックスの値を変更できます。下の画面でデータを更新すると、今度は上の画面でチェックボックスを操作しようするとエラーが発生します。


アプリケーションで使用する表CBX_STATEMENTSを作成します。

クイックSQLの以下のモデルを使用します。
# prefix: cbx
# rowversion: true
# auditcols: true
statements
    message     vc80 /nn
    is_approved vc1  /nn /check Y,N /default N
ロスト・ライト・プロテクションの実装に、行バージョンを使用します。そのためクイックSQLのモデルにrowversion: trueを指定します。行バージョンの代わりにチェックサムを使うこともできますが、異なる実装になります。(APEXはロスト・ライト・プロテクションにチェックサムを使っています)保護対象をすべての列ではなく、一部の列に限定する場合はチェックサムによる実装が必要です。

クイックSQLでは表CBX_STATEMENTSの作成までを行い、アプリケーションの作成はしません。


表が作成されたら、アプリケーション作成ウィザードを起動します。

アプリケーションの名前Checkbox on IRとします。デフォルトで作成されているホーム・ページを削除し、代わりに対話モード・レポートのページIR対話グリッドのページIGを追加します。


対話モード・レポートのページ定義です。表またはビューとしてCBX_STATEMENTSを指定します。動的アクションによるデータの更新は、このページに実装します。


対話グリッドのページ定義です。対話グリッドは表CBX_STATEMENTSにデータを投入するために使用します。


以上でアプリケーションを作成します。

アプリケーションが作成されたら、ページ番号のIRのページを開きます。

最初に対話モード・レポートのリージョンに静的IDを設定します。詳細静的IDstatementsと記述します。


IS_APPROVEDには、データが文字のまま(YまたはN)表示されるようになっています。チェックボックスとして表示されるよう、以下のコードを列の書式HTML式に記述します。チェックボックスの値が変更されるたびに、列IDROW_VERSIONチェックボックスのステータスを含んだINPUT要素に紐づけた(CSSクラスdummychangeで紐づける)動的アクションが呼び出されます。



動的アクション・ビューを開き、動的アクションを作成します。

識別名前チェックボックスの値変更とします。

実行イベント有効範囲動的とし、静的コンテナ(jQueryセレクタ)には#statementsを指定します。これは対話モード・レポートのリージョンです。タイプ即時です。

タイミングイベント変更選択タイプとしてjQueryセレクタを選択します。jQueryセレクタとして.dummychangeを指定し、列IS_APPROVEDHTML式に記述したINPUT要素を指定します。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定コードに以下を記述します。Ajaxコールバックとして実装したUPDATE_CHECKBOXを呼び出します。引数x01に列IDx02に列ROW_VERSIONx03チェックボックスのステータスを渡し、Ajaxコールバックとして実装したプロセスUPDATE_CHECKBOXを呼び出します。



プロセス・ビューを開き、AjaxコールバックとしてプロセスUPDATE_CHECKBOXを作成します。ソースPL/SQLコードとして以下を記述します。



以上でアプリケーションは完成です。

アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/checkbox-on-ir.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。