葉っぱのメモ帳

フリーランスなフロントエンドエンジニアの備忘録

FullCalendarの表示をカスタマイズする

2021.08.14

前々回と前回でGoogleカレンダーのAPIキーを取得し、FullCalendarと連携させることができました。

前々回

前回

表示までならここまでで大丈夫なのですが、今回は案件で少しだけデザインも触りましたのでそちらのメモです。
内容としては本当に極一部ですので、お役に立てるかは謎!

FullCalendarのデザインの基本

そもそもは公式でけっこう色々見本を出しています。
ダウンロードしたファイル内の「examples」を覗いて見るといろんなパターンがあるので、その中からこれ!というものがあればそのサンプルのソースから必要なところをコピペすればOKです。

公式のサンプル

公式サイトからサンプルを見てもよし。

公式のドキュメント

正確な情報は公式にあります。読めるかどうかはまた別。

日本語化と日付表記の変更

とりあえず日本語にしてみます。

日本語化ファイルを読み込む

ダウンロードしたファイル内にてlib/locales/ja.jsというファイルを探して、読み込みます。
場所は適宜好きなところに上げてください。

<script type='text/javascript' src='js/fullcalendar/ja.js'></script>

あ、これ前回もう読み込んでましたね。この構成力の無さよ。
これだけでは日本語化できないので、オプションを追加していきます。

日本語化する

前回貼ったコードの中から

var calendar = new FullCalendar.Calendar(calendarEl, {

    (ここにオプション等を記述)

});

この中に色々足していきます。

locale: 'ja',

こちらを追加してみます。

日本語化されました!
しかしこれだと1日、2日、3日…とちょっと鬱陶しいでの日付部分の「日」を消します。

「〇日」の「日」を表示させない

dayCellContent: function(e) {
    e.dayNumberText = e.dayNumberText.replace('日', '');
},

こちらを追加。

「今日」「月」「予定リスト」を変更

前後の月移動をしていて、今月に戻りたいときに「今日」をクリックするのですが、今日って気分でもなかったので「今月」にします。

buttonText: {
    today: '今月',
    month: '月',
    list: 'リスト'
},

ここまでで見てみると

こんな感じになりました。

曜日の表記を変更する

日~土までの曜日を変更します。
日本語化しておいてなんなのですが、曜日はS・M・T…のような表記にしたいとのことでした…。

あとでまとめて表記しますが、オプションの前に曜日の表記の配列を作って、それをオプション内で指定するイメージです。

// 曜日の表記を配列に入れる
var DAY_NAMES = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];

var calendar = new FullCalendar.Calendar(calendarEl, {
    // 曜日の表記の指定
    dayHeaderContent: function(arg) {
        return DAY_NAMES[arg.date.getDay()]
    },
});

曜日の表記が変わりました!

終日イベントに背景色を付ける

eventのオプションはたくさんあるので、ここでは「終日イベントの背景色を変える」だけですがご紹介。

前回、イベントのソース部分は

events: 'ここにカレンダーID',

としましたが、ここにオプションを付けていきます。

// イベントの指定
events: {
    googleCalendarId: 'ここにカレンダーID',
    display: 'background',  // 背景表示
    color:"#49B9A7",  // 背景の色指定
    classNames: 'gcal-event', // 独自のclass名を付与(必要なら)
},

終日イベントに背景色が付きました!(すみません、画像は指定した色と違います…)
ただこのやり方だと終日イベントではないイベントは非表示になってしまうんですよね…💧
今回、要は「定休日だけ分かるようにしたい」というご依頼だったので今回はここまで…。

詳しいことはやはり公式にてどうぞ!

CSSで見栄えを調整する

ここまでくればあと一息です。
今回はイベントの表示より、定休日の表示が目的だったので、イベント名そのものも表示しないという乱暴なCSSです。

.fc .fc-scrollgrid {
  border-width: 0 0 0 0; /* 外側の枠線消す */
  font-size: 20px;
  font-weight: normal;
}
.fc-theme-standard td, .fc-theme-standard th {
  height: 60px; /* 枠の高さ指定 */
  border: none; /* 枠のボーダー消す */
  padding: 0 5px 5px;
}
/* 今日の背景 */
.fc .fc-daygrid-day.fc-day-today {
  background: none;
}
.fc .fc-daygrid-day.fc-day-today .fc-daygrid-day-frame {
  background: rgba(49,159,141,0.1);
}
/* 日付を枠の高さいっぱいに */
.fc .fc-daygrid-day-frame {
  height: 100%;
}
/* 日付を枠の中心に */
.fc .fc-daygrid-day-top {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 100%;
}
.fc .fc-bg-event {
  opacity: 1;
}
/* イベントタイトル非表示 */
.fc .fc-bg-event .fc-event-title {
  display: none !important;
}
/* 時間指定のあるイベントの表示スペースをそもそも非表示にしてしまう暴挙 */
.fc .fc-daygrid-body-natural .fc-daygrid-day-events {
  display: none;
}
.fc .fc-cell-shaded, .fc .fc-day-disabled {
  background: none;
}

tdの枠の高さを直接指定したりしていますが、そのあたりはpadding等で調整しても良いかと思います。
全体の幅等は親要素で調整してくださいね。

さて、ここまできて、できればイベントがある日(背景色を付けた日)は文字を白にしたいな、と思ったのですが、CSSで指定ができませんでした。
というのも、イベントの要素を非表示にするというCSSになっているので💧
最後の調整です。

イベントの日の文字色を変更する

この段階でイベントが設定されている日にはfc-bg-eventいうclassが付いています。
それが含まれているtdのcolorを白にしたいと思います。

loading: function(bool) {
  if(bool) {
    document.getElementById('loading').style.display = 'block';
  } else {
    document.getElementById('loading').style.display = 'none';

    // 若干タイミングずらす
    setTimeout(() => {
      // .gcal-eventを持つ要素を取得
      let els = document.getElementsByClassName('fc-bg-event');
      // 要素数分繰り返し処理
      for (let i = 0; i <  els.length; i++) {
        // 上位要素から直近のtdを見つけてフォントカラーを変更
        els[i].closest('td').style.color = '#ffffff';
      }
    }, 10);  
  }
}

もともとサンプルに入っていたloading: function(bool)という部分を活用させていただきます。

document.getElementById('loading').style.display = 'block';という部分は今回触れていなかったので載せていないのですが、ローディング画面用の要素のことなので、必要でしたらサンプルでご確認ください…(こうしてだんだんてきとうになっていく…)

コメントを見ていただければだいたいの流れが分かるかと思いますが、要素を見つけて、それを含むtdを見つけてスタイルを変更する、という流れです。
読込が終わったら実行されると思ったのですが、なんやかんや若干タイミングをズラさないと取得できなかったので苦肉の策でsetTimeoutを使っています…。

ちなみに最初はもっと乱暴に、ここだけjQueryにしていましたw

loading: function(bool) {
    if(bool) {
        略
    } else {
        jQuery(function($){
            $('.fc-bg-event').each(function(){
                $(this).closest('td').css('color','#ffffff');
            });
        });
    }
}

処理速度の問題なのか、こちらはsetTimeout無しで動作しています…。

コードまとめ

どこに何を記述してんだよ!とという感じなので、jsをまとめてみます。

document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');
  var DAY_NAMES = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];

  var calendar = new FullCalendar.Calendar(calendarEl, {
    locale: 'ja',

    dayCellContent: function(e) {
        e.dayNumberText = e.dayNumberText.replace('日', '');
    },
    dayHeaderContent: function(arg) {
        return DAY_NAMES[arg.date.getDay()]
    },

    headerToolbar: {
      left: 'prev,next today',
      center: 'title',
      right: ' ' // 月とリスト要らないので・・・でも要素のバランス用に
    },
    buttonText: {
      today: '今月',
      month: '月',
      list: 'リスト'
    },

    displayEventTime: false, // don't show the time column in list view
    firstDay: 1,    // 月曜始まり
    showNonCurrentDates: false,
    height: "auto", // 高さは自動

    // GoogleカレンダーAPIキー
    googleCalendarApiKey: 'ここに取得したAPIキー',

    // イベントの指定
    events: {
      googleCalendarId: 'ここにカレンダーID', // Googleカレンダーの指定
      display: 'background',  // 背景表示
      color:"#49B9A7",  // 背景の色指定
      classNames: 'gcal-event', // 独自のclass名を付与(必要なら)
    },

    // クリック時の動作(今回は割愛)
    eventClick: function(arg) {
      // opens events in a popup window
      window.open(arg.event.url, 'google-calendar-event', 'width=700,height=600');
      arg.jsEvent.preventDefault() // don't navigate in main tab
    },

    loading: function(bool) {
      if(bool) {
        document.getElementById('loading').style.display = 'block';
      } else {
        document.getElementById('loading').style.display = 'none';

        setTimeout(() => {
          let els = document.getElementsByClassName('fc-bg-event');
          for (let i = 0; i <  els.length; i++) {
            els[i].closest('td').style.color = '#ffffff';
          }
        }, 10);  
      }
    }

  });

  calendar.render();
});

ということでこんな感じになりました!
お店で使うときなんかは、定休日をGoogleカレンダーで設定さえすれば勝手に色が付いて表示してくれるという使い方です。
本当はもう少しカスタマイズすべきところがあるのですが、正直キリがないので!笑

デモ

デモを置いておきます!よろしければ参考にしてくださいませ。

デモ

まとめ

3回に渡ってFullCalendarとGoogleカレンダーの連携について書いてみました。
いやあ、実装も大変ですがブログにまとめるのも大変ですね。
丁寧な記事を載せてくださっている方々に頭が上がらないです…。

少しでも誰かのお役に立てれば幸いです!
お疲れ様でした~~!

参考にさせていただきました。

書いた人

トップへ