2024年6月21日金曜日

Oracle APEXでhtmxを使用する

Oracle APEXのアプリケーションの作成にhtmxを使ってみます。

サンプル・アプリケーションを作成するにあたって、以下のサイトや記事を参考にさせていただきました。

htmxの本家にあるReference
https://htmx.org/reference/

@twrcd1227 (Tomoki Ota)さんによるQiitaの記事
もうjsなんていらない!世界で流行っているHTMXについてまとめてみたhttps://qiita.com/twrcd1227/items/7bce18167fb02ec22729

@tsmd (Takayuki Shimada)さんによるQiitaの記事
htmxとは何なのか? その背景にある思想について
https://qiita.com/tsmd/items/0d07feb8e02cfa213cc4

作成するアプリケーションは以下のように動作します。アプリケーション自体はhtmxを使わなければ作れない、というものではありません。htmxの面白いところは、JavaScriptを書かずに以下ような処理を実装できることです。


最初にクイックSQLの以下のモデルより、画像を保存する表EBMJ_IMAGESを作成します。
# prefix: ebmj
images /unique title
    title vc80 /nn
    content file
レビューおよび実行をクリックし、表が作成されるまで作業を進めます。


EBMJ_IMAGESが作成されたら、アプリケーションの作成をクリックします。確認画面が開くので、そこでもアプリケーションの作成をクリックします。


生成されたアプリケーションの雛形には、作成した表EBMJ_IMAGESをソースとしたフォーム付き対話モード・レポートのページが含まれています。これはそのまま使用します。htmxを使った画像の表示はホーム・ページに実装します。

アプリケーションの名前Sample htmxとし、アプリケーションの作成をクリックします。


アプリケーションが作成されます。対話モード・レポートフォームのページでのBLOB列の扱いを修正します。

ページ番号の対話モード・レポートのページを開きます。


リージョンImagesに含まれる列CONTENTを選択し、BLOB属性に含まれるMIMEタイプ列CONTENT_MIMETYPEファイル名列CONTENT_FILENAME最終更新列CONTENT_LASTUPD文字セット列CONTENT_CHARSETを設定します。


ページ番号のフォームのページを開きます。

リージョンImageに含まれるページ・アイテムP3_CONTENTを選択し、ストレージに含まれるMIMEタイプ列CONTENT_MIMETYPEファイル名列CONTENT_FILENAME文字セット列CONTENT_CHARSETBLOB最終更新列CONTENT_LASTUPDを設定します。


以上で表EBMJ_IMAGESに画像をアップロードする準備ができました。

アプリケーションを実行し、いくつか画像をアップロードします。

ナビゲーション・メニューからImagesを開き、レポート上の作成をクリックして適当な画像をアップロードします。


画像を選んでアップロードします。


その他にも、いくつかの画像をアップロードします。今回の作業では、たぬきシマウマレッサーパンダの画像をアップロードしています。


表EBMJ_IMAGESより、画像のタイトルを引数として与え、画像をHTMLのIMG要素として返すRESTサービスを作成します。

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

左ペインのツリーよりモジュールを選択し、モジュールの作成をクリックします。


作成するモジュール名sample.htmxベース・パス/htmx/とします。

モジュールの作成をクリックします。


モジュールsample.htmxが作成されます。続けてテンプレートを作成します。

テンプレートの作成をクリックします。


URIテンプレートとしてimage/:titleを設定します。:titleがハンドラのコード内で、バインド変数として参照できる引数になります。

テンプレートの作成をクリックします。


リソース・テンプレートが作成されます。続けてハンドラを作成します。

ハンドラの作成をクリックします。


リソース・ハンドラメソッドGETソース・タイプPL/SQLを選択します。ソースに以下を記述します。タイトルで表EBMJ_IMAGESを検索し取得した画像より、IMG要素を生成して呼び出し元に返しています。

ハンドラの作成をクリックします。


GETハンドラが作成されます。完全なURLをコピーし、ブラウザまたはPostmanなどのツールより、作成したRESTサービスが正常に動作することを確認します。


RESTサービスが正常に動作することを確認したのち、APEXで認証されたセッション内からの呼び出しに限り、実行を許可するように権限を設定します。

左ペインより権限を選択し、権限の作成をクリックします。


特権定義名前sample.htmxタイトルsample.htmxとします。ロールとしてRESTful Services保護されたモジュールとしてsample.htmxを選択します。

権限の作成をクリックします。


権限としてsample.htmxが作成されます。


サインインするユーザーにロールRESTful Servicesを割り当てます。

管理メニューよりユーザーとグループの管理を開きます。


権限を割り当てるユーザーの編集画面を開きます。


グループ割当てのセクションに移動し、グループ割当てとしてRESTful Servicesを選択します。

変更の適用をクリックします。


以上で作成したRESTサービスの保護が完了しました。

先ほど実施した動作確認を再度行います。今度は応答が401 Unauthorizedになります。


RESTfulサービスを使った作業は以上で完了です。

アプリケーション・ビルダーに移り、htmxを組み込んだページを作成します。

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

作成済みのリージョンページ・ナビゲーション削除します。


画像を表示するためのボタンを配置するリージョンを作成します。

識別名前Buttonsタイプ静的コンテンツです。外観テンプレートとしてButtons Containerを選択します。


画像を表示するリージョンを作成します。

識別名前Imageタイプ静的コンテンツです。外観テンプレートBlank with Attributes (No Grid)を選択し、CSSクラスとしてw800 h800 margin-autoを指定します。リージョンの幅と高さを800ピクセルに設定し、中央揃えにしています。

詳細静的IDとしてimageを設定します。


ページ内でhtmxの機能を使えるように構成します。

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

https://unpkg.com/htmx.org@2.0.0

ページ・ロード時に実行に以下を記述し、htmxがRESTサービスを呼び出す際に、認証に必要なApex-Sessionヘッダーを追加します。
document.body.addEventListener('htmx:configRequest', function(evt) {
    evt.detail.headers['Apex-Session'] = apex.env.APP_ID + ',' + apex.env.APP_SESSION;
});
表示する画像をリージョン内に収めるために、CSSインラインに以下を記述します。
img {
  max-width:100%;
  max-height: 100%;
  width: auto;
  height: auto;
}


以上でhtmxが提供する属性を要素に指定できるようになりました。

これから画像を表示するためのボタンを、リージョンButtonsに作成します。

識別ボタン名BUTTON1ラベルたぬきとします。たぬきの画像を表示するボタンになります。

動作のアクションとして動的アクションで定義を選択し、詳細のカスタム属性として以下を記述します。hx-gethx-targethx-swaphtmxが提供している属性です。

hx-get="apexdev/htmx/image/たぬき" hx-target="#image" hx-swap="innerHTML"


これでボタンたぬきをクリックすると、リージョンImageにたぬきの画像が表示されます。


シマウマの画像を表示するボタンを作成します。

識別ボタン名BUTTON2ラベルシマウマ詳細カスタム属性として以下を記述します。

hx-get="apexdev/htmx/image/シマウマ" hx-target="#image" hx-swap="innerHTML"


レッサーパンダの画像を表示するボタンを作成します。

識別ボタン名BUTTON3ラベルレッサーパンダ詳細カスタム属性として以下を記述します。

hx-get="apexdev/htmx/image/レッサーパンダ" hx-target="#image" hx-swap="innerHTML"


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

htmxには指定できる属性が他にも沢山あります。確かにJavaScriptを書かずに色々な処理を行なうことができるので、巷の話題にあがるのも納得できます。

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

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