2022年8月30日火曜日

Grid.jsを使ってみる

 オープン・ソースのJavaScriptプラグインであるGrid.jsをOracle APEXで使ってみます。Grid.jsの紹介には"It works with most JavaScript frameworks, including React, Angular, Vue and VanillaJS."とあります。Oracle  APEXはJavaScriptフレームワークとは謳っていませんが、Grid.jsを組み込むことは可能です。

以前にOracle APEXでHighchartsを使う方法CKEditor5のInline Editorを使う方法を紹介しています。それと似た作業になります。

サンプル・データセットEMP/DEPTに含まれる表EMPを、Grid.jsにて表示します。


Grid.jsが受け付ける形式でデータを返すRESTサービスを作成します。

Grid.js側のコードは、ExamplesのCustom HTTP clientの例を参考にして記述します。


この例のコメントとして、RESTサービスが返すべきデータのフォーマットが記載されています。


正直なところ、上記のコードからはフォーマットがピンと来なかったので、Examplesのコードに含まれているURLにアクセスして、出力されるレスポンスを確認しました。


表EMPのデータを上記のフォーマットで返すSELECT文は以下になります。
select 
  json_object(
    'data' value coalesce(json_arrayagg(line),'[]') format json
    , 'total' value count(*)
  ) 
from (
  select json_object(empno, ename, job, sal, comm, hiredate) as line
  from emp
);
SQLワークショップSQLコマンドより上記のSQLを実行することにより、出力されるJSONオブジェクトを確認できます。


上記のSELECT文の結果を返す、RESTfulサービスのGETハンドラを作成します。

SQLワークショップRESTfulサービスを開きます。

モジュールgridjsを作成します。モジュール・パス/gridjs/とします。続いてURIテンプレートemp/をモジュールgridjsに作成します。

テンプレートemp/にGETハンドラを作成します。ソースとして以下を記述します。



完全なURLは、Grid.jsを初期化するコードにサーバー側のURLとして指定するため、コピーをして後で参照できるようにしておきます。

RESTfulサービスを、APEXセッションからのみ呼び出しができるように保護します。

ORDSの権限としてgridjsを作成します。ロールとしてRESTful Servicesを選択します。保護されたモジュールとしてgridjsを選択します。選択するロールはRESTful Servicesでなくてもかまいません(専用のロールを新規に作る方が望ましいでしょう)。ここで選択したロールを、APEXのユーザーに割り当てます。


ユーザーとグループの管理を開き、RESTfulサービスへアクセスするユーザーを編集します。グループ割当てとしてRESTful Servicesを割り当てます。


以上でデータのソースとなるRESTfulサービスの準備ができました。

APEXアプリケーションを作成し、Grid.jsを組み込みます。

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

アプリケーションの名前Grid.jsとします。


アプリケーションが作成されます。

ページ・デザイナにてホーム・ページを開きます。


Grid.jsのドキュメントのInstallにに含まれるjsdelivrのセクションを参照し、以下の設定を行います。

ページ・プロパティJavaScriptファイルURLとして以下を設定します。

https://cdn.jsdelivr.net/npm/gridjs/dist/gridjs.umd.js

CSSファイルURLとして以下を設定します。

https://cdn.jsdelivr.net/npm/gridjs/dist/theme/mermaid.min.css


Bodyにグリッドを表示するリージョンを作成します。

識別タイトルGridタイプとして静的コンテンツを選択します。外観テンプレートとして装飾の少ないBlank with Attributes (No Grid)を選択します。詳細静的IDとしてgridを設定します。


作成したリージョンGridを対象として、Grid.jsを初期化します。

ページ・プロパティJavaScriptファンクションおよびグローバル変数の宣言として、以下を記述します。RESTfulサービスの認証に使用します。

let apexSession = apex.env.APP_ID + ',' + apex.env.APP_SESSION;

ページ・ロード時に実行として、以下を記述します。



コード中で使用されている置換文字列G_DATA_SOURCE_URLを、アプリケーション定義置換に設定します。置換値はRESTfulサービスの完全なURLです。


グリッドをリフレッシュするボタンを作成します。

識別ボタン名B_REFRESHラベルリフレッシュとします。動作アクションとして動的アクションで定義を選択します。詳細カスタム属性としてdata-action="#action$force-render"を設定します。


Grid.jsのグリッドを初期化するリージョン、正確にはdiv要素に子要素が含まれていると初期化に失敗します。そのため、ここで作成するボタンB_REFRESHをリージョンGridに含めることはできません。エラーが発生しないようにするために、リージョンGridの静的ID空白にし、ソースHTMLコードとして

<div id="grid"></div>

を記述することもできます。


以上でAPEXアプリケーションへのGrid.jsの組み込みは完了です。

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

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

追記

RESTfulサービスの代わりにAjaxコールバックを使った実装例です。

AjaxコールバックとしてプロセスGET_EMPを作成します。ソースPL/SQLコードは、RESTfulサービスのGETハンドラのコードと同じです。


作成したAjaxコールバックを呼び出すように、ページ・プロパティJavaScriptページ・ロード時に実行を以下に変更します。