ラベル カレンダ の投稿を表示しています。 すべての投稿を表示
ラベル カレンダ の投稿を表示しています。 すべての投稿を表示

2025年8月20日水曜日

ページ・ロード時につねに現在の月のカレンダーを表示する

Oracle APEXのカレンダ・リージョンは開いている月を覚えていて、 別のページに移動した後にカレンダに戻ると、それまで開いていた月が表示されます。

どちらが便利かはわかりませんが、カレンダのページを開いたときはつねに現在の月を表示したい、という要望がありました。

Oracle APEXのカレンダ・リージョンはFullCalenderで作られています。

ChatGPTに聞いてみました。

fullCalenderで現在の月に移動するには?

.today().gotoDate()が使えるよ、とのこと。今日に移動するだけなら、.today()がお勧めとのことです。


実装して動作を確認してみました。

確認にはカレンダ・リージョンが実装されたAPEXアプリケーションが必要です。

アプリケーション作成を開き、ファイルからのアプリケーション作成を実行します。サンプル・データのプロジェクトとタスクに含まれるStart DateEnd Dateの値は、今日の日付を起点に前後の日付を算出するので、今回のテストの用途に向いています。


コピー・アンド・ペーストを選択し、サンプル・データとしてプロジェクトとタスクを選択します。CSVデータが画面に表示されます。

へ進みます。


 ロード先新規表とし、表名後で削除が楽になるような名前を指定します。その他はデフォルトのまま、データのロードを実行します。


表にサンプル・データがロードされます。アプリケーションの作成をクリックします。


アプリケーション作成ウィザードが開きます。

カレンダのページが含まれていることを確認し、アプリケーションの作成を実行します。


テスト用のアプリケーションが出来上がりました。ページ番号カレンダのページを実行します。


表示されるカレンダには、現在の月のカレンダが表示されます。


別の月を表示します。


ナビゲーション・メニューのホームをクリックし、ホーム・ページに移動します。その後、カレンダのページに戻ります。


カレンダには、それまで開いていた月が維持されています。


これから、ページ・ロード時にfullCalenderの.today()を呼び出す実装を追加します。

カレンダ・リージョンからfullCalendarのオブジェクトを取り出すために、カレンダ・リージョンに静的IDを設定します。静的IDcalendarとします。


ページ・ロード時に実行される動的アクションを作成します。

左ペインで動的アクション・ビューを開き、ページのロード動的アクションを作成します。

識別名前todayとします。タイミングページのロードになります。


TRUEアクションJavaScriptコードの実行を選択し、設定コードに以下を記述します。

apex.region("calendar").widget().data("fullCalendar").today();


以上で実装は完了です。

カレンダを開くたびに、現在の月が表示されるように動作が変わっています。


簡単な例ですが、いくつかのことを紹介しました。
  • カレンダ・リージョンは人気のJavaScriptライブラリであるfullCalendarを使っているので、fullCalendarを指定してChatGPTに聞くと出来ることを教えてくれる。
  • リージョンに静的IDを設定すると、apex.region("静的ID").widget().data("fullCalendar")としてfullCalendarのAPIを実装しているカレンダ・オブジェクトを取得できる。
今回の記事は以上です。

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

2024年12月12日木曜日

Oracle APEXのカレンダの日付セルを祝日を条件としてハイライトする

以前にOracle APEXのカレンダ・リージョンを使って国民の休日・祝日をイベントとして表示させる方法を紹介しています。


イベントとしてではなく、休日や祝日のときはセル(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のアプリケーション作成の参考になれば幸いです。

2024年1月16日火曜日

国民の祝日・休日をFullCalendar v6のmultiMonthYearおよびdayGridYearビューで表示する

フランスのパリ在住のLouis Moreauxさんが、彼のブログでFullCalendar v6で追加されたmultiMonthYearとdayGridYearビューの紹介記事を書いています。このような機能がOracle APEX 23.2から使えるようになっていたとは知りませんでした。

Oracle APEX 23.2 - Calendar region enhancements

FullCalendar v6で追加されたmultiMonthYearとdayGridYearビューは、ひとつのカレンダー・リージョンに複数の月を一度に表示します。

自分でも、実装サンプルとして以下のように動作するAPEXアプリケーションを作成してみました。


カレンダーに表示しているデータとして、内閣府「国民の祝日」についてのページからダウンロードした「昭和30年(1955年)から令和6年(2024年)国民の祝日(csv形式:20KB)」を使っています。

内閣府「国民の祝日」について

そもそもmultiMonthYearおよびdayGridYearビューはFullCalendarの新機能なので、Oracle APEXの新機能として説明されていません。リリース・ノートに以下のように記載されているだけです。
JavaScript Library Upgrades
We've updated several JavaScript libraries to newer releases including Oracle JET 15.0.0, jQuery 3.6.4, jQuery Migrate 3.4.1, FullCalendar 6.1.8, MarkedJS 5.1.2, DOMPurify 3.0.5, Terser 5.19.2, and TinyMCE 6.6.1.

 Oracle APEX 23.1に含まれているFullCalendarのバージョンは5.11.3なので、メジャー・バージョンが上がっています。multiMonthYearおよびdayGridYearビューは、このバージョンアップで導入された新機能になります。

FullCalendarのドキュメント(https://fullcalendar.io/docs)のViewsの、DayGridMulti-Month StackMulti-Month GridおよびCustom Viewsにあたります。


これらの新設されたビューは、Oracle APEXのページ・デザイナでは宣言的には扱えないため、初期化JavaScriptファンクションで定義します。

以下よりサンプル・アプリケーションの作成方法を紹介します。

クイックSQLの以下のモデルより表CAL_NATIONAL_HOLIDAYSを作成します。
#prefix: cal
national_holidays
    holiday_date
    holiday_name
レビューおよび実行をクリックし、生成されたSQLスクリプトを実行します。


SQLスクリプトの画面が開きます。スクリプト名を指定し、実行をクリックします。確認画面が開くので、即時実行をクリックします。


CAL_NATIONAL_HOLIDAYSが作成されます。


内閣府のWebページより、祝日のCSVファイルshukujitsu.csvがダウンロード済みとします。このCSVファイルを表CAL_NATIONAL_HOLIDAYSにロードします。

SQLワークショップユーティリティデータ・ワークショップを開きます。

データのロードを開きます。


ファイルの選択をクリックし、shukujitsu.csvを選択します。


ロード先として既存の表を選択し、に先ほど作成したCAL_NATIONAL_HOLIDAYSを選びます。ファイル・エンコーディングとして日本語(Shift JIS)を選択します。

このCSVには列見出しとして国民の祝日・休日月日国民の祝日・休日名称が含まれているため、最初の行にヘッダーが含まれるチェックが入ったままにします。CSVやExcelのデータをインポートする際に列見出しが日本語になっていると、ロード先新規表を選んでいると列名が日本語になってしまいます。一般に日本語の列名はSQLで扱いにくいため、データ・ワークショップを使って日本語データをロードする際は、あらかじめ表を作成しておくことを推奨します。

構成をクリックします。


ソース列国民の祝日_休日月日マップ先としてHOLIDAY_DATE(Date)国民の祝日_休日名称マップ先としてHOLIDAY_NAME(Varchar2)を設定します。

変更の保存をクリックします。


データ・ロードの準備ができたので、データのロードをクリックします。


データのロードが完了します。

取消をクリックし、データ・ワークショップのロード処理を終了します。


空のアプリケーションを作成します。

名前Sample FullCalendar v6 New Viewsとします。

アプリケーションの作成をクリックします。


アプリケーションが作成されます。

最初に標準の実装によるカレンダのページを作成します。

ページの作成をクリックします。


カレンダを選択します。


ページの名前Standardデータ・ソース表/ビューの名前CAL_NATIONAL_HOLIDAYSを選択します。

へ進みます。


表示列HOLIDAY_NAME開始日列HOLIDAY_DATEを選択します。終了日列は選択しない(- 選択 -のまま)、時間の表示いいえです。

ページの作成をクリックします。


カレンダのページが作成されます。


ページを実行すると以下のように表示されます。


ナビゲーション予定リストは、カレンダの属性タブの設定追加のカレンダ・ビューリストナビゲーションチェックによって表示/非表示が制御されます。この設定に限りませんが、初期化JavaScriptファンクションの記述によって、これらの設定が上書きされることがあります。


最初にMulti-Month Gridの表示を実装します。Standardのページをコピーします。

ページの作成をクリックし、コピーとしてのページの作成をクリックします。


次のコピーとしてのページを作成このアプリケーションのページです。

へ進みます。


コピー元ページ2. Standard新規ページ名Multi-Month Gridとします。ブレッドクラムを作成し、エントリ名Multi-Month Gridとします。

へ進みます。


ナビゲーションのプリファレンスとして新規ナビゲーション・メニュー・エントリの作成を選択します。新規ナビゲーション・メニュー・エントリMulti-Month Gridとします。

へ進みます。


リージョンStandard新しい値Multi-Month Gridに設定します。

コピーをクリックします。


カレンダのページMulti-Month Gridが作成されます。

リージョンMulti-Month Gridを選択し、プロパティ・エディタ属性タブを開きます。

詳細JavaScriptファンクションに以下を記述します。



カレンダのinitialViewとしてmultiMonthYearmultiMonthMaxColumns4(デフォルトは3)を設定しているため、一列に最大4つの月がカレンダに表示されるようになります。

ページを実行し、カレンダの表示を確認します。

手順によっては、初期化JavaScriptファンクションに記述した変更が反映されないことがあります。初期化JavaScriptファンクションにコードを記述する前にページを実行していると、ブラウザのセッション・ストレージにカレンダの状態が保存されるようです。そのためセッション・ストレージの記録をリセットするため、ブラウザのタブまたはウィンドウを一旦閉じ、再度、アプリケーションを実行します


カレンダを新しいタブまたはウィンドウで開くと、初期化JavaScriptファンクションでの設定が反映されます。

headerToolbar.endに空白を設定しているため、設定追加のカレンダ・ビューリストチェックが入っていても、予定リストのボタンは表示されません。

また、multiMonthMaxColumns4にしていても画面幅が十分で無い場合は、一列に表示される月の数は少なくなります。

Multi-Month Gridに切り替えた後の初回表示では、1年分のデータが表示されていない場合があります。


この現象には、パフォーマンス遅延ロードオンに変更して対処します。


遅延ロードオンにすると初回表示でも、1年分の祝日と休日が表示されます。


できるだけカレンダをスクロールしない設定などは、FullCalendarのDocumentのSizingの項目ににあるheightを調整します。

初期化JavaScriptファンクションにconfig.height = 'auto'を追加すると、表示は以下のようにできるだけスクロールせずに全ての月を表示しようとします。



画面に十分な横幅があれば、祝日の名前もカレンダに表示されます。


次にMulti-Month Stackの表示を実装します。Standardのページをコピーし、Multi-Month Stackのページを作成します。コピー手順はMulti-Month Gridと同じで、名称をMulti-Month Stackに置き換えて実行します。

作成したページのJavaScript初期化ファンクションに以下を記述します。Multi-Month StackはmultiMonthMaxColumnsを設定した、multiMonthYearビューです。



Multi-Month Stackでは、カレンダが縦方向にスクロールします。


続いてStandardのページをコピーし、Custom Viewsを実装します。

コピーしたページの初期化JavaScriptファンクションとして以下を記述します。multiMonthFourMOnthとしてヶ月分を表示するビューを定義し、それをmultiMonthMaxColumns2で表示しているため、2 x 2でカレンダが表示されます。



Custom Viewsの表示です。


最後にStandardのページをコピーし、Day Grid(dayGridYearビュー)を実装します。

コピーしたページの初期化JavaScriptファンクションとして以下を記述します。


 

dayGridYearビューでは、カレンダが月で分割されず、例えば1月31日の後に2月1日が続いて表示されます。


今回の記事は以上になります。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。今回は表CAL_NATIONAL_HOLIDAYSを作成するDDLとその表に投入する初期データをエクスポートに含んでいるため、APEXアプリケーションをインストールするだけで、アプリケーションの動作を確認することができます。
https://github.com/ujnak/apexapps/blob/master/exports/sample-fullcalendar-v6-new-views.zip

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