作成するアプリケーションは以下のように動作します。フォームを生成するJSON Schemaを選択し、APEXのフォーム(ドロワーとして実装)を開きます。開いたフォームは、選択したJSON Schemaから生成されたフォームを含みます。以下のGIF動画では、JSON SchemaとしてSimpleとUI Optionsのどちらかを選んでいて(react-jsonschema-formのLive Playgroundから拝借しています)、選択によってフォームに表示される項目が変わります。JSON Formの領域に含まれている項目は、JSON形式でひとつの列に保存されます。
クイックSQLの以下のモデルを元に、表EBAJ_JSON_DATAとEBAJ_JSON_SCHEMASを作成します。
表EBAJ_JSON_DATAの列CONTENTにJSON形式でデータを保存します。この列に保存するデータを入力するフォームを、表EBAJ_JSON_SCHEMASの列JSON_SCHEMA(JSON列の制約となるJSON Schema定義)と列UI_SCHEMA(UIの定義)から動的に生成します。列FORM_DATAはCONTENTに保存する初期値です。
# 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_DATAとEBAJ_JSON_SCHEMASを対象とした、フォーム付き対話モード・レポートのページが含まれています。
アプリケーションの作成をクリックします。
アプリケーションが作成されます。
アプリケーションを実行し、フォームを生成する元となるJSONスキーマを登録します。
Json Schemasのページを開きます。
JSONスキーマはreact-jsonschemas-formのLive Playgroundからコピーします。
今回はSimpleとUI Optionsについて、APEXアプリケーションに登録します。SimpleまたはUI Optionsを選択したときに表示されるJSONSchema、UISchemaおよびformDataをAPEXのフォームにコピペします。
Json Schemasの作成をクリックし、フォームを開きます。Json Schema、UI SchemaおよびForm Dataを入力し、作成をクリックします。
Live PlaygroundのSimpleとUI Optionsを対象に、同じ作業を行います。
Simple、UI 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を選択し、動作のターゲットを開きます。
以上で、react-jsonschema-formを組み込む準備ができました。
これから、フォームのページ(ページ番号3)に、react-jsonschema-formを組み込みます。
ページ・デザイナでページ番号3のフォームのページを開きます。
JSON Schemaを保持するページ・アイテムP3_JSON_SCHEMAを作成します。タイプは非表示です。セッション・ステートのデータ型はCLOB、ストレージはリクエストごと(メモリーのみ)を選択します。
UI Schemaを保持するページ・アイテムP3_UI_SCHEMAを作成します。設定内容はP3_JSON_SCHEMAと同じです。
レンダリング前のヘッダーの前にプロセスを作成します。識別の名前は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コードとして以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="container"></div> | |
<script type="text/babel" data-presets="react" data-type="module"> | |
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
import Form from '@rjsf/bootstrap-4'; | |
import RJSFSchema from '@rjsf/utils'; | |
import validator from '@rjsf/validator-ajv8'; | |
const schema = JSON.parse(apex.item("P3_JSON_SCHEMA").getValue()); | |
const uiSchema = JSON.parse(apex.item("P3_UI_SCHEMA").getValue()); | |
const formData = JSON.parse(apex.item("P3_CONTENT").getValue()); | |
class App extends React.Component { | |
render() { | |
return ( | |
<> | |
<Form | |
schema={schema} | |
uiSchema={uiSchema} | |
formData={formData} | |
validator={validator} | |
onChange={(e) => { | |
apex.item("P3_CONTENT").setValue(JSON.stringify(e.formData)); | |
}} | |
/> | |
</> | |
); | |
} | |
} | |
/* render React component within an APEX region */ | |
const container = document.getElementById("container"); | |
const root = ReactDOM.createRoot( container ); | |
root.render( <App /> ); | |
</script> |
react-jsonschema-formのテーマとして、依存の少ないbootstrap-4を選んでいます。
CSSのファイルURLとして、以下のURLを指定します。
https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css
以上でアプリケーションを実行すると、記事の先頭のGIF動画のように動作します。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/json-form-react-jsonschema-form.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完