実装が思ったよりも大変だったので、記事にしました。
サンプル・データセットのEMP/DEPTに含まれるEMP表をデータ・ソースとした対話グリッドと、フォームを作成しました。以下のように動作します。
対話グリッドを含むページのページ・プロパティに、対話グリッドで選択した行(の配列)を保持するための変数selectedIdsを宣言します。
JavaScriptのファンクションおよびグローバル変数の宣言に以下を記述します。
var selectedIds;
対話グリッドに静的IDとしてempを設定します。
イベントのダイアログのクローズを受けて、対話グリッドをリフレッシュするTRUEアクションは作成済みです。
リフレッシュの直前に、以下のJavaScriptのコードを実行するTRUEアクションを作成します。対話グリッドで選択されている行のID(主キーの値)の配列をselectedIdsに保存します。
const model = apex.region("emp").call("getViews", "grid").model;
selectedIds = model.getSelectedRecords().map(
(rec) => {
return model.getRecordId(rec);
}
);
// console.log(selectedIds);
対話グリッドのリフレッシュが完了した後に、selectedIdsに保存した行を選択した状態に戻します。
対話グリッドに動的アクションを作成します。タイミングのイベントはページ変更[対話グリッド]を選択します。ほとんどのリフレッシュ可能なコンポーネントは、イベントとしてリフレッシュ後を選べるのですが、対話グリッドではリフレッシュ後のイベントが発生しません。従って、それに近いイベントとしてページ変更を使います。
また、実行のタイプとしてデバウンスを選択し、ページ変更のイベントが発生してから100ミリ秒待機したのちに処理を開始するように設定します。100ミリ秒というのは、人が気が付かないほどの短時間で、かつ、JavaScriptの処理が空振りしない程度の時間として選んでいます。
TRUEアクションとして実行するJavaScriptコードは以下になります。行の選択はfetchRecordsの処理が完了した後に実行するようにしています。
// console.log('after', selectedIds);
const model = apex.region("emp").call("getViews", "grid").model;
model.fetchRecords(
apex.region("emp").call("setSelectedRecords", selectedIds)
);
以上で実装は完了です。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/preserve-selection.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完