2022年11月30日水曜日

APEX 22.2のアイテム・コンテナについて

 APEX 22.2よりリージョン・テンプレートにItem Containerが追加されました。APEX Office HourのPart 4: PWA, User and Developer Experienceの5:12より、開発者のVincent Morneauさんが紹介しています。

アイテム・コンテナにより、以下のようにボタンとアイテムを横一列に配置する際に、テンプレート・オプションで揃える位置を決めることができます。

以下は中央(Center)の例です。


APEX 22.2以前は、過去の記事に書きましたがCSSを定義する必要がありました。

アイテム・コンテナとは、外観テンプレートとしてItem Containerを選択した静的コンテンツのリージョンになります。


このリージョンを親としてボタンやページ・アイテムを配置します。ボタンを配置できる位置はButton StartButton End、ページ・アイテムを配置できる位置はItemです。他の位置には配置できません。

ボタンB_STARTを、Button Start位置に配置しています。


ページ・アイテムP1_ITEMは位置Itemに配置されます。


ボタンB_ENDは、Button End位置に配置しています。


ライブ・テンプレート・オプションを使って、テンプレートとしてItem Containerを指定しているリージョンのテンプレート・オプションを変更してみます。


AlignmentとしてCenterを選択した場合です。


AlignmentとしてStartを選択すると、上揃えになります。


AlignmentとしてEndを選択すると、下揃えになります。


Stretchを選択すると、ボタンの高さがアイテムの高さと同じになります。


Wrap Itemsにチェックを入れると、画面幅が狭い時にアイテムが回り込みます。



Stick On Mobile
にチェックが入っていると、コンポーネントの配置は以下のようになります。

アイテム・コンテナの紹介は以上になります。

アイテム・コンテナに含むボタンやページ・アイテムを作成するときの注意点です。

アイテム・コンテナのリージョンのコンテキスト・メニューよりボタンやページ・アイテムを作成しても、レイアウトリージョン親なしになり、コンテキスト・メニューを開いたリージョンになりません


リージョンとしてアイテム・コンテナを設定していないと位置を選択できないため、手動でリージョンを選択します。


リージョンとしてアイテム・コンテナが選択されると、位置を選択できるようになります。


以上です。

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

2022年11月29日火曜日

CSSのhas擬似クラスを使ったレポートのセルの色付け

 対話モード・レポートのセルに色を付けるために、対話モード・レポートのリフレッシュ後にJavaScriptを実行しているのだけど実装として今ひとつ。もっと良い方法は無いものか?という話がありました。

対話モード・レポートとしては以下のようになります。一番上はJavaScriptでセルに色付けを行っています。真ん中は対話モード・レポートの標準的な機能の範囲での実装です。最後はCSSの擬似クラスhasを使っています。


対話モード・レポートのソースとなるSELECT文は、すべて同じです。Oracle APEXに付属しているサンプル・データセットEMP/DEPTに含まれる表EMPをソースとしています。

給与(列SALのデータ)が1000より少ない時に列COLORの値がredになります。
select EMPNO,
       ENAME,
       JOB,
       MGR,
       HIREDATE,
       SAL,
       COMM,
       DEPTNO
       , case
       when sal < 1000 then 'red'
       else ''
       end color
  from EMP


APEXの標準の範囲での実装


SAL列の書式HTML式として、以下を設定しています。

<span style="background-color:#COLOR#;">#SAL#</span>


この設定で、列SALの値の背景色が赤になります。APEXでは、その親の要素の属性を変更する方法が提供されていないため、TD要素の背景色を変更できません。

結果として、セル全体の背景色の設定ができていません。


JavaScriptによる実装



JavaScriptによってセルの背景色を変更するために、列SALdata-color属性として色情報を含めるようにします。これも列の書式HTML式として設定します。

<span data-color="#COLOR#">#SAL#</span>


対話モード・レポートのリフレッシュ後に、動的アクションとして以下のJavaScriptを実行します。data-colorとして定義した値を、親の要素の背景色として設定しています。

document.querySelectorAll("#emp0 span[data-color]").forEach(
    (e) => {
        e.parentElement.style.backgroundColor = e.dataset.color;
    }
);
動的アクションは、初期化時にも実行するように設定します。


以上でセルの背景色が設定されます。


CSSの擬似クラスhasによる実装



動的アクションを作成する代わりに、ページ・プロパティCSSインラインに以下を記述します。
#emp2 td:has(span[data-color=red]) {
    background-color: red;
}

擬似クラスhasはFirefoxではまだサポートされていないようで、使うべきかどうかは迷うところではあります。それでもCSSで設定できるほうが、JavaScriptよりは有望です。

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

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

対話モード・レポートでのテンプレート・ディレクティブの利用

 APEX 22.2より対話モード・レポートとクラシック・レポートでもテンプレート・ディレクティブが利用できるようになりました。

今までは条件ごとに列の表示を切り替えるために、主にCASE句を使用していました。これだとレポートのSELECT文が非常に見難くなります。

APEX 22.2より対話モード・レポートとクラシック・レポートで使用できるようになったテンプレート・ディレクティブにより、レポートのソースのSELECT文がどのように変わるか以下に紹介します。

アプリケーションのページに対話モード・レポートを3つ作成しています。最初の対話モード・レポートデフォルトは表SAMPLE_FILESにテスト・データを投入するために使用します。ページ作成ウィザードによって作成されたフォーム付き対話モード・レポートです。

対話モード・レポート従来の実装では、レポートのソースのSELECT文にCASE句を使っています。対話モード・レポートテンプレート・ディレクティブでは、レポートのソースのSELECT文ではなくテンプレート・ディレクティブで列の表示を切り替えています。

どちらも表示上は同じになっています。


表SAMPLE_FILESの作成


クイックSQLの以下のモデルより、表SAMPLE_FILESを作成しています。

# prefix: sample
files
    name vc80 /nn
    url vc400
    content file

生成されるDDLは以下になります。
create table sample_files (
    id                             number generated by default on null as identity 
                                   constraint sample_files_id_pk primary key,
    name                           varchar2(80 char) not null,
    url                            varchar2(400 char),
    content                        blob,
    content_filename               varchar2(512 char),
    content_mimetype               varchar2(512 char),
    content_charset                varchar2(512 char),
    content_lastupd                date
)
;
今回実装するレポートの列Nameに、以下の設定を行ないます。

列CONTENTにBLOBのデータが保存されている場合は、NameをクリックするとBLOBのデータをダウンロードします。そうでない場合は列URLを開きます。

また、列CONTENT_MIMETYPEよりファイルタイプに応じたアイコンを表示します。


従来の実装



従来の実装でのソースです。




レポートに現れる列はNAMEとTYPEですが、これらは両方ともHTMLなのでセキュリティ特殊文字のエスケープOFFにする必要があります。アプリケーションの安全性が下がります。


また列フィルタタイプとしてデフォルトの列タイプに基づくデフォルトが選択されていると、列のデータ(HTMLのA要素)がそのまま検索条件やソートの条件に使用されます。




テンプレート・ディレクティブ



テンプレート・ディレクティブの使用を前提とした、ソースのSELECT文です。



DOWNLOAD_URLEXTERNAL_URLFILE_EXISTが追加されています。列NAMEとTYPEにテンプレート・ディレクティブを使ったHTML式を記述する際に使用しますが、表示は不要です。これらの列の識別タイプ非表示にします。


NAME列の書式HTML式として、以下を記述します。



先頭の1行はコメントです。

{!#FILE_EXIST#/}

本来であればこの行が無くても同じ動作になるのですが、if文の条件に非表示文字列が使用されていると正しく認識されないという不具合があり、そのワークアラウンドとして先頭に非表示列を含むコメント行を含めています。

TYPEHTML式です。




列NAMEとTYPEともに検索結果のデータ自体はHTMLではないため、セキュリティ特殊文字のエスケープOFFにする必要はありません。より安全な実装になっています。

また、列フィルタの値もHTMLにはなりません。


列TYPEの列フィルタの値は、アイコンではなくMIMEタイプの文字列が表示されます。アイコンでは検索やソートはできないので、文字列が表示される方が実用的といえます。


対話モード・レポートでのテンプレート・ディレクティブの利用方法の紹介は以上になります。

今回使用したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/new-222-template-directive.zip

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

Oracle APEXの環境作成(12) - パッチの適用

更新: 2026年1月28日

Oracle APEXの最新の修正は、My Oracle Supportよりダウンロードすることができます。

https://www.oracle.com/tools/downloads/apex-downloads.html

Patch Set Bundleのリンクをクリックすると、My Oracle Supportのパッチ詳細のページへリダイレクトされます。パッチをダウンロードするには、登録されているアカウントによるサインインが必要です。

2026年1月28日時点でダウンロードできたファイルはp37366599_2420_Generic.zipでした。このパッチをAPEX 24.2の環境に適用します。


現行の確認


開発環境にサインインし、ヘルプ情報を開きます。

詳細製品のバージョン番号を確認します。


最初のスクリーンショットの画面に以下の記述があります。最新のパッチを適用すると製品のバージョンは24.2.13に変わります。現状は24.2.0なので、パッチは未適用であることがわかります。
The Patch Set Bundle was last updated on January 26, 2026 and its PATCH_VERSION is 13. When this patch is applied, the APEX product version will be updated to 24.2.13.
Oracle APEXが実行されているデータベース・サーバーからインターネットへの接続ができるようになっていると、開発環境のトップ画面にパッチが利用可能であることが表示されます。


インスタンス・パラメータIMAGE_PREFIXの値も確認します。データベースにSYSで接続し、APEX_INSTANCE_ADMIN.GET_PARAMETERを実行します。

exec dbms_output.put_line(apex_instance_admin.get_parameter('IMAGE_PREFIX'));

[oracle@apex-arm ~]$ . oraenv

ORACLE_SID = [FREE] ? 

The Oracle base remains unchanged with value /opt/oracle

[oracle@apex-arm ~]$ sqlplus sys/********@localhost/freepdb1 as sysdba


SQL*Plus: Release 23.26.0.0.0 - Production on Wed Jan 28 20:08:51 2026

Version 23.26.0.0.0


Copyright (c) 1982, 2025, Oracle.  All rights reserved.



Connected to:

Oracle AI Database 26ai Free Release 23.26.0.0.0 - Develop, Learn, and Run for Free

Version 23.26.0.0.0


SQL> set serveroutput on

SQL> exec dbms_output.put_line(apex_instance_admin.get_parameter('IMAGE_PREFIX'));

/i/24.2.0/


PL/SQL procedure successfully completed.


SQL> 


APEXの静的ファイルの位置として、ローカルのファイルシステムを指している場合(/i/24.2.0/)と、CDN(https://static.oracle.com/cdn/apex/24.2.0/)を指している場合でパッチの適用作業は変わります。


パッチの適用


パッチの適用方法は、パッチを解凍したディレクトリに含まれるREADME.txtに記載されています。パッチごとに手順が違う場合もあり得るので、README.txtは必ず確認します。

ユーザーoracleにて作業を行います。パッチのファイルは/tmp以下にアップロードしておきます。

最初にパッチ・ファイルp37366599_2420_Generic.zipunzipコマンドで解凍します。zipファイルが解凍されて、ディレクトリ34628174が作成されます。

unzip -q /tmp/p37366599_2420_Generic.zip
ls 37366599/


[oracle@apex-arm ~]$ unzip -q /tmp/p37366599_2420_Generic.zip 

[oracle@apex-arm ~]$ ls 37366599/

catpatch_appcon.sql           wwv_flow_approval.plb

catpatch_con.sql              wwv_flow_authentication_dev.plb

catpatch.sql                  wwv_flow_authentication_native.plb

copyu.plb                     wwv_flow_authentication.plb

corepatch.sql                 wwv_flow_automation.plb

devpatch.sql                  wwv_flow_branch.plb

f8842.242.sql                 wwv_flow_builder.plb

flowc.plb                     wwv_flow_cdn.plb

flows_release.sql             wwv_flow_copy_page.plb

flowu.plb                     wwv_flow_data_profile_dev.plb

gen_api_pkg.plb               wwv_flow_debug.plb

generate_ddl.plb              wwv_flow_doc_src_dev.plb

images                        wwv_flow_error.plb

imp_parser.plb                wwv_flow_event_metrics_int.plb

meta.plb                      wwv_flow_exec_doc_src.plb

modules                       wwv_flow_exec_web_src_boss.plb

null1.sql                     wwv_flow_exec_web_src_http.plb

patch_36293226_dev.sql        wwv_flow_f4000_util.plb

patch_36774907_dev.sql        wwv_flow_file_editor_dev.plb

patch_37086304.sql            wwv_flow_fnd_developer_api.plb

patch_37155423_dev.sql        wwv_flow_hint.plb

patch_37355551.sql            wwv_flow_imp_page.plb

patch_37377364.sql            wwv_flow_imp_shared.plb

patch_37403215_dev.sql        wwv_flow_instance_admin.plb

patch_37473871.sql            wwv_flow_ir.plb

patch_37512460_dev.sql        wwv_flow_mail.plb

patch_37553042_dev.sql        wwv_flow_maint_dev.plb

patch_37579661.sql            wwv_flow_maint.plb

patch_37588311_dev.sql        wwv_flow_native_item.plb

patch_37751502.sql            wwv_flow_pdf.plb

patch_37791306.sql            wwv_flow_plugin_dev.plb

patch_37809911_dev.sql        wwv_flow_print_util.plb

patch_37830514.sql            wwv_flow_process_bg.plb

patch_37858190.sql            wwv_flow_pwa.plb

patch_37859062.sql            wwv_flow_report_query_dev.plb

patch_37859249.sql            wwv_flow_report_query.plb

patch_37952347.sql            wwv_flow_security.plb

patch_37967372.sql            wwv_flow_session.plb

patch_38279730_dev.sql        wwv_flow_session_state.plb

patch_38320934.sql            wwv_flow_sw_parser.plb

patch_38559097.sql            wwv_flow_theme_manager.plb

patch_38596648.sql            wwv_flow_translation_util_api.plb

patch_38669716_dev.sql        wwv_flow_upgrade.plb

patch_38726720.sql            wwv_flow_web_services_invoker.plb

patch_38840925.sql            wwv_flow_web_src_openapi.plb

patch_central_themes.sql      wwv_flow_web_src_sync.plb

provision.plb                 wwv_flow_wf_management.plb

README.txt                    wwv_flow_workflow.plb

reports3.plb                  wwv_flow_working_copy_dev.plb

validate_apex.sql             wwv_imp_workspace.plb

wwv_dictionary_cache_dev.plb  wwv_meta_meta_data.plb

wwv_flow_ai_dev.plb           wwv_sample_dataset.plb

wwv_flow_ai.plb               wwv_util_apex.plb

[oracle@apex-arm ~]$ 

作成されたディレクトリ37366599へ移動します。環境変数NLS_LANGおよびその他の環境変数を設定します。

[oracle@apex-arm ~]$ cd 37366599

[oracle@apex-arm 37366599]$ . oraenv

ORACLE_SID = [oracle] ? FREE

The Oracle base has been set to /opt/oracle

[oracle@apex-arm 37366599]$ export NLS_LANG=American_America.AL32UTF8

[oracle@apex-arm 37366599]$ 

パッチの適用前にOracle REST Data Servicesを停止します。systemctl stop ordsを実行します。

systemctl stop ords

[oracle@apex-arm 37366599]$ systemctl stop ords

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====

Authentication is required to stop 'ords.service'.

Authenticating as: root

Password: ********

==== AUTHENTICATION COMPLETE ====

[oracle@apex-arm 37366599]$ 


APEXがインストールされているPDBにSYSで接続し、catpatch.sqlを実行します。

[oracle@apex-arm 37366599]$ sqlplus sys/*******@localhost/freepdb1 as sysdba


SQL*Plus: Release 23.26.0.0.0 - Production on Wed Jan 28 20:23:41 2026

Version 23.26.0.0.0


Copyright (c) 1982, 2025, Oracle.  All rights reserved.



Connected to:

Oracle AI Database 26ai Free Release 23.26.0.0.0 - Develop, Learn, and Run for Free

Version 23.26.0.0.0


SQL> @catpatch.sql


. ORACLE

.

. Oracle APEX 24.2.%

. Patch Set Exception 37366599

........................................


APEX_VERSION

------------------------------

APEX_SCHEMA

--------------------------------------------------------------------------------

24.2.0

APEX_240200




PL/SQL procedure successfully completed.


... Syncing with Post-Upgrade Job


PL/SQL procedure successfully completed.


... Disabling Jobs


[中略]


PL/SQL procedure successfully completed.


... Enabling Jobs


PL/SQL procedure successfully completed.


...Validating APEX

...(20:24:28) Starting validate_apex for APEX_240200

...(20:24:28) Checking missing privileges for APEX_240200

...(20:24:29) Checking missing privileges for APEX_GRANTS_FOR_NEW_USERS_ROLE

...(20:24:29) Re-generating APEX_240200.wwv_flow_db_version

... wwv_flow_db_version is up to date

...(20:24:29) Checking for sys.wwv_flow_cu_constraints

...(20:24:29) Checking invalid public synonyms

...(20:24:29) Key object existence check

...(20:24:29) Post-ORDS updates

...(20:24:30) calling wwv_util_apex_240200.post_ords_upgrade

...enabled_schema

...define_module

...define_template

...define_handler

...set_module_origins_allowed

...(20:24:30) Setting DBMS Registry for APEX to valid

...(20:24:30) Exiting validate_apex


PL/SQL procedure successfully completed.


...Recompiling invalid public synonyms


PL/SQL procedure successfully completed.



PL/SQL procedure successfully completed.


timing for: Complete Patch 37366599

Elapsed: 00:00:37.66

Disconnected from Oracle AI Database 26ai Free Release 23.26.0.0.0 - Develop, Learn, and Run for Free

Version 23.26.0.0.0

[oracle@apex-arm 37366599]$ 


catpatch.sqlによるパッチ適用開始初期に適用前の状況が画面に出力されます。catpatch.sqlが終了する前に、インストールの検証(Validating APEX)が実行されます。

再度、データベースに接続しパッチの適用状況を確認します。

select patch_number, patch_version, installed_on from apex_patches order by installed_on;

SQL> select patch_number, patch_version, installed_on from apex_patches order by installed_on;


PATCH_NUMBER PATCH_VERSION     INSTALLED_ON

------------ ------------------------------ -------------------

    37366599 13     2026-01-28 20:24:30


SQL> 


問題がなければcatpatch.sqlの実行は完了です。

ローカルのファイルシステムに静的ファイルが配置されている場合は、パッチに含まれているファイルに置き換えます。

imagesの下にあるファイルをIMAGE_PREFIXとなっているディレクトリに上書きします。

cp -r -p images/* /home/oracle/i/24.2.0/

[oracle@apex-arm 37366599]$ cp -r -p images/* /home/oracle/i/24.2.0/

[oracle@apex-arm 37366599]$ 


CDNを参照している場合は、IMAGE_PREFIXをダウンロードのページに記載のあるCDN URLに更新します。変更が必要な場合は、APEX_INSTANCE_ADMIN.SET_PARAMETERを実行しIMAPGE_PREFIXを更新します。

exec apex_instance_admin.set_parameter('IMAGE_PREFIX','https://static.oracle.com/cdn/apex/24.2.13/');

以上でパッチ適用が完了しました。Oracle REST Data Servicesを起動します。

systemctl start ords

[oracle@apex-arm 37366599]$ systemctl start ords

==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====

Authentication is required to start 'ords.service'.

Authenticating as: root

Password: ********

==== AUTHENTICATION COMPLETE ====

[oracle@apex-arm 37366599]$ 

最初に確認したヘルプの情報の製品のバージョン情報も24.2.13へ更新されます。


最後にアップロードしたパッチ・ファイルを削除します。

[opc@apex-arm ~]$ rm /tmp/p37366599_2420_Generic.zip 

[opc@apex-arm ~]$