2022年6月2日木曜日

表示のみアイテムの表示色を変更する

 タイプ表示のみのページ・アイテムの表示色を、入力値の条件によって変更するにはどうしたらよいか、という質問があったので実装してみました。

同じ結果が得られますが、3つの異なる実装方法を試してみます。

レベルには0から10までの値を入力します。ステータスとして、レベルが0-4までは緑で安全5-10赤で危険と表示します。


アプリケーション作成ウィザードを起動し、ホーム・ページのみを含む空のアプリケーションを作成します。名前表示のみアイテムの色付けとしました。

試験実装にはAlways FreeのAutonomous DatabaseのAPEX 21.2を使用しています。実装に使用している動的アクションのクライアント側の条件は、APEX 21.1から追加された機能であるため、それ以前のバージョンでは利用できません。コードによる実装では、ネームスペースapex.itemsを使っているため、APEX 21.2以降のバージョンでのみ動作します。

宣言的実装


レベルを入力するページ・アイテムとしてP1_LEVEL1ステータスを表示するページ・アイテムとしてP1_STATUS1を作成します。P1_STATUS1の表示は、P1_LEVEL1に設定する動的アクションで実行します。TRUEアクションにクライアント側の条件を設定することにより、レベルの入力値に依存して、表示を変更します。

リージョンを作成し、識別名前宣言的実装タイプ静的リージョンとします。

作成したリージョンに、ページ・アイテムP1_LEVEL1を作成します。識別タイプ数値フィールドラベルレベル設定最小値0最大値10数字の位置合せLeftにします。


続いて、ページ・アイテムP1_STATUS1を作成します。識別タイプ表示のみラベルステータスとします。ページの送信時に送信OFFにします。OFFの場合spanタグで囲まれたテキストとして値が生成されます。ONの場合はinputタグのvalue属性として値が設定されます。そのため、CSSクラスを設定しても効果がありません。


ページ・アイテムP1_LEVEL1に数値が入力されたときにP1_STATUS1の表示を決めるように、P1_LEVEL1に動的アクションを作成します。

作成した動的アクションの識別名前を、ステータスの設定1とします。タイミングは、イベント変更選択タイプアイテムアイテムP1_LEVEL1になります。


ステータス安全という文字列を設定するTRUEアクションを作成します。

識別アクションとして、値の設定を選択します。設定タイプの設定Static Assignment安全です。影響を受ける要素として、選択タイプアイテムアイテムとしてP1_STATUS1を指定します。これで、ページ・アイテムP1_STATUS1に安全という文字が設定されます。

実行オプション初期化時に実行ONにします。この設定によりページ・ロード時(ページ・アイテムP1_LEVEL1は変更されていない)に、このアクションが評価されます。実行されるかどうかは、この後に設定するクライアント側の条件に依存します。

クライアント側の条件タイプとしてアイテム < 値を選択し、アイテムP1_LEVEL15を設定します。このTRUEアクションは、P1_LEVEL1の値が5より小さいときに実行されます。


作成したTRUEアクションを重複させ、表示色を初期化するTRUEアクションに変更します。

識別アクションクラスの削除に変更し、設定クラスとしてu-dangerを指定します。それ以外の設定は、重複元の安全という文字を設定したTRUEアクションと同じです。


u-dangerはOracle APEXのUniversal Themeにて定義されているCSSクラスになります。標準で定義されている危険色を使用することにより、標準が変更されたときに、ここで指定した色も合わせて変更されます。

TRUEアクションを再度重複させます。設定アクションクラスの追加設定クラスu-successとします。これでアイテムの表示色が緑になります。

これらのTRUEアクションのクライアント側の条件はすべて同じく、P1_LEVEL1が5より小さいです。


反対に5以上のときに、ステータスを赤で危険と表示するTRUEアクションを作成します。

作成済みの3つのTRUEアクションを選択し、重複を実行します。


作成された3つのTRUEアクションのクライアント側の条件タイプを、アイテム >= 値に変更します。


重複したTRUEアクション値の設定の、設定を安全から危険へ変更します。


クラスの削除u-dangerからu-successへ変更します。


クラスの追加u-successからu-dangerへ変更します。


1つめの実装は以上で完了です。


コードによる実装



先ほどと同じ条件で、リージョンコードによる実装、ページ・アイテムP1_LEVEL2、ページ・アイテムP1_STATUS2を作成します。

リージョン宣言的実装重複させ、識別タイトルコードによる実装に変更します。レイアウト新規行の開始OFFにします。同時にコピーされたページ・アイテムP1_LEVEL1_1をP1_LEVEL2、P1_STATUS1_1をP1_STATUS2に変更します。動的アクションはコピーされません。


ページ・アイテムP1_LEVEL2に動的アクションを作成します。識別名前ステータスの設定2とします。作成する動的アクションは、ページ・アイテムP1_LEVEL1の設定と同様なので、スクリーンショットは割愛します。

作成するTRUEアクションJavaScriptコードの実行です。以下のコードを、設定コードに記述します。
if (apex.items.P1_LEVEL2.value < 5) {
    apex.items.P1_STATUS2.setValue("安全");
    apex.items.P1_STATUS2.element.removeClass("u-danger");
    apex.items.P1_STATUS2.element.addClass("u-success");
}
else
{
    apex.items.P1_STATUS2.setValue("危険");
    apex.items.P1_STATUS2.element.removeClass("u-success");
    apex.items.P1_STATUS2.element.addClass("u-danger");
}
実行オプション初期化時に実行ONにします。


以上で、実装は完了です。

見かけ上の動作は変わりませんが、大きな違いがあります。

宣言的にTRUEアクションを並べた場合、この通りの順番でTRUEアクションが実行/終了することは保証されません。そのため、実行の順番に関わらず、結果は同じになるようにTRUEアクションを定義する必要があります


 一塊のコードで記述している場合は、コードに記載された通りの順番で実行されます。実行順を保証したい場合は、JavaScriptのコードを記述する必要があります。


宣言的実装2


クライアント側の条件をTRUEアクションに設定する代わりに、動的アクションに設定することもできます。

コードによる実装のときと同様の準備を行い、リージョン宣言的実装2、ページ・アイテムP1_LEVEL3P1_STATUS3を作成します。

動的アクションの作成も同様に行いますが、クライアント側の条件を設定します。

識別名前ステータスの設定 - 安全とし、クライアント側の条件タイプアイテム < 値アイテムP1_LEVEL35とします。


もう一つ、動的アクションを作成します。

識別名前ステータスの設定 - 危険とし、クライアント側の条件タイプアイテム >= 値アイテムP1_LEVEL35とします。


それぞれの動的アクションに、同じ効果を得るためのTRUEアクションを作成します。動的アクションクライアント側の条件を設定するため、TRUEアクションにはクライアント側の条件は設定しません。


こちらの実装も以上で完了です。

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

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