2021年11月26日金曜日

Oracle APEX 21.2新機能(0) - まとめ

 今まで書いたOracle APEX 21.2の新機能に紹介記事です。

1. ドロワー

ドロワーというページ・テンプレートおよびリージョン・テンプレートについて。

2. マルチバリュー・ファセット

ファセット検索またはスマート・フィルタのページで利用可能になった、複数値の検索条件の指定について。

3. ファセット検索の改善

ファセット名の表示とアイコンの設定について。

4. アラートとダイアログの改善

ボタン押下時にアラートまたはダイアログをポップアップさせる方法について。

 5. ダイアログを取り消したときのイベント

ダイアログをクローズしたときに発出される、閉じられたか取り消されたダイアログ(Dialog Closed or Canceled)のイベントの使い方について。

6.  環境バナー

環境バナーを表示させ、開発環境を識別する方法について。


検索コンポーネント、スマート・フィルタについて。

8. 新しいコンポーネントの配置方法

刷新されたページ・アイテムやボタンなどのコンポーネントの配置方法について。

9. 対応言語の追加

31ヶ国語に対応が増えたアプリケーションの翻訳について。

10. SAMLサインイン

追加されたSAML認証スキームについて。

 11. 地図関連の拡張

地図を表示するページ・アイテム、ミニマップ、ジオコーディングの機能について。

12. REST関連の拡張

RESTソース・カタログと簡易HTTPのページ区切りのサポートについて。

13. データ・パッケージ

サポートするオブジェクトとしてデータを含めるデータ・パッケージャについて。

14. 電子メール関連の拡張

電子メール送信プロセスにてテンプレートが利用可能になった。また、電子メールの翻訳にも対応。

15. レポートの拡張

 PDF、XLSXおよびHTML出力へのイメージの埋め込み、その他について。

16. PWAのサポート

PWA(Progressive Web App)のサポートについて。

17.  追加されたAPEX_DEBUGのAPI

get_page_view_id、get_last_message_idを使った外部ログとのリンクについて。

18. ポップアップLOVの拡張

動的アクションでポップアップLOVの表示値と追加値を更新する方法について。

19. 日付ピッカーの表示条件

日付ピッカーを表示するタイミングを制御する方法について。

20. コピーライト・バナー

アプリケーションのエクスポートにコピーライトの記載を含める方法について。

21. 開発ツールの機能追加

静的ファイルのエディタについて。ブレッドクラムの編集画面について。

22. JavaScript APIの追加

ネームスペースapex.env、apex.items、apex.regionsの使い方、およびライブラリapex.dateについて。

23. その他

Template Directiveのif条件の拡張および、いくつかのセキュリティ面での変更について。 

参考にした情報です。

apex.oracle.comの新機能紹介

Oracle APEX 21.2 Release Note

Oracle APEX 21.2 App Builder User's Guide

asktom.oracle.comのOffice Hoursの録画

オーストリアのFOEXが提供しているapexdiff.foex.atのサイト

カナダのInsumの記事 - Oracle APEX 21.2 10 New Features We Love

YouTubeのOracle APEXのチャンネル

この他に海外のAPEXのエキスパートによるブログ記事なども参考にしています。

以上です。



Oracle APEX 21.2新機能(23) - その他

 Oracle APEX 21.2の新機能およびその他の変更で、気に留まったものを紹介します。

テンプレート・ディレクティブの条件追加

Oracle APEX 21.2までのテンプレート・ディレクティブのifの条件はページ・アイテムまたは列の値が、空文字列ではなく、かつ、F、N、0の文字列でもないときに真と評価されました。Oracle APEX 21.2よりおよびのプレフィックス・オペレータが追加されています。

{if P2_COND/}
   P2_CONDの条件では、&P2_COND.は空文字列ではなくN0Fでもないので印刷される。<br>
{endif/}
{if =P2_COND/}
   =P2_CONDの条件では、&P2_COND.はN0Fではないので空文字列でも印刷される。<br>
{endif/}
{if ?P2_COND/}
   ?P2_CONDの条件では、&P2_COND.は空文字列ではないので印刷される。<br>
{endif/}

=オペレータはページ・アイテムまたは列の値がN、0、F以外であれば、空文字列を含め真となります。つまり真偽値だけを検証します。

?オペレータはページ・アイテムまたは列の値が空文字列以外であれば真となります。N、0、Fであっても条件としては真になります。つまり空文字列かどうかだけを検証します。

P2_CONDとしてAが渡されると、上記のスクリプトは以下を印刷します。

P2_CONDの条件では、Aは空文字列ではなくN0Fでもないので印刷される。
=P2_CONDの条件では、AはN0Fではないので空文字列でも印刷される。
?P2_CONDの条件では、Aは空文字列ではないので印刷される。

F(または0、N)を渡した場合は以下になります。

?P2_CONDの条件では、Fは空文字列ではないので印刷される

空文字列の場合は以下になります。

=P2_CONDの条件では、はN0Fではないので空文字列でも印刷される。

空文字列とN、0、Fといった真偽値の判定を異なる条件として扱えるようになり、条件設定が容易になっています。

POSTリクエストに問い合わせ引数p_contextを追加

ORDSにアクセス・ログを出力する設定を追加し、POSTリクエストのURLを確認してみます。アクセス・ログを出力する設定については、こちらの記事が参考になります。

フォームの送信でのログは以下のようになっています。簡易URLはONです。

10.0.2.2 - - [26/Nov/2021:04:25:12 +0000] "POST /ords/xepdb1/wwv_flow.accept?p_context=employees/employee/8528313532441 HTTP/1.1" 200 101

Ajaxのリクエストの場合は以下です、

10.0.2.2 - - [26/Nov/2021:04:25:13 +0000] "POST /ords/xepdb1/wwv_flow.ajax?p_context=employees/employees-report/8528313532441 HTTP/1.1" 200 22038

簡易URLがOFFの場合の例です。

10.0.2.2 - - [26/Nov/2021:04:24:07 +0000] "POST /ords/xepdb1/wwv_flow.accept?p_context=4550:1:8705366998123 HTTP/1.1" 302 0

GETリクエストの場合はアプリケーション名(もしくはID)、ページ名(または番号)およびセッションIDがURLに含まれていました。POSTやAjaxはそうではなかったのですが、これからはURLから呼び出し元を確認できます。

アクセス・ログの解析が、今までより容易になりました。

新規ページ作成時のページ・アクセス保護のデフォルト値

新規にページを作成したときのページ・プロパティページ・アクセス保護の値が引数にチェックサムが必要になりました。今までは制限なしだったので、デフォルト値がより安全な設定になっています。


apex.util.escapeHTMLAttrの追加

これまでJavaScript APIとしてapex.util.escapeHTMLがありましたが、より多くの特殊文字をエスケープの対象とするapex.util.escapeHTMLAttrが追加されました。英数字とカンマ、ピリオド、ダッシュ、アンダースコア以外はエスケープされます。

例えば、!#$%&をそれぞれエスケープすると、結果は以下になります。

apex.util.escapeHTML("!#$%&");

'!#$%&amp;'

apex.util.escapeHTMLAttr("!#$&");

'&#x21;&#x23;&#x24;&#x26;'

クロスサイト・スクリプティングに対応するために追加されたファンクションになります。HTMLの属性となる文字列は、apex.util.escapeHTMLAttrを呼び出してエスケープすることが推奨されています。

リリース・ノートなどの記載から気に留まった変更点は以上になります。

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

Oracle APEX 21.2新機能(22) - JavaScript APIの追加

 Oracle APEX 21.2で追加されたJavaScript APIについて紹介します。リリース・ノートの記載はこちらです。

追加されたネームスペースは以下です。apex.envapex.itemsapex.regionsはJavaScript APIのドキュメントのNamespacesの一覧ではなく、apexPropertiesに記載があります。apex.pwaについては、PWAの説明で触れています。

JavaScript APIのリファレンスに追加されたインターフェースは以下です。
ただ、インターフェース(およびそれを実装しているウィジェット)についてはそもそもJavaScript APIリファレンスに記載されていないものが多数あります。リージョンのインターフェースについては、それぞれのリージョンのカスタマイズ(例えば対話グリッドやファセット)方法を紹介する際に取り上げたいと思います。

以下より、ネームスペースとして追加されたAPIについて確認してみます。

apex.env


ブラウザのJavaScriptコンソールを開き、apex.envのネームスペースに含まれるプロパティを確認します。


APP_USER(サインインしているユーザー名)、APP_FILES(静的アプリケーション・ファイルへのパス)といった値を参照することができます。コード・エディタでの補完の対象になります。

アプリケーション・ビルダーのマニュアルに記載がありますが、システムが提供している置換文字列の名称が更新されています。apex.envにてサポートされているのは、21.2から有効になった置換文字列の名称のみです。
  • IMAGE_PREFIX -> APEX_FILES
  • WORKSPACE_IMAGES -> WORKSPACE_FILES
  • APP_IMAGES -> APP_FILES
  • THEME_IMAGES -> THEME_FILES
  • THEME_DB_IMAGES -> THEME_DB_FILES
静的ファイルは画像に限らないので、より適切になるようファイルを指す名称に変更されています。

apex.items


現在開かれているページ上のページ・アイテムが含まれます。


例えばページ・アイテムP3_DEPTNOは、以下のようにオブジェクトとして取得できます。
let myItem = apex.items.P3_DEPTNO;
これは以下の記法と同等です。
let myItem = apex.item("P3_DEPTNO");
取得したオブジェクトは、どちらも同じです。

今回のバージョンより、JavaScript APIのリファレンスにnumberFieldItemのインターフェースについて記載されました。このインターフェースはアイテム・タイプ数値フィールドのページ・アイテムに実装されています。実際には、数値フィールド以外でもアイテム・タイプごとに異なるインターフェースが実装されています。概ねAPEXのメディアのimages/libraries/apex/以下にwidget.XXXX.jsとして実装が記載されていますが、今回の拡張によりページ・アイテムを選択して、そのページ・アイテム(のオブジェクト)に実装されているプロパティやメソッドを補完することができるようになりました。


そのため、JavaScriptのコーディングの負担がかなり軽減されます。また、JavaScript APIリファレンスに説明のないインターフェースでも、どのようなプロパティやメソッドが実装されているか確認できます。

apex.regions


現在開かれているページ上のリージョンが含まれます。補完の対象となるのはリージョンの静的IDです。こちらはブラウザの開発ツールからはうまく補完されませんでした。ページ・デザイナからJavaScriptのコード・エディタを開いて確認しています。


例えばリージョンR_FACETS(静的IDをR_FACETSとして設定)は、以下のようにオブジェクトとして取得できます。
let myRegion = apex.regions.P_FACETS;
これは以下の記法と同等です。
let myRegion = apex.regions("R_FACETS");
取得したオブジェクトは、どちらも同じです。

apex.itemsと同様にリージョンのタイプに応じてプロパティやメソッドが補完されるため、コーディングの負担がかなり軽減されます。

apex.date


日付を操作するファンクションを提供します。JavaScriptで日付を扱うためにDay.jsなどのライブラリを導入する必要が無くなります。

選択した日付から、apex.date.addを呼び出して1ヶ月後の日付を求めるアプリケーションを作ってみます。


左のページ・アイテムP1_DAY1が変更されたときに動的アクションを呼び出し、以下のスクリプトを実行します。
let d = apex.date.parse(apex.items.P1_DAY1.value);
apex.date.add(d, 1, apex.date.UNIT.MONTH);
// apex.items.P1_DAY2.value = apex.date.format(d);
apex.items.P1_DAY2.value = d.toLocaleDateString();


このようなケースでは以下のようにPL/SQLを記述し、データベースのADD_MONTHSファンクションを使っていたケースもあったかと思います。
begin
    :P1_DAY2 := add_months(:P1_DAY1, 1);
end;


上記の実装ではサーバーとの通信が発生するため、画面の反応は今ひとつでした。これからは日付の操作の多くをブラウザ側で実行できるため、画面の反応も改善できるでしょう。

apex.date.formatはオラクルの日付書式フォーマットによって、JavaScriptのDateを文字列にするファンクションです。ただし、現行では書式フォーマット"DD"は日本語で適切に変換できない不具合があります

DDの変換を以下のファイルから確認してみます。
https://static.oracle.com/cdn/apex/21.2.0/libraries/apex/date.js
                DD: ( d ) => {
                    return ( "0" + d.toLocaleString( "default", { day: "numeric" } ) ).slice( -2 );
                },
d.toLocaleStringは日本語だとnumeric - 数値だけではなく"日"も後ろにつけてしまいます。getDateを使うと回避できます。
                DD: ( d ) => {
                    return ( "0" + d.getDate() ).slice( -2 );
                },
すでに開発チームには修正を依頼しています。

日付関連ではapex.locale.getDateFormatファンクションが新設されています。呼び出すとアプリケーション定義のアプリケーション日付書式が返されます。


JavaScriptによる開発全般に使用できるAPIの追加については以上になります。追加、変更されたAPIは他にもありますが、それは別の機会に紹介できればと思います。

2021年11月24日水曜日

Oracle APEX 21.2新機能(21) - 開発ツールの機能追加

 Oracle APEX 21.2では、アプリケーション・ビルダーやSQLワークショップに含まれるツールに、以下の3つの機能追加があります。

  1. 静的アプリケーション・ファイル、静的ワークスペース・ファイルのエディタ機能が追加されました。JavaScriptとCSSのMinifyおよびLessのコンパイルをファイルの保存時に自動で行います。
  2. ブレッドクラムを編集する画面が追加されました。
  3. SQLコマンドにて、32Kバイトの制限が無くなりました。
追加された機能を確認していきます。

静的ファイルのエディタ


Oracle APEX 21.2より、共有コンポーネント静的アプリケーション・ファイルまたは静的ワークスペース・ファイルを開いた画面に、ファイルの作成が追加されています。


以前はエディタの機能がなかったため、ファイルのアップロードがありました。アップロードするファイルは手元のPCで作成し、それをアップロードする必要があります。ファイルを編集するには、一旦ファイルをダウンロードします。


ファイルの作成をクリックすると、ディレクトリの指定(任意)、ファイル名の指定があります。すでに作成済みのファイルをアップロードすることも可能です。

以前に対話グリッドの表示に色を付ける実装を行ったことがあります。(記事:対話グリッドの列の文字の色を条件によって変更する - JavaScriptによる実装)この実装では、ページ・プロパティJavaScriptページ・ロード時に実行動的アクションに、直接JavaScriptを記述しています。

このJavaScriptの記述をひとつの静的アプリケーション・ファイルにまとめてみます。

一覧画面でファイルの作成をクリックします。ファイル名changeColors.jsとして作成をクリックします。


ファイルに記載する内容は以下です。参照のパスをコピーしておきます。色を設定する部分のコードは共通にしています。
// 部署ごとに色を設定する。
function setColor(elems, deptno) {
    if (elems.length == 1) {
        let elem = elems[0];
        switch(deptno) {
            case '10': // 会計は赤
                if (elem.classList.contains("u-success-text")) {
                    elem.classList.remove("u-success-text");
                }
                if (elem.classList.contains("u-warning-text")) {
                    elem.classList.remove("u-warning-text");
                }
                if (! elem.classList.contains("u-danger-text")) {
                    elem.classList.add("u-danger-text");
                }
                break;
            case '20': // 研究開発は黄色
                if (elem.classList.contains("u-success-text")) {
                    elem.classList.remove("u-success-text");
                }
                if (elem.classList.contains("u-danger-text")) {
                    elem.classList.remove("u-danger-text");
                }
                if (! elem.classList.contains("u-warning-text")) {
                    elem.classList.add("u-warning-text");
                }
                break;
            case '30': // セールスは緑
                if (elem.classList.contains("u-warning-text")) {
                    elem.classList.remove("u-warning-text");
                }
                if (elem.classList.contains("u-danger-text")) {
                    elem.classList.remove("u-danger-text");
                }
                if (! elem.classList.contains("u-success-text")) {
                    elem.classList.add("u-success-text");
                }
                break;
        }
    }
};

// ページ・ロード時の処理
function changeColor(region) {
    let view = apex.region(region).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(region).widget().interactiveGrid( "getActions" ).invoke( "single-row-view" );
            // 単一ビューに切り替えた後は、DOMの操作を行なう。
            let elem = document.getElementById(region);
            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;
            setColor(enameElems, deptno);
        }
    }
};

// 動的アクションの処理
function changeColorDA(region, o) {
    let view =
        apex.region(region).widget().interactiveGrid("getCurrentView");
    if (view.singleRowMode) {
        let model = o.data.model;
        let record = o.data.selectedRecords[0];
        let deptno = model.getValue(record, "DEPTNO");
        let elem = o.triggeringElement;
        let enameElems = elem.getElementsByClassName("u-bold");
        setColor(enameElems, deptno);
    }
};


変更の保存をクリックするとファイルが保存され、縮小されましたと表示されます。Minifyされたファイルが生成されています。


取消をクリックし、ファイルの一覧画面に戻ります。Minifyされたファイルも一覧に表示されていることが確認できます。


静的アプリケーション・ファイルに記載したJavaScriptファンクションを呼び出すように、ページ・プロパティの設定を変更します。

ファイルURLは以下です。
#APP_FILES#changeColors#MIN#.js

ファンクションおよびグローバル変数の宣言は以下です。
var empStaticId = "emp";

ページ・ロード時に実行は以下です。
changeColor(empStaticId);


動的アクションのコードも以下に変更します。
changeColorDA(empStaticId, this);


以上でアプリケーションの変更は完了です。動作自体はまったく変わりませんが、コードのメンテナンスに関しては遥かに容易になっています。

続いてLessの記載について確認してみます。Lesscss.orgにある例を静的アプリケーション・ファイルとして作成します。ファイル名はexample.lessとします。
// Variables
@link-color:        #428bca; // sea blue
@link-color-hover:  darken(@link-color, 10%);

// Usage
a,
.link {
  color: @link-color;
}
a:hover {
  color: @link-color-hover;
}
.widget {
  color: #fff;
  background: @link-color;
}
変更の保存をクリックすると、ファイルが保存され、コンパイルされ、縮小されましたと表示されます。


一覧画面に戻ると、example.lessに加えてexample.css、example.min.cssが作成されていることが確認できます。


CSSについてもページ・プロパティのCSSにインラインで記載するより、静的アプリケーション・ファイル(または静的ワークスペース・ファイル)にまとめて記載する方が生産性が上がるでしょう。

Tipsとして、MacであればCMD+S、WindowsであればCtrl+Sでエディタ上の変更が保存されます。変更の保存をクリックし、ページの送信を行う必要がありません。

以前に紹介したことのあるAPEX Builder Extension by FOSは、APEX 21.2とは互換性がないようで同時に使用できません。そもそも、この機能はStephan DobreさんがオラクルのAPEX開発チームにジョインして作ったもので、同じ人が開発しています。そのため、ほとんど機能的には同じなのですが、プラグインのBoilerplate Codeは含まれていないようです。

開発者のStephan Dobreさんが、Office Hourで静的ファイル・エディタの解説をしています。


ブレッドクラムの編集画面


ブレッドクラムの編集画面が刷新されました。以下の画面になっています。


以前のバージョンでは1画面ではなく、ブレッドクラムの一覧画面と詳細画面に分かれていました。

一覧画面は以下でした。


編集画面は以下でした。


設定できる内容に違いはありません。ターゲットURLを選択したときに限りURLターゲットの設定ができるようになったり、コメントが入れられるようになっています。

ブレッドクラムの設定が直感的にできるようになりました。


32Kバイトの制限の撤廃


Oracle APEX 21.2以前では、SQLコマンドで32Kバイト以上のコードを実行しようとすると、ダイアログが表示され実行できませんでした。

以下がメッセージです。
URL Encoded SQL length exceeds allowed 32k limit


21.2よりこの制限は無くなっています。

Oracle APEX 21.2で開発ツールに追加された機能の紹介は以上です。

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

Oracle APEX 21.2新機能(20) - コピーライト・バナー

 Oracle APEX 21.2より、アプリケーションのエクスポートにコピーライトに関する記述を追加できるようになりました。Srihari Ravvaさん(Oracle Corporationに所属しているAPEXを開発している方です)のブログの記事Adding Copyright information to application export filesに詳しい説明があります。こちらの記事にそって、この機能について確認してみます。

APEXで作成したアプリケーションをエクスポートして、GitHubなどから公開する方向けの機能です。

アプリケーション定義コピーライト・バナーのセクションで設定します。

ヘルプを開き、コピーライト・バナーの説明を確認します。

コピーライト・バナーのテキストをここに入力します。これは、APEXアプリケーションのエクスポート・ファイルに組み込まれます。現在のアプリケーション名を参照するには#APP_NAME#置換文字列を、現在の年を参照するには#YEAR#を使用できます。

#APP_NAME#および#YEAR#を置換文字列として使用できます。コピーライトの書き方については色々あるようです。ただし、©︎は英数字ではないためエクスポートされたファイルに含めるのは適切ではないでしょう。

コピーライト・バナーとして以下を設定します。

Name: #APP_NAME#
Copyright #YEAR# Oracle Corporation.

フォーマットをSQLとしてエクスポートしたときは、以下のように、SQLファイルの先頭にコメントとしてコピーライトが含まれます。

--------------------------------------------------------------------------------

-- Name: デモ - 従業員 / 部門^M

-- Copyright 2021 Oracle Corporation.

--------------------------------------------------------------------------------

prompt --application/set_environment

set define off verify off feedback off

whenever sqlerror exit sql.sqlcode rollback

--------------------------------------------------------------------------------

#APP_NAME#置換文字列がアプリケーション名に置き換わることを確認するために、コピーライト・バナーに#APP_NAME#を含めていますが、アプリケーション名はコピーライト・バナーに含めても含めなくても、どちらでもよいでしょう。

ZIP形式でエクスポートしたときは、copyright.txtというファイルにコピーライトが記載されます。

% cat copyright.txt 

Name: デモ - 従業員 / 部門

Copyright 2021 Oracle Corporation.

% 

copyright.txtは、ZIPファイルを展開した直下のディレクトリに作成されます。

これはページやコンポーネントのエクスポートといった、アプリケーションの部分的なエクスポートでも同様です。SQL形式であればコピーライト・バナーはコメントとして追加され、ZIP形式であればcopyright.txtとして追加されます。

コピーライト・バナーの紹介は以上になります。

2021年11月22日月曜日

Oracle APEX 21.2新機能(19) - 日付ピッカーの表示条件

 Oracle APEX 21.2では、日付ピッカーに表示条件が追加されました。表示形式PopupもしくはInlineのときに有効です。

個々の日付ピッカーのページ・アイテムに設定するには、デフォルトの使用OFFにします。表示条件として、Item FocusまたはIcon Clickを選べます。

表示条件Item Focusの場合は、ページ・アイテムがフォーカスされたとき、および、アイコンがクリックされたときに日付ピッカーが開きます。


表示条件Icon Clickの場合は、アイコンがクリックされたときのみ日付ピッカーが開きます。

日付ピッカーのデフォルトは共有コンポーネントコンポーネント設定で定義されています。


コンポーネント設定日付ピッカーが含まれています。


表示条件のデフォルトとして、アイテム・フォーカスまたはアイコン・クリックを選択できます。


Oracle APEX 21.2の日付ピッカーの拡張については以上です。

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








Oracle APEX 21.2新機能(18) - ポップアップLOVの拡張

 Oracle APEX 21.2より、JavaScript APIのapex.item.setValueを呼び出してポップアップLOVの値を設定したときに、同時にページ・アイテムの表示と追加値も更新されるようになりました。

以下のGIF動画では、最初にポップアップLOVを操作して値を選択しています。その次に動的アクションによって、ポップアップLOVに従業員番号を設定しています。従業員名の表示とジョブの表示も更新されています。


実装について確認してみます。サンプル・データセットEMP/DEPTがインストールされていて、表EMPが存在することを前提とします。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。アプリケーションの名前は任意です。


ポップアップLOVで追加値を扱う場合は、共有コンポーネントのLOVが必要です。表EMPを扱うLOVを作成します。共有コンポーネントLOVを開きます。


作成済みのLOVの一覧ページより、作成をクリックします。


LOVの作成最初からを選択し、へ進みます。


LOVの名前LOV_EMPタイプDynamicとします。へ進みます。


ソース・タイプTable表/ビューの名前としてEMP(表)を選択します。へ進みます。


戻り列EMPNO表示列ENAMEとします。作成をクリックします。


共有コンポーネントのLOV、LOV_EMPが作成されます。追加値を扱えるように設定を加えます。LOV_EMPをクリックして編集画面を開きます。


追加表示列列の選択をクリックします。


今回は検証なので、すべての列を追加表示列にします。更新をクリックします。


以上でLOVの設定は完了です。変更の適用をクリックして共有コンポーネントの作業を終了します。


ホーム・ページページ・デザイナで開き、ページ・アイテムを3つ作成します。

最初にポップアップLOVのページ・アイテムP1_EMPNOを作成します。

識別名前P1_EMPNOタイプポップアップLOVです。ラベル従業員とします。追加出力としてJOB:P1_JOBを指定します。LOVタイプ共有コンポーネントLOVは先ほど作成したLOV_EMPを指定します。


追加出力のジョブを保持するページ・アイテムP1_JOBを作成します。

識別名前P1_JOBタイプテキスト・フィールドラベルジョブとします。


動的アクションの引数とする従業員番号を入力するページ・アイテムP1_EMPNO_DAを作成します。

識別名前P1_EMPNO_DAタイプテキスト・フィールドラベル従業員#とします。


ポップアップLOVに値を設定するJavaScriptのコードを、動的アクションとして実行するボタンを作成します。

識別ボタン名B_SETラベル設定とします。動作アクションとして動的アクションで定義を選択します。


動的アクションは、タイミングとしてボタンB_SETクリックした時にTRUEアクションが実行されるように設定します。


TRUEアクションを設定します。識別アクションとしてJavaScriptコードの実行を選択します。コードとして以下を記載します。
apex.item("P1_EMPNO").setValue($v("P1_EMPNO_DA"));

Oracle APEX 21.2からは、apex.item.setValueでポップアップLOVの値を設定すると、画面上の表示および追加値も変更されます。結果として、最初のGIF画面の動作になります。

Oracle APEX 21.2ではapex.itemsというネーム・スペースが追加され、ページ・アイテムの参照が容易になっています。apex.itemsを使用すると上記のコードを、以下に書き換えることができます。
apex.items.P1_EMPNO.setValue(
    apex.items.P1_EMPNO_DA.getValue()
);
Oracle APEX組み込みのJavaScriptのコード・エディタは、apex.items.から続くページ・アイテム名の補完を行うようになっています。


ページ・アイテムから呼び出せるファンクション名も補完してくれます。


apex.items以外にコーディングを容易にするネーム・スペースとして、apex.regionsおよびapex.envが追加されています。

ポップアップLOVの拡張については以上になります。

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

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

追記

apex.item.setValueを呼び出す他にアクション値の設定でも、同様に表示と追加値が設定されます。

設定タイプの設定としてJavaScript Expressionを選択し、JavaScript式としてapex.items.P1_EMPNO_DA.getValue()影響を受ける要素として選択タイプアイテムアイテムP1_EMPNOを選択します。