2024年9月13日金曜日

PPTXjsおよびmammoth.jsを使ってPowerPointとWordのファイルをブラウザ上で表示する

PPTXjsmammoth.jsを使って、データベースのBLOBに保存されたMicrosoft PowerPoint(.pptx)とWord(.docx)をブラウザ上に表示してみます。

PPTXjsの場合は、読みやすく表示されるPowerPointもあれば、


背景色やフォントの色が適切に変換されず、まったく読めないスライドもあります。


日本語でのPPTXjsの利用実績を見つけることはできませんでした。これをそのままで使うのは難しいと思います。また、slideModeはdivs2slidesjsおよびrevealjsともに動作しませんでした。PPTXjsのデモのページでも動作していないため、APEXへの組み込み方に問題があるわけでも無さそうです。

とはいえ、PowerPointをブラウザ上でHTMLに変換して表示するJavaScriptライブラリは、ほとんど無いようです。どのようなものか、動作を確認してみる価値はあります。

mammoth.jsを使ったWordの変換では、大体は読める形式でHTMLに変換してくれる感じです。ただし、追加の実装をしないと埋め込まれた画像は表示されません。


以下より、APEXアプリケーションの作り方を紹介します。

PowerPointやWordのドキュメントをBLOBとして保存する表を作成します。

クイックSQLの以下のモデルから、表EBAJ_DOCV_DOCUMENTSを作成します。
# prefix: ebaj_docv
documents
    title vc80 /nn
    document file
レビューおよび実行をクリックします。


次のページでスクリプト名を入力し実行をクリックし、表示された確認画面で即時実行をクリックします。

EBAJ_DOCV_DOCUMENTSが作成されます。

続けて、アプリケーションの作成をクリックします。確認画面が表示されるので、再度アプリケーションの作成をクリックします。


アプリケーション作成ウィザードが起動します。表EBAJ_DOCV_DOCUMENTSソースとしたフォーム付き対話モード・レポートのページはあらかじめ追加されています。

ページの追加をクリックし、空白のページとしてWord ViewerPowerPoint Viewerさらにdownloadを追加します。

以上で、アプリケーションの作成を実行します。


アプリケーションが作成されたら、ファイルのアップロードとダウンロードの機能を調整します。ソースとなる表にBLOB列が含まれていると、アプリケーション作成ウィザードおよびページ作成ウィザードは、ファイルをBLOBにアップロードする機能と、BLOBをファイルとしてダウンロードする機能を自動的に作成してくれます。しかし、ファイル名列MIMEタイプ列は自動では設定されません。

ページ・デザイナで、ページ番号の対話モード・レポートのページを開きます。

DOCUMENTを選択し、BLOB属性MIMEタイプ列DOCUMENT_MIMETYPEファイル名列DOCUMENT_FILENAME最終更新列DOCUMENT_LASTUPD文字セット列DOCUMENT_CHARSETを設定します。

以上で変更を保存します。


ページ・デザイナで、ページ番号のフォームのページを開きます。

ページ・アイテムP3_DOCUMENTを選択し、ストレージMIMEタイプ列DOCUMENT_MIMETYPEファイル名列DOCUMENT_FILENAME文字セット列DOCUMENT_CHARSET、BLOB最終更新列DOCUMENT_LASTUPDを設定します。


以上で変更を保存します。

この時点でAPEXアプリケーションを実行し、確認に使用するPowerPointとWordのファイルをアップロードします。

表EBAJ_DOCV_DOCUMENTSの対話モード・レポートのページを開き、作成をクリックします。


ドロワーが開くので、適当にタイトルをつけてPowerPointやWordのファイルをアップロードします。


動作確認に使用するファイルを複数アップロードします。


続いて、JavaScriptのコード中よりURLを指定して、BLOBのデータを取り出せるようにします。

ページ・デザイナdownloadのページを開きます。

空白ページdownloadに、表EBAJ_DOCV_DOCUMENTSの主キーIDの値を渡して、BLOBをファイルとして返す機能を実装します。

ダウンロードするBLOBのIDを受け付けるページ・アイテムP6_IDを作成します。タイプ非表示セッション・ステートストレージリクエストごと(メモリーのみ)とします。


ページ・アイテムP6_IDに渡されたIDのBLOBを、ファイルとしてダウンロードするプロセスを作成します。識別タイプとしてAPEX 24.1で新設されたダウンロードを選択します。

設定ファイルの表示形式として添付を選択し、ソースSQL問合せとして、以下を記述します。

select document, document_filename from ebaj_docv_documents where id = :P6_ID


以上の設定を行うことにより、BLOBをファイルとして取得するURLをAPEX_PAGE.GET_URLにより生成できるようになりました。以下のように呼び出します。
declare
    l_url varchar2(400);
begin
    l_url := apex_page.get_url(
        p_application => :APP_ID
        ,p_page => 'download'
        ,p_items => 'P6_ID'
        ,p_values => :P4_ID -- assume select list on page 4
    );
    :P4_DOCUMENT_URL := l_url;
end;

最初にWord Viewerのページに、mammoth.jsを使ったWordビューワーを実装します。

ページ・デザイナWord Viewerのページを開きます。

ページ・プロパティHTMLヘッダーに、mammoth.jsをロードするためにimportmapを設定します。
<script type="importmap">
    {
        "imports": {
            "mammoth": "https://cdn.jsdelivr.net/npm/mammoth@1.8.0/+esm"
        }
    }
</script>

プレビューするドキュメントを選択するページ・アイテムとしてP4_IDを作成します。タイプ選択リストです。LOVタイプとしてSQL問合せSQL問合せとして以下を記述します。

select title d, id r from ebaj_docv_documents

追加値の表示オフNULL値の表示オンNULL表示値として- Select Document -を設定します。

以前の値を記憶するように、セッション・ステートストレージセッションごと(永続)とします。


ページを送信して選択したドキュメントをプレビューするボタンを作成します。

識別ボタン名VIEWラベルView動作アクションページの送信です。外観ホットオンテンプレート・オプションWidthStretchに設定します。


BLOBの取り出しに指定するURLを保持するページ・アイテムP4_DOCUMENT_URLを作成します。本来であればタイプ非表示とすべきですが、値を確認できるようにタイプテキスト・フィールドとします。セッション・ステートストレージセッションごと(永続)を選びます。


ボタンViewをクリックしたときに実行されるプロセスを作成します。

以下のPL/SQLコードを実行し、BLOBを取り出すURLをページ・アイテムP4_DOCUMENT_URLに設定します。
declare
    l_url varchar2(400);
begin
    l_url := apex_page.get_url(
        p_application => :APP_ID
        ,p_page => 'download'
        ,p_items => 'P6_ID'
        ,p_values => :P4_ID -- assume select list on page 4
    );
    :P4_DOCUMENT_URL := l_url;
end;
サーバー側の条件ボタン押下時VIEWです。


mammoth.jpを呼び出し、Wordドキュメントから生成したHTMLを表示します。

静的コンテンツのリージョンを作成し、以下のコードをソースHTMLコードに記述します。



以上で、Word Viewerは完成です。

アプリケーションは以下のGIF動画のように動作します。


次にPPTXjsを組み込んだPowerPoint Viewerを実装します。

GitHubのReleasesのページを開き、最新バージョンのv1.21.1(といっても2年以上前)のSource code (zip)をダウンロードします。PPTXjs-1.21.1.zipがダウンロードされます。

ダウンロードされたPPTXjs-1.21.1.zipを展開します。ディレクトリPPTXjs-1.21.1が作成され、その下にPowerPointをHTMLに変換するために必要なファイルが含まれます。

ディレクトリPPTXjs-1.21.1へ移動し、必要なファイルをpptxjs.zipにまとめます。

cd PPTXjs-1.21.1
zip -r pptxjs.zip js/d3.min.js js/dingbat.js js/divs2slides.js js/divs2slides.min.js js/filereader.js js/jszip.min.js js/nv.d3.min.js js/pptxjs.js js/pptxjs.min.js css/pptxjs.css css/nv.d3.min.css

% cd PPTXjs-1.21.1

 PPTXjs-1.21.1 % zip -r pptxjs.zip js/d3.min.js js/dingbat.js js/divs2slides.js js/divs2slides.min.js js/filereader.js js/jszip.min.js js/nv.d3.min.js js/pptxjs.js js/pptxjs.min.js css/pptxjs.css css/nv.d3.min.css

  adding: js/d3.min.js (deflated 65%)

  adding: js/dingbat.js (deflated 90%)

  adding: js/divs2slides.js (deflated 65%)

  adding: js/divs2slides.min.js (deflated 53%)

  adding: js/filereader.js (deflated 75%)

  adding: js/jszip.min.js (deflated 69%)

  adding: js/nv.d3.min.js (deflated 80%)

  adding: js/pptxjs.js (deflated 87%)

  adding: js/pptxjs.min.js (deflated 80%)

  adding: css/pptxjs.css (deflated 74%)

  adding: css/nv.d3.min.css (deflated 77%)

 PPTXjs-1.21.1 % 


共有コンポーネント静的アプリケーション・ファイルを開き、ファイルの作成をクリックします。


コンテンツに先ほど作成したpptxjs.zipを選択し、ファイルの解凍オンにします。

作成をクリックします。


ファイルが作成されたことを確認するため、静的アプリケーション・ファイルを開きます。


pptxjs.zipに固めたファイルが、静的アプリケーション・ファイルの一覧に含まれていれば準備は完了です。


ページ・デザイナPowerPoint Viewerのページを開きます。

ページ・アイテムP5_ID、ボタンVIEW、ページ・アイテムP5_DOCUMENT_URL、それと、プロセスGet Document URLは、Word Viewerと同様に作成します。ページ番号が5になっているため、その部分は変更します。

静的コンテンツのリージョンDocument ViewerHTMLコードは以下になります。

<div id="container" class="h600"></div>


ページ・プロパティJavaScriptファイルURLに以下を記述します。
#APP_FILES#js/jszip.min.js
#APP_FILES#js/filereader.js
#APP_FILES#js/d3.min.js
#APP_FILES#js/nv.d3.min.js
#APP_FILES#js/dingbat.js
#APP_FILES#js/pptxjs.min.js
#APP_FILES#js/divs2slides.min.js
CSSファイルURLに以下を記述します。
#APP_FILES#css/pptxjs.css
#APP_FILES#css/nv.d3.min.css
JavaScriptページ・ロード時に実行に以下を記述します。
$("#container").pptxToHtml({
    pptxFileUrl: apex.item("P5_DOCUMENT_URL").getValue(),
    slideMode: false,
    keyBoardShortCut: false
});

以上でPowerPoint Viewerは完成です。

アプリケーションは以下のGIF動画のように動作します。


今回の記事は以上です。

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

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

2024年9月12日木曜日

Oracle APEXがサポートしているラインタイム・メッセージの翻訳を確認する

Oracle APEX 24.1ではウクライナ語とベトナム語が、ライタイム・メッセージの翻訳に追加されました。今までサポートしていた言語と合わせると34言語の翻訳を提供しています。

提供されているランタイム・メッセージの翻訳は以下です。


Oracle APEXの管理ツールやアプリケーション・ビルダーは、10言語(ドイツ語、英語、スペイン語、フランス語、イタリア語、ポルトガル語(ブラジル)簡体中国語、繁体中国語、日本語、韓国語)に翻訳されています。

ランタイム・メッセージというのは主にOracle APEXの組み込みコンポーネントが扱うメッセージになります。具体的には対話モード・レポートや対話グリッドです。

サポートされている34言語はどのような言語なのか、自動的に切り替えるアプリケーションを作成してみました。

以下のように動作します。ボタンStart LoopをクリックするとIntervalで指定した秒ごとにランタイム・メッセージの言語を切り替えていきます。

開発ツールも翻訳されている言語では、Welcomeの表示がそれぞれの言語に翻訳されます。また、アラビア語とヘブライ語については、表示をRTL(Right-to-Left)に切り替えています。


このAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/oracle-apex-support-languages.zip

対話モード・レポートのソースとして、サンプル・データセットEMP/DEPTに含まれる表EMPが必要です。

作り方はあまり参考にならないアプリケーションですが、いくつかの実装のポイントを紹介します。すべての機能をホーム・ページに実装しています。


ボタンSTART_LOOPを押すとJavaScriptのファンクションstartLoop()を呼び出します。STOP_LOOPではstopLoop()を呼び出します。翻訳を選択するページ・アイテムP1_LANGは値が変更されると、動的アクションでページの送信を実行します。

ページ・アイテムP1_LANGは以前の値を保存させるため、セッション・ステートストレージセッションごと(永続)にします。

ページ・アイテムP1_LANGが変更され、ページの送信が実行されたときに呼び出されるプロセスでは、以下のコードが実行されます。
begin
    apex_util.set_preference(
        p_preference => 'FSP_LANGUAGE_PREFERENCE'
        ,p_value => :P1_LANG
    );
    /*
     * autoChangeでの呼び出しであれば、P1_AUTO_ENABLEDをYとする。
     * 手動切り替えのときはP1_AUTO_SUBMITは空になるため、自動切り替えは
     * 継続しない。
     */
    if :P1_AUTO_SUBMIT = 'Y' then
        :P1_AUTO_ENABLED := 'Y';
    else
        :P1_AUTO_ENABLED := '';
    end if;
end;
プリファレンスFSP_LANGUAGE_PREFERENCEに言語コードを設定することにより、ランタイム・メッセージの翻訳を切り替えています。


アプリケーション定義グローバリゼーションアプリケーション言語の導出元として、アプリケーション・プリファレンス(FSP_LANGUAGE_PREFERENCEを使用)を選択しています。


ページ・プロパティJavaScriptファンクションおよびグローバル変数の宣言に、以下を記述しています。


ページ・ロー時に実行に以下を記述しています。自動的に発生したページ・ロードのときは、自動ロードを継続します。
/*
 * 言語の自動切り替えが有効であれば、startLoopを呼び出す。
 */
if ( apex.item("P1_AUTO_ENABLED").getValue() === "Y" ) {
    startLoop();
}
else
{
    document.getElementById("START_LOOP").disabled = false;
    document.getElementById("STOP_LOOP").disabled  = true;    
}

ページ・ロード時に言語がarまたはhe(つまりアラビア語またはヘブライ語)のときは、動的アクションでRight-to-Leftに変更しています。

document.documentElement.setAttribute('dir', 'rtl');


開発言語のリージョンに表示している「ようこそ」の翻訳文は、以下のコードを記述した動的コンテンツとして実装しています。
declare
    l_message clob;
begin
    l_message := apex_lang.message('INSTALLER.WELCOME');
    return l_message;
end;

Oracle APEXの製品としてはメッセージ・キーINSTALLER.WELCOMEで取得できるメッセージの言語は10言語ですが、以下のようにAPEX_LANG.CREATE_MESSAGEを呼び出すか、または共有コンポーネントテキスト・メッセージから、それぞれの言語のメッセージを追加することで、標準では翻訳文が提供されていない言語にも対応できます。


今回の記事は以上になります。

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

2024年9月11日水曜日

Genson-jsをMLEモジュールとして作成しJSONデータからJSONスキーマを生成する

JavaScriptライブラリのGenson-jsをOracle Database 23aiのMLEモジュールとして作成し、サーバーサイドでJSONデータからJSONスキーマを生成します。

以下のスクリプトを実行し、Genson-jsのESモジュールからOracle Database 23aiのMLEモジュールを作成します。

SQLワークショップSQLスクリプトとして実行するか、(SQLコマンドでは1行ごとでしか実行できないため)1行ごとにSQLコマンドで実行します。

最初にMLEモジュールESM_GENSON_JS_0_0_8を作成します。


モジュールESM_GENSON_JS_0_0_8を含むMLE環境JSONENVを作成します。


以上で、データベース・サーバーでGenson-jsを呼び出せるようになりました。

SQLコマンドで以下を実行し動作を確認します。SQLコマンド言語としてJavaScript(MLE)を選択し、環境に先ほど作成したJSONENVを指定します。
const Genson = await import('/npm/genson-js@0.0.8/+esm');

const jsonData = {
    "firstName": "Sakura",
    "age": 35
};

const schema = Genson.createSchema(
    jsonData
);

console.log(JSON.stringify(schema, null, 2));
スクリプトを実行してJSONスキーマが出力されれば、Genson-jsは正しくMLEモジュールとして作成されています。


JSONデータからJSONスキーマを生成する機能と、JSONスキーマのマージを行う機能を組み込んだ、簡単なAPEXアプリケーションを作成します。

アプリケーション作成ウィザードを起動します。作成するアプリケーションの名前JSON Schema Generator by Genson-jsとします。

ページの追加をクリックし、ページ名Create Schemaとした空白のページとMerge Schemasとした空白のページを追加します。

以上で、アプリケーションの作成を実行します。


アプリケーションが作成されます。アプリケーションはCreate SchemaMerge Schemasのページを含みます。


このアプリケーションからGenson-jsを呼び出すために、MLE環境として作成したJSONENVを紐づけます。

アプリケーション定義セキュリティを開き、データベース・セッションMLE環境に、JSONENVを設定します。

以上の設定で、このアプリケーション内でGensos-jsを呼び出すことができるようになります。


Create Schemaのページを開き、JSONデータからJSONスキーマを生成する機能を実装します。

JSONデータを入力するページ・アイテムとしてP2_JSON_DATAを作成します。タイプテキスト領域です。続いて、JSONデータからJSONスキーマを生成するボタンCREATE_JSON_SCHEMAを作成します。動作アクションページの送信です。生成したJSONスキーマを保存するページ・アイテムとしてP2_JSON_SCHEMAを作成します。タイプテキスト領域です。


ボタンCREATE_JSON_SCHEMAを押した時に実行されるプロセスを作成します。

識別名前Create JSON Schemaとします。タイプコードを実行です。ソース言語JavaScript(MLE)を選択し、JavaScriptコードとして以下を記述します。
const Genson = await import('/npm/genson-js@0.0.8/+esm');

const jsonData = JSON.parse(apex.env.P2_JSON_DATA);

const schema = Genson.createSchema(
    jsonData
);

apex.env.P2_JSON_SCHEMA = JSON.stringify(schema, null, 2);
サーバー側の条件ボタン押下時CREATE_JSON_SCHEMAを指定します。


以上でCreate Schemaのページは完成です。ページを実行すると以下のように動作します。


Merge Schemasのページを開き、JSONスキーマをマージする機能を実装します。

JSONスキーマを入力するページ・アイテムとしてP3_JSON_SCHEMA_1P3_JSON_SCHEMA_2を作成します。Genson_jsのファンクションmergeSchemaの引数はマージするJSONスキーマの配列を受け付けるため、2つ以上のJSONスキーマを一度にマージすることができます。ただし、このページでは2つに限定しています。

JSONスキーマをマージするボタンMERGE_JSON_SCHEMAを作成します。動作アクションページの送信です。生成したJSONスキーマを保存するページ・アイテムとしてP3_JSON_SCHEMAを作成します。


ボタンMERGE_JSON_SCHEMAを押した時に実行されるプロセスを作成します。

識別名前Merge JSON Schemaとします。タイプコードを実行です。ソース言語JavaScript(MLE)を選択し、JavaScriptコードとして以下を記述します。
const Genson = await import('/npm/genson-js@0.0.8/+esm');

const jsonSchema1 = JSON.parse(apex.env.P3_JSON_SCHEMA_1);
const jsonSchema2 = JSON.parse(apex.env.P3_JSON_SCHEMA_2);

const schema = Genson.mergeSchemas(
    [ jsonSchema1, jsonSchema2 ]
);

apex.env.P3_JSON_SCHEMA = JSON.stringify(schema, null, 2);

以上でMerge Schemaのページは完成です。ページを実行すると以下のように動作します。


以上でアプリケーションは完成です。

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

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

2024年9月10日火曜日

react-jsonschema-formを使ってJSON列を扱うフォームを生成する

react-jsonschema-formを組み込んで、データベースのJSON列向けのフォームを自動生成してみます。

作成するアプリケーションは以下のように動作します。フォームを生成するJSON Schemaを選択し、APEXのフォーム(ドロワーとして実装)を開きます。開いたフォームは、選択したJSON Schemaから生成されたフォームを含みます。以下のGIF動画では、JSON SchemaとしてSimpleUI Optionsのどちらかを選んでいて(react-jsonschema-formのLive Playgroundから拝借しています)、選択によってフォームに表示される項目が変わります。JSON Formの領域に含まれている項目は、JSON形式でひとつの列に保存されます。


クイックSQLの以下のモデルを元に、表EBAJ_JSON_DATAEBAJ_JSON_SCHEMASを作成します。

EBAJ_JSON_DATAの列CONTENTにJSON形式でデータを保存します。この列に保存するデータを入力するフォームを、表EBAJ_JSON_SCHEMASの列JSON_SCHEMA(JSON列の制約となるJSON Schema定義)と列UI_SCHEMA(UIの定義)から動的に生成します。列FORM_DATACONTENTに保存する初期値です。
# prefix: ebaj
json_data
    title vc80 /nn
    content json
    schema_id num /fk json_schemas

json_schemas
    title vc80 /nn
    json_schema json
    ui_schema json
    form_data json
SQLワークショップユーティリティよりクイックSQLを開き、上記のモデルで表を作成します。今回は表の作成後、アプリケーションの作成まで続けて実行します。

レビューおよび実行をクリックします。


SQLスクリプトスクリプト・エディタが開きます。スクリプト名を設定し、実行をクリックします。


即時実行をクリックします。


エラーがなくDDLの実行が完了していることを確認します。

アプリケーションの作成をクリックします。


確認画面が表示されるので、再度アプリケーションの作成をクリックします。


アプリケーション作成ウィザードが開きます。アプリケーションの名前JSON Formとします。表EBAJ_JSON_DATAEBAJ_JSON_SCHEMASを対象とした、フォーム付き対話モード・レポートのページが含まれています。

アプリケーションの作成をクリックします。


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


アプリケーションを実行し、フォームを生成する元となるJSONスキーマを登録します。

Json Schemasのページを開きます。


JSONスキーマはreact-jsonschemas-formのLive Playgroundからコピーします。

今回はSimpleUI Optionsについて、APEXアプリケーションに登録します。SimpleまたはUI Optionsを選択したときに表示されるJSONSchemaUISchemaおよびformDataをAPEXのフォームにコピペします。


Json Schemas作成をクリックし、フォームを開きます。Json SchemaUI SchemaおよびForm Dataを入力し、作成をクリックします。

Live PlaygroundSimpleUI Optionsを対象に、同じ作業を行います。


SimpleUI Optionsの双方とも、uiSchemaにてSubmitボタンを描画する設定になっています。SubmitボタンはAPEX側で作成するため、JSONのフォームでは不要です。SimpleではuiSchemaに以下の一行を含めます。

  "ui:submitButtonOptions": { "norender": true },

UI Optionsにはui:submitButtonOptionsの設定が含まれています。norenderの指定をfalseからtrueに変更しておきます。

Json Schemasのレポートに、登録されたスキーマSimpleとUI Optionsの2行が表示されます。


このスキーマより、表EBAJ_JSON_DATAの列CONTENTを対象としたフォームを生成します。

ページ・デザイナで、表EBAJ_JSON_DATAの対話モード・レポートのページ(ページ番号2)を開きます。このページにある作成ボタンおよびレポート行にある編集アイコンをクリックすると、表EBAJ_JSON_DATAを編集するフォームが開きます。そのフォーム上に、react-jsonschema-formを使ったフォームを組み込みます。

編集フォームを開く際に、列CONTENTのフォームを生成するJSON Schemaを選択するページ・アイテムを作成します。

識別名前P2_SCHEMA_IDタイプ選択リストラベルSchemaとします。設定選択時のページ・アクションとして値のリダイレクトと設定を選択します。

LOVタイプ共有コンポーネントを選択し、LOVとしてEBAJ_JSON_SCHEMAS.TITLEを選択します。このLOVはアプリケーション作成の元となったDDLに参照制約が含まれているため、自動的に生成されました。追加値の表示オフNULL値の表示オンとし、NULL表示値として- Select JSON Schema -を入力します。

値の選択を変えるたびに警告が表示されるのを抑止するため、詳細保存されていない変更の警告無視にします。


ボタン作成をクリックしたときに、ページ・アイテムP2_SCHEMA_IDとして選択した値をフォームに渡すようにします。

ボタンCREATEを選択し、動作ターゲットを開きます。


アイテムの設定名前としてP3_SCHEMA_IDとして&P2_SCHEMA_ID.を追加し、OKをクリックします。


以上で、react-jsonschema-formを組み込む準備ができました。

これから、フォームのページ(ページ番号3)に、react-jsonschema-formを組み込みます。

ページ・デザイナでページ番号3のフォームのページを開きます。

JSON Schemaを保持するページ・アイテムP3_JSON_SCHEMAを作成します。タイプ非表示です。セッション・ステートデータ型CLOBストレージリクエストごと(メモリーのみ)を選択します。


UI Schemaを保持するページ・アイテムP3_UI_SCHEMAを作成します。設定内容はP3_JSON_SCHEMAと同じです。


ページ・アイテムP3_JSON_SCHEMAP3_UI_SCHEMAおよびP3_CONTENTを初期化するプロセスを作成します。

レンダリング前ヘッダーの前にプロセスを作成します。識別名前Initialize JSON Formとします。タイプコードを実行です。

ソースPL/SQLコードとして以下を記述します。
declare
    l_form_data clob;
begin
    select
        json_schema, ui_schema, form_data
    into
        :P3_JSON_SCHEMA, :P3_UI_SCHEMA, l_form_data
    from ebaj_json_schemas
    where id = :P3_SCHEMA_ID;
    if :P3_CONTENT is null then
        :P3_CONTENT := l_form_data;
    end if;
end;

ページ・プロパティHTMLヘッダーに、Reactとreact-jsonschema-formを参照するためのimportmapを設定します。
<script type="importmap">
    {
        "imports": {
            "react": "https://cdn.jsdelivr.net/npm/react@18.3.1/+esm",
            "react-dom": "https://cdn.jsdelivr.net/npm/react-dom@18.3.1/+esm",
            "@rjsf/core": "https://cdn.jsdelivr.net/npm/@rjsf/core@5.20.1/+esm",
            "@rjsf/utils": "https://cdn.jsdelivr.net/npm/@rjsf/utils@5.20.1/+esm",
            "@rjsf/validator-ajv8": "https://cdn.jsdelivr.net/npm/@rjsf/validator-ajv8@5.20.1/+esm",
            "@rjsf/bootstrap-4": "https://cdn.jsdelivr.net/npm/@rjsf/bootstrap-4@5.20.1/+esm"
        }
    }
</script>
JavaScriptファイルURLにBabelをロードするURLを設定します。

https://cdn.jsdelivr.net/npm/@babel/standalone/babel.min.js


CONTENT(ページ・アイテムP3_CONTENT)に値を設定するフォームとなるリージョンを作成します。

識別名前JSON Formタイプ静的コンテンツです。ソースHTMLコードとして以下を記述します。



react-jsonschema-formのテーマとして、依存の少ないbootstrap-4を選んでいます。

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

https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css


以上で一通り動作するアプリケーションは完成です。ページ・アイテムP3_CONTENTは実際にはタイプ非表示にすべきですが、JSON Formのフィールドを操作したときに値が変更されることを目視するために、そのままにしておきます。

以上でアプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

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

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