2022年7月15日金曜日

日付ピッカーにて日本の祝日を選択不可にする

2024年6月10日追記:

Oracle APEX 22.2より日付ピッカーの実装が置き換えられています。APEX 22.2以降での実装の紹介は、こちらの記事「 APEX 22.2の日付ピッカーに日本の休日を設定する」になります。

追記終わり

日付ピッカーで特定の日付を選択できないようにするには?という質問があったので、試しに実装してみました。日本の祝日を選択不可にします。

最初に日本の祝日の情報をデータベースにロードします。以下のスクリプトを実行します。

create table holidays(holiday_name varchar2(80) not null, holiday_date date not null);
insert into holidays(holiday_name, holiday_date) values('元日',to_date('22-01-01','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('成人の日',to_date('22-01-10','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('建国記念の日',to_date('22-02-11','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('天皇誕生日',to_date('22-02-23','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('春分の日',to_date('22-03-21','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('昭和の日',to_date('22-04-29','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('憲法記念日',to_date('22-05-03','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('みどりの日',to_date('22-05-04','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('こどもの日',to_date('22-05-05','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('海の日',to_date('22-07-18','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('山の日',to_date('22-08-11','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('敬老の日',to_date('22-09-19','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('秋分の日',to_date('22-09-23','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('スポーツの日',to_date('22-10-10','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('文化の日',to_date('22-11-03','RR-MM-DD'));
insert into holidays(holiday_name, holiday_date) values('勤労感謝の日',to_date('22-11-23','RR-MM-DD'));
commit;
view raw holidays.sql hosted with ❤ by GitHub

SQLワークショップSQLスクリプトで実行すると良いでしょう。実行すると表HOLIDAYSが作成されます。

日付ピッカーを実装するアプリケーションを作成します。

アプリケーション作成ウィザードにて、空のアプリケーションを作成します。名前日本の祝日とします。

デフォルトのまま、アプリケーションの作成を実行します。


アプリケーションが作成されたら、ページ・デザイナにてホーム・ページを開きます。

テストに使用するページ・アイテムを作成します。

識別名前P1_DAYタイプとして日付ピッカーを選択します。ラベル日付の選択とします。


選択を禁止する日付の情報を保持するページ・アイテムを作成します。

識別名前P1_HOLIDAYSタイプとして非表示を選択します。


ページ・アイテムP1_HOLIDAYSを初期化するプロセスを作成します。

レンダリング前のヘッダーの前にプロセスを作成します。識別の名前を祝日の初期化とし、コードとして、以下を記述します。

declare
l_year number;
-- 年間の祝日
l_holidays varchar2(32767);
-- 月ごとの祝日
function get_holidays_in_month(p_year in number, p_month in number)
return varchar2
is
l_hm varchar2(32676);
begin
select
listagg(
'"' || extract(day from holiday_date) || '":' ||
'{"disabled":true}'
, ',')
into l_hm
from holidays
where 1=1
and extract(year from holiday_date) = p_year
and extract(month from holiday_date) = p_month;
return l_hm;
end get_holidays_in_month;
begin
l_year := extract(year from sysdate);
l_holidays :=
json_object(key to_char(l_year,'FM9999') value
'{"1":{' || get_holidays_in_month(l_year,1) || '},' ||
'"2":{' || get_holidays_in_month(l_year,2) || '},' ||
'"3":{' || get_holidays_in_month(l_year,3) || '},' ||
'"4":{' || get_holidays_in_month(l_year,4) || '},' ||
'"5":{' || get_holidays_in_month(l_year,5) || '},' ||
'"6":{' || get_holidays_in_month(l_year,6) || '},' ||
'"7":{' || get_holidays_in_month(l_year,7) || '},' ||
'"8":{' || get_holidays_in_month(l_year,8) || '},' ||
'"9":{' || get_holidays_in_month(l_year,9) || '},' ||
'"10":{' || get_holidays_in_month(l_year,10) || '},' ||
'"11":{' || get_holidays_in_month(l_year,11) || '},' ||
'"12":{' || get_holidays_in_month(l_year,12) || '}}'
format json);
:P1_HOLIDAYS := l_holidays;
end;


ここで生成しているJSONオブジェクト(となる文字列)を、日付ピッカーにプロパティdayMetaDataとして設定します。

ページのロード時に、日付ピッカーを初期化するJavaScriptコードを実行します。動的アクションを作成します。

ページのロードで動的アクションを作成します。識別名前日付ピッカーの初期化とします。


アクションJavaScriptコードの実行を選択し、設定コードとして以下を記述します。
let elem = document.getElementById("P1_DAY");
let dm = JSON.parse(apex.items.P1_HOLIDAYS.value);
elem.setProperty("dayMetaData", dm);

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

ページ・アイテムのタイプによっては(例えばリッチ・テキスト・エディタなど)、プロパティ詳細JavaScript初期化コードの設定が含まれます。このプロパティがあるコンポーネントであれば、初期化コードを実行するにあたって動的アクションを作成する必要がなくなります。


日付ピッカーはOracle JETにて提供されているコンポーネントです。

色々な機能が提供されているようですが、活用するためにはOracle JETのリファレンスを参照する必要があります。なかなか一筋縄ではいかなそうです。

https://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html

以上で、今回の記事は終了です。

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

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