テンプレート・ディレクティブを使った設定ではなく、JavaScriptで単一行ビューの項目の色を変更する処理を実装してみました。部門番号(DEPTNO)に依存して従業員名(ENAME)の色を変更します。こちらの記事で作成したアプリケーションに機能を追加しています。
実装はしてみましたが、テンプレート・ディレクティブを使った方が実装としては良いでしょう。JavaScriptによるカスタム実装の場合、現状で年に2回発生するOracle APEXのアップデートの際に、毎回処理に影響がないことを確認しないといけません。
そういった点は置いておいて、せっかく調べたので純粋に技術的な観点で実装方法を紹介します。
動的アクションによる実装
単一行ビューに切り替わる場合、大抵は行が選択されています。なので、選択の変更のタイミングで動的アクションを実行します。
最初に対話グリッドに静的IDを設定します。静的IDはempとします。
TRUEアクションはJavaScriptコードの実行とします。設定のコードには以下を記述します。
let view =
apex.region("emp").widget().interactiveGrid("getCurrentView");
if (view.singleRowMode) {
let model = this.data.model;
let record = this.data.selectedRecords[0];
let deptno = model.getValue(record, "DEPTNO");
let elem = this.triggeringElement;
let enameElems = elem.getElementsByClassName("u-bold");
if (enameElems.length == 1) {
switch(deptno) {
case '10':
if (enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.remove("u-success-text");
}
if (enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.remove("u-warning-text");
}
if (! enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.add("u-danger-text");
}
break;
case '20':
if (enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.remove("u-success-text");
}
if (enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.remove("u-danger-text");
}
if (! enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.add("u-warning-text");
}
break;
case '30':
if (enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.remove("u-warning-text");
}
if (enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.remove("u-danger-text");
}
if (! enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.add("u-success-text");
}
break;
}
}
}
アクションの入れ替えによる実装
グリッド・ビューで行を選択した後に単一行ビューに切り替えると(グリッド・ビューで選択したときにすでにイベントが発生しているため)、選択の変更[対話グリッド]のイベントが発生しません。動的アクションが実行されないと列ENAMEに色が付かず、黒で表示されます。その状況を補完するため、単一行ビューへの切り替えを行のアクション・メニューから呼び出したときに、列ENAMEに色をつける処理も同時に実行します。
ページ・プロパティのJavaScriptのページ・ロード時に実行に、以下のコードを記述します。
let view = apex.region("emp").widget().interactiveGrid("getViews", "grid"),
menu$ = view.rowActionMenu$;
// 行メニューの設定をかえる 。
menu$.menu("option").items[0] =
{
type:"action",
label:"Alt Single Row View",
action: function(menu, element) {
// 最初に単一行ビューに切り替える。
apex.region( "emp" ).widget().interactiveGrid( "getActions" ).invoke( "single-row-view" );
// 単一ビューに切り替えた後は、すべてPureなJavaScriptによるDOMの操作を行なう。
let elem = document.getElementById("emp");
let enameElems = elem.getElementsByClassName("u-bold");
let deptnoElems = elem.getElementsByClassName("this-deptno");
let deptnoValElems = deptnoElems[0].getElementsByClassName("a-RV-fieldValue");
let deptno = deptnoValElems[0].innerText;
if (enameElems.length == 1) {
switch(deptno)
{
case '10':
if (enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.remove("u-success-text");
}
if (enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.remove("u-warning-text");
}
if (! enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.add("u-danger-text");
}
break;
case '20':
if (enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.remove("u-success-text");
}
if (enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.remove("u-danger-text");
}
if (! enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.add("u-warning-text");
}
break;
case '30':
if (enameElems[0].classList.contains("u-warning-text")) {
enameElems[0].classList.remove("u-warning-text");
}
if (enameElems[0].classList.contains("u-danger-text")) {
enameElems[0].classList.remove("u-danger-text");
}
if (! enameElems[0].classList.contains("u-success-text")) {
enameElems[0].classList.add("u-success-text");
}
break;
}
}
}
};
部門番号の値を取り出すために、列DEPTNOのfieldCssClassesとしてthis-deptnoを設定しています。
以上で実装は完了です。アプリケーションを実行すると最初のGIF動画のように動きます。
今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/singlerowview-javascript.sql
実装を推奨しているわけではありませんが、Oracle APEXのアプリケーション作成の参考になれば幸いです。
完