イベントとしてではなく、休日や祝日のときはセル(TD要素です)の色(もしくは、TD要素としてのその他の属性やスタイル)を変更したい、との相談がありました。
Oracle APEXのカレンダ・リージョンの実体はFullCalendarのv6です。FullCalendarのドキュメントを確認すると、Day-Cell Render Hooksという機能が見つかりました。このフックの内のdayCellDidMountを使って実装してみました。
以下、dayCellDidMountのフックを使って、祝日にあたる日付セルの背景色を変えてみました。
以下より、実装について紹介します。
最初に日本の祝日のデータをデータベースにロードします。以前の記事に合わせて祝日を保持する表として、表CAL_NATIONAL_HOLIDAYSを作成します。以下のDDLを実行します。
create table cal_national_holidays (
id number generated by default on null as identity
constraint cal_national_holidays_id_pk primary key,
holiday_date date,
holiday_name varchar2(255 char)
);
SQLワークショップのSQLコマンドでの実行例です。
表CAL_NATIONAL_HOLIDAYSに日本の祝日のデータをロードします。データ・ロード自体は本記事の本題ではないので、手短に以下のスクリプトを実行してデータをロードします。
SQLコマンドでの実行例です。表CAL_NATIONAL_HOLIDAYSに挿入された行数が報告されます。
空のAPEXアプリケーションを作成します。名前はFullCalendar Cell Highlightとしています。サンプルの実装は、ホーム・ページに行っています。
実装に使うカレンダのリージョンを作成します。ソースのタイプをSQL問合せとし、SQL問合せとして以下を記述します。SELECT文の列情報を参照するだけなので、条件句として 1<>1を指定して、どのような場合でも1行も値を返さないようにしています。
select 'TITLE' as title, date'2001-01-01' as start_date from dual where 1<>1
JavaScriptよりリージョンを参照するため、静的IDとしてCALENDARを割り当てています。
カレンダの属性を開き、設定の表示列にTITLE、開始日列にSTART_DATEを設定します。
以上で最低限のカレンダの設定ができました。
続いて、国民の祝日のデータをJavaScriptから参照できるようにします。祝日の確認の度にデータベースに問い合わせるのは現実的では無いため、ページ・ロード時にデータベースから国民の祝日のデータを取り出し、JavaScriptのグローバル変数に保存します。
データベースから国民の祝日のデータを取り出す処理を、Ajaxコールバックのプロセスとして作成します。プロセス名はGET_HOLIDAYSとします。
ソースのPL/SQLコードとして以下を記述します。
declare
l_holidays clob;
begin
select
json_objectagg(to_char(holiday_date,'YYYY-MM-DD') value holiday_name returning clob)
into l_holidays
from cal_national_holidays;
htp.p(l_holidays);
end;
国民の祝日の情報は、以下のようなJSONドキュメントとしてGET_HOLIDAYSの呼び出し元に返されます。
{
"1988-11-23": "勤労感謝の日",
"1989-01-01": "元日",
"1989-01-02": "休日",
"1989-01-15": "成人の日",
"1989-01-16": "休日",
"1989-02-11": "建国記念の日",
....
"2025-10-13": "スポーツの日",
"2025-11-03": "文化の日",
"2025-11-23": "勤労感謝の日",
"2025-11-24": "休日"
}
カレンダの日付セルの変更に関わる実装を行います。
ページ・プロパティのJavaScriptのファンクションおよびグローバル変数の宣言に以下を記述します。
/*
* 国民の祝日を保持する。
*/
var g_HOLIDAYS = {};
/*
* 日付セルの要素と日付データを受け取り、祝日が設定されていれば
* 日付セルを変更する。
*
* 以下は例としてCSSクラスu-color-18-bgを設定している。
*/
const modifyDayIfHoliday = (elem, date) => {
const year = date.getFullYear();
const month = String(date.getMonth()).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const key = `${year}-${month}-${day}`;
if ( g_HOLIDAYS[key] !== undefined ) {
elem.classList.add('u-color-18-bg');
}
};
ページ・ロード時に実行に以下を記述します。ページ・ロード時はdayCellDidMountのフックが呼び出されません。そのため、祝日データの読み込みが完了した後に、表示されているすべての日付セルを対象に、dayCellDidMountフックの代わりにmodifyDayIfHolidayを呼び出します。
/*
* 休日のデータをHOLIDAYSにキャッシュした後に、
* 日付セルに祝日処理を適用する。
*/
apex.server.process( "GET_HOLIDAYS", {},
{
success: (data) => {
g_HOLIDAYS = data;
/* 表示されているカレンダに色付けをする */
const calEl = document.getElementById("CALENDAR");
const cells = calEl.querySelectorAll('td[role="gridcell"]');
cells.forEach( (e) => {
const date = e.getAttribute('data-date');
modifyDayIfHoliday(e, new Date(date));
});
}
}
);
カレンダにdayCellDidMountフックを設定します。属性の詳細の初期化JavaScriptファンクションに以下を記述します。
function( options ) {
options.dayCellDidMount = (e) => {
modifyDayIfHoliday(e.el, e.date);
}
}
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/fullcalendar-cell-highlight.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完