Oracle IndiaのSrihari RavvaさんがWeb Components in Oracle APEXとして、WebコンポーネントをOracle APEXで扱う方法を紹介しています。面白いトピックなので、自分でも試してみました。
環境に依存せずに作業を試行できるよう、いくつか手順を変えています。特にJavaScriptから呼び出すRESTful APIを独自のものから、Oracle APEXのRESTful APIのサンプルとして提供されているoracle.example.hrを使うようにしています。
確認作業は以下の順番で行います。
- Oracle APEX Builder Extension by FOSを導入する。
- RESTfulサービスのサンプルをインストール(またはリセット)する。
- 空のアプリケーションを作成する。
- 静的アプリケーション・ファイルに、WebコンポーネントとなるJavaScriptのコードを記述する。
- 静的リージョンを作成し、動作を確認する。
- 動的アクションを作成し、動作を確認する。
Oracle APEX Builder Extension by FOSを導入する
RESTfulサービスのサンプルをインストール(またはリセット)する
今回はサンプル・サービスをそのまま利用するので、サンプル・サービスのインストールをONにし、スキーマ属性の保存を実行します。
空のアプリケーションを作成する
新規アプリケーションをクリックします。
アプリケーションの名前は任意ですが、今回はWebコンポーネント検証としています。その他は何もせず、アプリケーションの作成を実行します。
以上でアプリケーションの準備も完了しました。
JavaScriptのコードを記述する
File Nameとしてemployee-info.jsを指定し、Createを実行します。
// JavaScriptコード // temlate要素を生成する。 const template = document.createElement('template'); // 従業員情報を表示するテンプレートとなるHTMLとCSSを記述する。 // Shadow DOMにになるので、ここで定義されたCSSはカスタム要素のemployee-data内でのみ有効。 // ページレベルで定義されているCSSはカスタム要素には適用されない。 template.innerHTML = ` <style> div.employee-data { background: #F5F4F2; width: 400px; margin-bottom: 10px; border-bottom: purple 8px solid; padding: 4px; } div.employee-data h2{ color: purple; } </style> <div class="employee-data"> <h2></h2> <div class="empno">EMPNO: <span></span> </div> <div class="job">JOB: <span></span> </div> </div> `; // カスタム要素のためのクラスを定義する。 // 一般的にはカスタム要素の名前が custom-element であれば、 CustomElement をクラス名とする。 // 今回は employee-info がカスタム要素なので、クラス名は EmployeeInfo となる。 class EmployeeInfo extends HTMLElement { constructor() { // かならず super をコンストラクタの先頭で呼び出す。HTMLElementとして正しく初期化される。 super(); // Shadow DOMをアタッチする。これによりカスタム要素が独立する。 this.attachShadow({ mode: 'open' }); // テンプレートをクローンし、ShadowRootに追加する。 this.shadowRoot.appendChild(template.content.cloneNode(true)); // RESTful APIを呼び出し従業員データを取得する。 // 従業員番号(empno)の属性を引数として、RESTful APIを呼び出す。 // RESTful APIの応答をテンプレートの穴埋めに使用する。 fetch('https://apex.oracle.com/pls/apex/your_workspace/hr/employees/' + this.getAttribute('empno')).then(response => response.json()).then(data => { this.shadowRoot.querySelector('h2').innerText = data.ename; this.shadowRoot.querySelector('div.empno > span').innerText = data.empno; this.shadowRoot.querySelector('div.job > span').innerText = data.job; }); } } // カスタム要素 employee-info と クラス EmployeeInfo を関連づける。 window.customElements.define('employee-info', EmployeeInfo);
静的リージョンで動作確認をする
ページ・デザイナでホーム・ページ(Page 1)を開きます。HTMLヘッダーとして以下を設定し、ホーム・ページのロード時に、先ほど静的アプリケーション・ファイルとして作成したJavaScriptのファイルを読み込みます。
<script type="module" src="#APP_IMAGES#employee-info.min.js"></script>
静的アプリケーション・ファイルを標準のJavaScriptのファイルURLではなく、HTMLヘッダーのscriptタグで読み込んでいます。これは、スクリプトをmoduleとして認識させ、グローバルから参照できないようにするためです。
次にリージョンを作成し、名前はWeb Components、タイプは静的コンテンツとします。ソースのテキストには以下を設定します。
<employee-info empno="7839"></employee-info>
リージョンの設定ができたら、ページの保存と実行を行い、動作を確認します。
以下のように、従業員KINGが表示されたら、手順通り実装できています。
動的アクションを使って動作確認をする
Webコンポーネントの表示に動的アクションを使います。再度、新規にリージョンを作成します。名前はWeb Components - Dynamic Action、タイプは静的コンテンツです。ソースのテキストには以下を設定します。
<div id="employee_data_container"></div>
表示する従業員を指定するため、ページ・アイテムの作成を実行します。名前はP1_EMPLOYEES、タイプはチェック。ボックス・グループ、ラベルはEmployeesとします。LOVのタイプは静的値とします。
LOVの静的値として、以下のペアを設定します。
表示値 | 戻り値 |
BLAKE | 7698 |
CLARK | 7782 |
JONES | 7566 |
SCOTT | 7788 |
サンプルのRESTfulサービスが初期状態でない場合は、表示値としている従業員が存在しない場合もあります。存在する従業員を探してLOVの値を登録してください。
最後に動的アクションを登録します。左ペインから動的アクション・ビューを開き、動的アクションを作成します。
名前はDisplay Employee Dataとし、タイミングとして、イベントは変更、選択タイプはjQueryセレクタ、jQueryセレクタとしてinput[name=P1_EMPLOYEES]を指定します。
実行されるアクションとして、JavaScriptコードの実行を指定し、設定のコードに以下を設定します。
// チェック・ボックスより従業員番号を取得する let empNo = $(this.triggeringElement).val(); // 従業員番号に対応するemployee-infoのタグを探して取得する。 let employeeNode = $("employee-info[empno=" + empNo + "]"); if ($(this.triggeringElement).is(':checked')) { // 要素が既に存在するか確認する。存在する場合は表示する。 if (employeeNode.length == 1) employeeNode.show(); else // そうでない場合は、要素を追加する。 $('#employee_data_container').append('<employee-info empno="' + empNo + '"></employee-info>'); } else { // チェックが外れたときは非表示にする。 employeeNode.hide(); }
動的アクションの設定が完了したら、ページの保存と実行を行います。この記事の先頭にあるGIF動画の動作を確認できるはずです。
以上でOracle APEXでのWebコンポーネントの実装についての記事は終了です。
実際にはより複雑な実装になるかと思いますが、元記事を読んで、基本的な実装手順について参考になる内容だと思いました。また、Oracle APEXのプラグインとして実装することで、サーバー側の条件や認可スキームなども活用できるようになり、より便利なものになるでしょう。
完