📚

FullCalendarV6のMonthビューの使い方

2024/12/24に公開

はじめに

JavaScriptのライブラリFullCalendar(https://fullcalendar.io/) のv6を使う機会があったのですがドキュメント見ただけではいまいちわからないことがあったので、引っかかったポイントなどまとめておこうと思います。
扱うのはMonthビューです。
https://fullcalendar.io/docs/month-view-demo

allDayに関して

EventオブジェクトのallDayプロパティに関して

  • allDay: trueに設定するとそのイベントが終日のイベント(その日一日をまるごと占めるイベント)として扱われます
    そのため開始・終了時間を指定しても、無視されます。
  • イベント個々ではなく一括で設定する場合はオプションでdefaultAllDay: trueに設定します
    allDayのプロパティを指定した場合はそちらの値が優先されます。
  • 終了日は排他的に扱われるため、終了日に設定された日付自体はカレンダーに表示されず、その前日までがイベント期間として表示されます

下記の様に設定するとカレンダー上は12/1~12/5にまたがって表示されて、1日短いように表示されます

events: [
  {
    title: 'イベントA',
    start: '2024-12-01',
    end: '2024-12-06 ',
    allDay: true,
  }
]

https://fullcalendar.io/docs/event-object

allDay: trueで1日短く表示される問題の対処方

対処法①終了日に1日加算する

2024-12-06に終了するイベントの場合endには2024-12-07を指定する。
終了日はその日を含まないため、1日短く表示されるように見えます。この仕様に合わせるには、終了日を1日加算することが対処法となります。

events: [
  {
    title: 'イベントA',
    start: '2024-12-01',
    end: '2024-12-07', //2024-12-06 + 1日
    allDay: true,
  }
]

対処法②allDay: falseにして、display: blockに設定する

display: blockに設定しないと背景色が一部反映されないみたいなので、背景色を反映させるために設定します。
displayの設定はデフォルトはautoなのですが、終日のイベントではない時間指定のイベント(例. 2024-12-01 10:00:00 ~ 2024-12-01 12:00:00)はbackgroundColorのプロパティが効かないようです。もしかするとこれは他のスタイルの競合や環境によるのかもしれないです。
細かく追えていないので必要があれば調べてみてください。
その他にもプロパティの値が反映されないなどあるかもしれないので適宜設定が必要かもしれません。

events: [
  {
    title: 'イベント',
    start: '2024-12-01',
    end: '2024-12-06 ',
    allDay: false, //デフォルトでfalseなのであえて設定しなくてもいい
    display: 'bolck',
  }
]

イベントの並び順

デフォルトでは下記上から順に優先的に並び替えをする。開催が早いものが上にきます。

  • 開催が早い
  • 長い時間
  • 終日かどうか
  • アルファベット順

ただ見た目がコンパクトかどうかで、よりコンパクトな並び順にデフォルトでは置き換わるみたいなので、厳密に並び順を制御したい場合はeventOrderStrict: trueに設定すると良さそうです。
https://fullcalendar.io/docs/eventOrderStrict

並び順を制御したい場合eventOrderで値をセット
文字列で設定する場合はプロパティ名のカンマ区切りで、-をつけると降順になります

eventOrder: 'title,propA,-propB',
eventOrderStrict: true,

配列や関数も設定可能。詳細はドキュメントにかかれています
https://fullcalendar.io/docs/eventOrder

非標準フィールド(title,start,endのようなもともとあるフィールド以外のもの)の場合
extendedPropsを使っても使わなくてもどちらでも問題なさそうです。

events: [
  {
    title: 'イベント',
    start: '2024-12-01',
    end: '2024-12-06',
    type: 1,
    'extendedProps' => [
        'sub_title' => 'game streaming',    
    ],
  },
  {
    title: 'イベント2',
    start: '2024-12-01',
    end: '2024-12-02',
    type: 3,
    'extendedProps' => [
        'sub_title' => 'hokkaido fair',    
    ],
  }
]

上記のようなイベントの場合、下記の様にすれば並び替えは反映される。extendedPropsに設定していたsub_titleも直接設定していたtypeもどちらも並び替えの対象となります。

eventOrder: 'type,sub_title',
eventOrderStrict: true,

イベントを再描画

イベントを描画後(render())に別のイベントを再描画する方法です

calendar.render();
calendar.removeAllEventSources() //calendar.removeAllEvents()でも動く

const newEventSource = [
    { title: 'New Event 1', start: '2024-12-25' },
    { title: 'New Event 2', start: '2024-12-26' }
];

calendar.addEventSource(newEventSource);

refetchEvents()

addEventSource();の後にrefetchEvents()の記述がなくてもイベントは再描画されるみたいです。
refetchEvents()はカレンダーのイベントをAPIなど外部データから取得していてイベントの書き換えが発生する場合にカレンダーを最新の状態に保つために使えそうです。
ボタンを押下毎にrefetchEvents()を呼び出したり、数分毎にrefetchEvents()を呼び出すみたいな使い方ができるかと思います。

https://fullcalendar.io/docs/Calendar-refetchEvents

イベントの削除について

removeAllEventSources() はイベントのデータソース自体を削除し、removeAllEvents() は現在表示されているすべてのイベントをカレンダーから削除します。ですが両方ともremoveAllEventSources(), removeAllEvents()はドキュメントに記載が見当たらなかったので、あまり使わないほうがいいのかもしれないです。

使わない場合下記のようにするとイベントをカレンダーから削除できます。

calendar.getEventSources().forEach(source => source.remove());

allDaySlot

EventオブジェクトのallDaySlotについて

  • 終日スロットをカレンダーの上部に表示するかどうかを決定するプロパティ。
  • Monthビュー(dayGridMonth)では意味がなさそう
  • おそらくtimeGridWeek, timeGridDayなどのTimeGridビューで使う

https://fullcalendar.io/docs/allDaySlot

カレンダーのイベントをクリックした際の動作を制御する方法

Eventオブジェクトのurlプロパティがnullの場合、リンクを無効にしたかったのでその方法です。
eventClickをオプションで設定します。

eventClick: function (info) {
    const url = info.event.url;
    //Eventオブジェクトのurlはstringで型指定されている影響なのか'null'という文字列になる
    if (url === 'null') {
        info.jsEvent.preventDefault();
    }
},

info.jsEvent.preventDefault() を呼び出すことで、リンク先への移動をキャンセルしています。
urlが文字列がどうかはイベントオブジェクトの設定の方法で変わるかもしれないので、適宜変更が必要かもしれないです。
eventClickのコールバック関数の引数に関してはドキュメントにまとめられているのでそちらを確認ください。
https://fullcalendar.io/docs/eventClick

このままだとurlがnullでもそのイベントのカーソルはpointerのままなのでそれを変更する方法も合わせて記載します。eventDidiMountを使います。
これはイベントがカレンダーに追加された直後に呼び出されるイベントです

eventClick: function (info) {
    const url = info.event.url;
    //Eventオブジェクトのurlはstringで型指定されている影響なのか'null'という文字列になる
    if (url === 'null') {
        info.jsEvent.preventDefault();
    }
},
eventDidMount: function (info) {
    const url = info.event.url;
    if (url === 'null') {
        info.el.style.cursor = 'default';
    }
},

https://fullcalendar.io/docs/event-render-hooks

環境

fullcalendar 6.1.15
https://github.com/fullcalendar/fullcalendar

Discussion