2021年8月3日火曜日

日付データの変換

 YYYY/MM/DDのフォーマットでページ・アイテムに入力した日付を、YYYY/MM/DD(DY)に変換したいとの相談がありました。

Oracle APEX 21.1より日付と数値として入力した値は、すぐに書式マスクが適用されます。

ですので、以下の方法は21.1以前のバージョンでのみ有効です。


PL/SQLでの日付データの変換


ページ・アイテムP1_DATEPがあり、タイプ日付ピッカーとします。書式マスクYYYY/MM/DD(DY)を指定します。

日付ピッカーを使って日付を入力すると書式マスクに沿った値が設定されますが、手動で入力するときには曜日の指定は省きたいです。そのため、YYYY/MM/DDを入力したらYYYY/MM/DD(DY)に変換します。

ページ・アイテムP1_DATEPに動的アクションを作成します。タイミングイベント変更です。

TRUEアクション値の設定とし、設定タイプの設定としてPL/SQL Function Bodyを選択します。PL/SQL Function Bodyとして以下を記述します。

declare
l_valid number;
l_date varchar2(20);
begin
select validate_conversion(:P1_DATEP as date, 'YYYY/MM/DD(DY)') into l_valid
from dual;
if l_valid = 1 then
-- 変換不要
return :P1_DATEP;
end if;
l_date := substr(:P1_DATEP,1,10);
select validate_conversion(l_date as date, 'YYYY/MM/DD') into l_valid
from dual;
if l_valid = 1 then
-- 曜日を追加する
return to_char(to_date(l_date,'YYYY/MM/DD'), 'YYYY/MM/DD(DY)');
end if;
-- それ以外はそのまま
return :P1_DATEP;
end;

送信するアイテムP1_DATEPを指定します。特殊文字をエスケープOFF変更イベントの禁止ONにします。P1_DATEPが変更された際にP1_DATEPを変更しているため、変更イベントを禁止しないと動的アクションが呼び出され続けます。影響を受ける要素アイテムP1_DATEPです。

これで日付データは変更されます。ただし、変更の際にはP1_DATEPの値がブラウザからデータベース・サーバーに送信され、PL/SQLコードが実行された結果がブラウザに返されるという動作になります。そのためレスポンスはよくありません。


JavaScriptでの日付データの変換


ブラウザ側で日付データを変換してみます。Dayjsというライブラリを使用します。

最初に必要なライブラリをロードします。今回はページでロードします。ページ・プロパティのJavaScriptファイルURLとして以下を指定します。

https://unpkg.com/dayjs@1.8.21/dayjs.min.js

https://unpkg.com/dayjs@1.8.21/locale/ja.js

ページ・ロード時にライブラリを日本語で初期化します。ページ・ロード時に実行に以下を記述します。

dayjs.locale('ja')


動的アクションはPL/SQLと同様ですが、TRUEアクションとしてJavaScriptコードの実行を選択します。設定コードとして以下を記述します。

let ds = apex.item("P1_DATEJ").getValue();
if (dayjs(ds,"YYYY/MM/DD").isValid())
{
let dt = dayjs(ds, "YYYY/MM/DD").format("YYYY/MM/DD(dd)");
// 第3引数のpSuppressChangeEventはtrue
apex.item("P1_DATEJ").setValue(dt,dt,true);
}

apex.item("P1_DATEJ").setValue()を呼び出してブラウザ上のページ・アイテムに直接値を設定しているため、影響を受ける要素の指定は不要です。また、第3引数のpSuppressChangeEventtrueを渡すことにより、変更イベントが禁止されます。


以上で日付データが変更されます。

ページ・アイテムの値を動的アクションによって変更するときは、変更イベントの禁止の設定に注意しましょう。

以上になります。

確認に使用したアプリケーションのエクスポートを以下に置きました。

https://github.com/ujnak/apexapps/blob/master/exports/date-format-conversion.sql

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