原因と対処方法について紹介します。
最初に検証に使用する簡単なアプリケーションを作成します。
アプリケーション作成ウィザードを起動します。アプリケーションの名前はDialog Close Eventとします。
ホーム・ページは削除し、サンプル・データセットのEMP/DEPTに含まれる表EMPをソースとした、対話モード・レポートとフォームのページを追加します。
対話モード・レポートのページ名はEMPとし、表またはビューとしてEMPを選択します。フォームを含めるにチェックをいれ、ページの追加を行います。
以上で、アプリケーションを作成します。
ページ・デザイナで、ページ番号1の表EMPの対話モード・レポートのページを開きます。
動的アクションでフォームを開く実装を追加します。
フォームを開くURLを保持するページ・アイテムとしてP1_URLを作成します。
一般的な実装ではタイプとして非表示を選択しますが、今回は検証なのでテキスト・フィールドを選択します。
フォームを開くボタンとしてOPENを作成します。動作のアクションとして動的アクションで定義を選択します。
ボタンOPENに動的アクションを作成します。
識別の名前をonClick OPENとします。タイミングのイベントはデフォルトのクリックです。
最初のTRUEアクションで、フォームを開くためのURLを生成します。
アクションとしてサーバー側のコードを実行を選択し、設定のPL/SQLコードとして以下を記述します。
:P1_URL := apex_page.get_url(p_page => 2, p_items => 'P2_EMPNO', p_values => :P1_EMPNO);
追記: 以下のようにapex_page.get_urlの引数p_triggering_elementとして対話モード・レポートの静的IDを指定すると、JavaScriptによるワークアラウンドは不要でした。
:P1_URL := apex_page.get_url(p_page => 2, p_items => 'P2_EMPNO', p_values => :P1_EMPNO, p_triggering_element => 'emp');
送信するアイテムとしてP1_EMPNOを指定し、戻すアイテムとしてP1_URLを指定します。
ボタンのアクションとしてこのアプリケーションのページにリダイレクトを選択してフォームを開く場合は、ページが表示された時点でのページ・アイテムの値が引数となります。ページ表示後に変更したページ・アイテムの値を引数とすることはできないため、このような場合は、動的アクションとして実装します。
実行の結果を待機はかならずオンにします。初期化時に実行する必要は無いので、これはオフにします。
ページ・アイテムP1_URLとして設定されたページを開くTRUEアクションを作成します。
アクションとしてJavaScriptコードの実行を選択し、設定のコードとして以下を記述します。
apex.navigation.redirect(apex.items.P1_URL.value);
以上でアプリケーションを実行します。
Empnoとして7788を入力し、ボタンOPENをクリックします。
指定した従業員番号でフォームが開きます。動的アクションは適切に実装されていることがわかります。
Commissionなどを変更し、変更の適用をクリックします。
変更の適用をクリックするとフォームが閉じますが、対話モード・レポートがリフレッシュされないため、変更した値がレポートに反映されません。
このようになる理由は、ダイアログのクローズに登録されている動的アクションとファンクションapex.navigation.dialog(apex.theme42.dialog)呼び出し時のイベントのターゲットの不一致にあります。
ページ作成ウィザードで対話モード・レポートとフォームのページを作成すると、レポートの編集 - ダイアログのクローズという名前で、レポートをリフレッシュする動的アクションが作成されます。
この動的アクションのタイミングの選択タイプとしてリージョン、リージョンとして対話モード・レポートのリージョンであるEmployeesが選択されています。
ページ・アイテムP1_URLに実際にフォームを開くURLが設定されています。こちらを確認すると、以下のようになっています。
javascript:apex.theme42.dialog('\u002Fords\u002Fr\u002Fapexdev\u002Fdialog-close-event\u002Femployee?p2_empno=7788\u0026session=107992989464019\u0026cs=3mbMpJtQdUFyCb1YAXSH6hLtMuzCcsW93-WP8d5oMfp9J5S4Dw5nDFMEHLvOPgfUVORO3IxljtqC_NTpKInotEw\u0026dialogCs=kwCn_71eCWwNlEi-AzXtGDzAVWhhenYNbvXNDRUKCKLRDluOCNLUMotdGi_ZlKcPv5qzmDil0lWfd4yV41Z1bA',{title:'Employee',w:'720',mxw:'960',modal:true,dialog:null,dlgCls:'t-Drawer-page--standard '+''},' js-dialog-class-t-Drawer--pullOutEnd',this)
JavaScript APIのapex.theme42.dialogを呼び出していますが、APIリファレンスのapex.navigation.dialogを同等なので、以下のリファレンスを参照します。
https://docs.oracle.com/en/database/oracle/apex/23.1/aexjs/apex.navigation.html#.fn:dialog
第4引数のpTriggeringElementに指定されたHTML要素にapexafterclosedialog、apexafterclosecanceldialogのイベントが発行されると記載されています。つまり、動的アクションのタイミングとして設定されている要素がpTriggeringElementとして指定されていないと、ダイアログのクローズとして作成されている動的アクションは動作しません。
以上より、ページ・アイテムP1_URLとして生成されたJavaScriptを実行する際のthisを、対話モード・レポートのリージョンEmployeesとなるようにします。
色々な方法があるとは思いますが、今回はcallを使ってみます。
pTriggeringElementとして指定するために、対話モード・レポートのリージョンに静的IDとしてempを設定します。
ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言として、以下を記述します。
function openDialog(url) {
eval(url);
}
openDialog.call(apex.jQuery("#emp"),apex.items.P1_URL.value);
以上で対応は完了です。
フォームをクローズしたときにレポートがリフレッシュされるようになりました。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/dialog-close-event.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
追記
フォームのページにあるプロセスダイアログを閉じるの設定の戻すアイテムに、値を戻すページ・アイテムをカンマ区切りで複数設定します。今回の例ではP2_ENAME,P2_JOBとしています。
レポートのページに、フォームから戻されたページ・アイテムの値を保持するページ・アイテムP1_ENAMEとP1_JOBを作成しておきます。
イベントがダイアログのクローズのときに実行されるTRUEアクションを作成します。