対話モード・レポートの列にチェックボックスを配置し、その値をページを送信せずに更新するにはどうしたら?という相談がありました。APEX_ITEM.CHECKBOX2の使用を考えていて、その場合、ページを送信する必要があります。
ページを送信せずにデータベースに保存されているデータを更新するには、動的アクションを使えます。下のレイヤーで考えると、ページの送信はHTTPのPOSTリクエストの発行による更新、動的アクションはAjaxコールの発行による更新です。
ただし、動的アクションによる更新の場合、失われた更新の防止(Lost Write Protection)が行われません。
単に動的アクションで更新するだけであれば、それほど実装は難しくありません。ロスト・ライト・プロテクションについても実装してみようと思います。
以下の動作するアプリケーションを作成します。上の画面でチェックボックスをチェックしたり外したりします。すでに上の画面でデータを変更しているため、下の画面で同じ行のチェックボックスを操作しようとするとエラーが発生します。
エラーが発生したら、一旦、ページをリロードします。ページをリロードすると直前のデータベースの状態がレポートに反映されるため、チェックボックスの値を変更できます。下の画面でデータを更新すると、今度は上の画面でチェックボックスを操作しようするとエラーが発生します。
クイック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にデータを投入するために使用します。
以上でアプリケーションを作成します。
アプリケーションが作成されたら、ページ番号1のIRのページを開きます。
最初に対話モード・レポートのリージョンに静的IDを設定します。詳細の静的IDにstatementsと記述します。
列IS_APPROVEDには、データが文字のまま(YまたはN)表示されるようになっています。チェックボックスとして表示されるよう、以下のコードを列の書式のHTML式に記述します。チェックボックスの値が変更されるたびに、列ID、ROW_VERSIONとチェックボックスのステータスを含んだINPUT要素に紐づけた(CSSクラスdummychangeで紐づける)動的アクションが呼び出されます。
動的アクション・ビューを開き、動的アクションを作成します。
識別の名前はチェックボックスの値変更とします。
実行のイベント有効範囲を動的とし、静的コンテナ(jQueryセレクタ)には#statementsを指定します。これは対話モード・レポートのリージョンです。タイプは即時です。
タイミングのイベントは変更、選択タイプとしてjQueryセレクタを選択します。jQueryセレクタとして.dummychangeを指定し、列IS_APPROVEDのHTML式に記述したINPUT要素を指定します。
TRUEアクションとしてJavaScriptコードの実行を選択し、設定のコードに以下を記述します。Ajaxコールバックとして実装したUPDATE_CHECKBOXを呼び出します。引数x01に列ID、x02に列ROW_VERSION、x03にチェックボックスのステータスを渡し、Ajaxコールバックとして実装したプロセスUPDATE_CHECKBOXを呼び出します。
プロセス・ビューを開き、AjaxコールバックとしてプロセスUPDATE_CHECKBOXを作成します。ソースのPL/SQLコードとして以下を記述します。