ラベル カード の投稿を表示しています。 すべての投稿を表示
ラベル カード の投稿を表示しています。 すべての投稿を表示

2022年12月13日火曜日

画像ビューワーのアプリを改良する

以前の記事で作成した、画像をオブジェクト・ストレージにアップロードするアプリを少々手直ししてみました。

元記事は以下になります。

APEXアプリに埋め込む画像をオブジェクト・ストレージに配置する
http://apexugj.blogspot.com/2022/09/image-viewer-preauth-obs.html


ファイル選択の代わりにカメラを起動


タイプがファイル参照...のページ・アイテムP2_IMAGEの詳細のカスタム属性として、以下を記述します。

capture="environment" accept="image/*"


これでスマホからファイル選択を行なった場合、背面カメラが起動します。

ファイル選択のダイアログが画面いっぱいで開くよう、ページ番号2の外観のテンプレート・オプションを開きます。


Stretch to Fit Windowにチェックを入れます。




ファイルを送信する前にプレビューを表示


非表示のページ・アイテムP2_URLを作成します。これは、カメラで写真をとったときのプレビューには使用しません。


プレビューを表示するリージョンを作成します。

識別のタイトルはPreview、タイプに静的コンテンツを選択します。ソースのHTMLコードとして以下を記述します。

<img id="preview" src="&P2_URL."></img>

外観のテンプレートとして、装飾のないBlank with Attributesを選択します。


画像のプレビューを表示するので、ページ・アイテムP2_IMAGEのファイルの選択はシンプルな表示形式のNative File Browseに変更します。


ページ・アイテムP2_IMAGEでファイルが選択されたときに、動的アクションを実行します。

タイミングのイベントは変更、選択タイプはアイテム、アイテムはP2_IMAGEのときに、アクション選択した画像のプレビューを実行します。


アクション選択した画面のプレビューのアクションはJavaScriptコードの実行、設定のコードとして以下を記述します。



プレビューとして表示する画像のサイズを画面の横幅に合わせます。ページ・プロパティのCSSのインラインに以下を記述します。
#preview {
    width: 100%;
}

以上で完了です。

PCからの実行なのでカメラは起動しませんが、選択した画像のプレビューが表示されます。




編集時に画像を表示



フォームのページのレンダリング前のヘッダーの前にプロセスを作成します。ページ・アイテムP2_URLにオブジェクト・ストレージに保存されている画像のURLを設定します。

識別の名前は画像URLの取得とします。タイプはコードの実行を選択し、コードとして以下を記述します。
select :G_PREAUTH_URL || g.location into :P2_URL
from img_items i join 
(
    select id, item_id, location, file_name, mime_type from
        (
            select
                row_number() over (partition by item_id order by last_updated desc) rn,
                id, item_id, location, file_name, mime_type
            from img_images
        )
    where rn = 1
) g on i.id = g.item_id
where i.id = :P2_ID;
ファイルの更新または削除時に実行されるように限定するため、サーバー側の条件のタイプにアイテムはNULLではないを選択し、アイテムとしてP2_IDを指定します。

以上で対応完了です。以下のように動作します。




現在位置を保存



APEX 22.2から、動的アクションの現在の位置の取得が追加されました。この機能を使って、画像を選択した場所を表IMG_ITEMSに保存します。

列CURRENT_LOCATIONを追加します。

alter table img_items add (current_location varchar2(400));

GeoJSONで保存する予定ですが、サンプルなので列の型はVARCHAR2にしています。

ページ番号2にあるフォーム・リージョンのImg Itemで、ページ・アイテムの同期化を実行します。フォームにページ・アイテムP2_CURRENT_LOCATONが追加されます。識別のタイプを非表示に変更します。

動的アクションによって値を設定するため、設定の保護された値はOFFにします。


動的アクションの画像の選択にTRUEアクションを追加します。

識別のアクションとして現在の位置の取得を選び、設定の戻り値としてGeoJSON、アイテムとしてP2_CURRENT_LOCATIONを選択します。


取得した位置をカードに表示するため、カード・リージョンのソースを変更します。
select i.id, i.name, :G_PREAUTH_URL || g.location location, g.file_name, i.current_location
from img_items i join 
(
    select id, item_id, location, file_name, mime_type from
        (
            select
                row_number() over (partition by item_id order by last_updated desc) rn,
                id, item_id, location, file_name, mime_type
            from img_images
        )
    where rn = 1
) g on i.id = g.item_id

列の同期化を行い、カード・リージョンの属性のサブタイトルの列としてCURRENT_LOCATIONを選択します。


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

写真のExifからではありませんが、撮影場所の座標を取得することができます。


APEXの処理はOracle Databaseで行われるため、バイナリ・データの操作は得意ではありません。画像などは、オブジェクト・ストレージに配置した際にイベント・サービスなどを使って処理した方が良いと思います。

以上です。

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

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

完

カード上のボタンをクリックしてJavaScriptを実行する

  カード・リージョンでは、個々のカードにたいしてアクションを作成できます。作成できるアクションのタイプは以下の3つで、動的アクションはありません。

  1. このアプリケーションのページにリダイレクト
  2. 別のアプリケーションのページにリダイレクト
  3. URLにリダイレクト
APEX 22.2よりインターフェースactionsが追加され、ボタンやリンクのクリックからapex.actionsに登録したJavaScriptのコードが実行できるようになりました。

以下より、actionsインターフェースを使って、カード上のボタンをクリックしてJavaScriptを呼び出す実装を行なってみます。

サンプル・データセットのEMP/DEPTをデータ・ソースとして使い、以下の動作を行うAPEXアプリケーションを作成します。

従業員名に隣にある鉛筆アイコンをクリックするか、またはボタンの従業員番号の設定をクリックすると、従業員番号のテキスト・フィールドに従業員番号を設定します。


アプリケーション作成ウィザードを起動します。アプリケーションの名前はカードアクションとしました。

デフォルトで作成されているホーム・ページを(編集をクリックして)削除し、ページの追加をクリックしてカードのページを追加します。


追加するカードのページ名もカードアクションとします。表またはビューとしてEMPを選択し、レイアウトはグリッドを選択します。タイトル列はENAME、本体列はJOBを指定し、ページの追加をクリックします。


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

アプリケーションが作成されます。これから、カードアクションのページにアクションを実装していきます。


ページ・デザイナにてページ番号1のカードアクションを開きます。

従業員番号を設定するページ・アイテムを、Breadcrumb Barのカードアクションのリージョンに作成します。

識別の名前はP1_EMPNOです。タイプとしてテキスト・フィールドを選択します。ラベルは従業員番号とします。


ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言に、ボタンのクリックで呼び出されるAPEXアクションを記述します。引数empnoに渡された従業員番号をページ・アイテムP1_EMPNOに設定します。

ページ・ロード時に実行に以下の一行を記述します。

apex.actions.add(PAGE_ACTIONS_EMPCARD);


カードのアクションとしてボタン従業員番号の設定を作成します。

識別のタイプはボタン、ラベルは従業員番号の設定とします。リンクのタイプにURLにリダイレクトを選択し、ターゲットとして以下を記述します。

#action$setempno?empno=&EMPNO.

このターゲットの指定により、APEXアクションとして登録されているsetempnoが呼び出され、従業員番号がページ・アイテムP1_EMPNOに設定されます。


従業員名の横に表示されている鉛筆アイコンのボタンは、ボタン・ビルダーを使ってHTMLを生成します。

Button Builder - Universal Theme (oracle.com)

https://apex.oracle.com/pls/apex/apex_pm/r/ut/button-builder

今回の設定は以下です。Button TemplateはIcon、Button LabelはEdit (表示はされません)、Icon Classとしてfa-pencil、StyleをRemove UI Decorationsを選んでいます。

上記の設定で生成されたEntire Markupを使用します。


生成されたマークアップをカードに設定します。

カード・リージョンの属性を開き、タイトルを拡張フォーマットに切り替えます。

HTML式として記述するマークアップには、以下のdata-actionカスタム属性を追加します。

data-action="setempno?empno=&EMPNO."

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

a要素ではhref属性として"#action$アクション名"で呼び出すアクションを指定します。button要素ではカスタム属性data-action="アクション名"で呼び出すアクションを指定します。

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

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

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

完