<div class="calendar"></div>
* {
    margin: 0;
    padding: 0;
}
body {
    height: 100vh;
    width: 100%;
}
@media screen and (max-width:768px) {
  body {
    font-size: 62.5%;
  }
}
.custom-view table{
  width: 100%;
}
.custom-view thead th {
  padding: 10px;
  text-align: left;
}
.custom-view tbody th,
.custom-view tbody td {
  padding: 10px;
  text-align: left;
}
.no-data {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  padding: 80px;
  background: #d0d0d04d;
  border: 1px solid #ddd;
}
(function() {
    'use strict';

    const CustomViewConfig = {
      classNames: ['custom-view'],
      buttonText: '予定リスト2',
      duration: {days: 31},
      titleFormat: function (date) {
          const startYear = date.start.year;
          const endYear = date.end.year;
          const startMonth = date.start.month + 1;
          const endMonth = date.end.month + 1;
          const startDay = date.start.day;
          const endDay = date.end.day;

          if (startYear === endYear) {
              return startYear + '年' + startMonth + '月' + startDay + '日 ~ ' + endMonth + '月' + endDay + '日';
          } else {
              return startYear + '年' + startMonth + '月' + startDay + '日 ~ ' + endYear + '年' + endMonth + '月' + endDay + '日';
          }
      },
      content: function (props) {
        const segs = FullCalendar.sliceEvents(props, true);
        let getData = '';
        function addZero (num) {
            let result = '';
            if (num < 10) {
                result = '0' + num;
            } else {
                result = String(num);
            }

            return result;
        };
        function getSegs() {
          for (let i = 0, len = segs.length; i < len; i++) {
            const data = segs[i];
            const start = data.instance.range.start;
            const end = data.instance.range.end;
            const month = start.getMonth() + 1;
            const day = start.getDate();
            const weekNum = start.getDay();
            const week = ['(日)', '(月)', '(火)', '(水)', '(木)', '(金)', '(土)'][weekNum];
            const getDate = month + '月' + day + '日' + week;

            const startHours = start.getUTCHours();
            const endHours = end.getUTCHours();
            const startMinutes = start.getUTCMinutes();
            const endMinutes = end.getUTCMinutes();
            let getTime;
            if (startHours + startMinutes + endHours + endMinutes === 0) {
                getTime = '終日';
            } else {
                getTime = addZero(startHours) + ':' + addZero(startMinutes) + '-' + addZero(endHours) + ':' + addZero(endMinutes);
            }

            const getEvent = data.def.title;

            getData += '<tr><th>' + getDate + '</th><td>' + getTime + '</td><td>' + getEvent + '</td></tr>';
          }
          return getData;
        }
        getSegs();

        let html;
        if (getData === '') {
          html = '<div class="no-data">表示する予定はありません</div>';
        } else {
          html = '<table><thead><tr><th>日付</th><th>時間</th><th>予定</th></tr></thead>' +
          '<tbody>' + getData + '</tbody>' +
          '</table>';
        }
        
        return {html: html};
      }
    };
    
    const calendarEl = document.querySelector('.calendar');
    const calendar = new FullCalendar.Calendar(calendarEl, {
        views: {
          timeGridWeek: {
            titleFormat: function (date) {
              const startMonth = date.start.month + 1;
              const endMonth = date.end.month + 1;

              if (startMonth === endMonth) {
                 return startMonth + '月';
              } else {
                 return startMonth + '月~' + endMonth + '月'; 
              }
            },
            dayHeaderFormat: function (date) {
              const day = date.date.day;
              const weekNum = date.date.marker.getDay();
              const week = ['(日)', '(月)', '(火)', '(水)', '(木)', '(金)', '(土)'][weekNum];

              return day + ' ' + week;
            },
            slotMinTime: '09:00:00',
            slotMaxTime: '18:00:00'
          },
          timeGridDay: {
            slotMinTime: '09:00:00',
            slotMaxTime: '18:00:00'
          },
          custom: CustomViewConfig
        },
        headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth,custom'
        },
        initialDate: '2020-12-07',
        navLinks: true,
        slotDuration: '00:15:00',
        slotLabelInterval: '01:00',
        editable: true,
        contentHeight: 'auto',
        locale: 'ja',
        nowIndicator: true,
        dayCellContent: function (e) {
          e.dayNumberText = e.dayNumberText.replace('日', '');
        },
        dayMaxEvents: true,
        eventDisplay: 'block',
        events: [
          {
            title: 'Checka11y.cssによるアクセシビリティチェック',
            start: '2020-12-01'
          },
          {
            title: 'ミツエーリンクス製npmパッケージの紹介',
            start: '2020-12-02'
          },
          {
            title: 'CustomEventをバブリングさせてみよう',
            start: '2020-12-03'
          },
          {
            title: 'Adobe XDで3D表現を取り入れたUIをつくってみる',
            start: '2020-12-04'
          },
          {
            title: 'Photoshopの描画モードで魅力的なクリスマスカードを作ろう',
            start: '2020-12-05'
          },
          {
            title: '日本企業500社を対象にLighthouseのアクセシビリティスコアを計測してみた',
            start: '2020-12-06'
          },
          {
            title: '今日から始めるBroadcast Channel API',
            start: '2020-12-07'
          },
          {
            title: 'FullCalendar v5.0.0を使いこなす(カスタマイズ編)',
            start: '2020-12-08'
          },
          {
            title: 'WCAGに心折られて不死鳥のごとく復活した男の話',
            start: '2020-12-09'
          },
          {
            title: 'FacebookやInstagramの自動代替テキスト機能に期待すること',
            start: '2020-12-10'
          },
          {
            title: 'Microsoftのヒートマップツール「Clarity」を使ってみた',
            start: '2020-12-11'
          },
          {
            title: 'Pythonのモジュールを使ってWordファイルからHTMLファイルを作成する方法',
            start: '2020-12-12'
          },
          {
            title: 'Section 508のアクセシビリティテストプロセス(Trusted Tester)について',
            start: '2020-12-13'
          },
          {
            title: 'Node.js v15に実装されたAbortController',
            start: '2020-12-14'
          },
          {
            title: '日替わりコンテンツから学ぶ、習慣化のルール',
            start: '2020-12-15'
          },
          {
            title: 'After Effectsで作るアイコンアニメーション',
            start: '2020-12-16'
          },
          {
            title: 'Adobe XDのstack機能を使ってline-heightを考慮したデザインを作る',
            start: '2020-12-17'
          },
          {
            title: 'Web Componentsの実用に向けて',
            start: '2020-12-18'
          },
          {
            title: 'CRMをヒントにチームのヒューマンエラー予防について考える',
            start: '2020-12-19'
          },
          {
            title: 'PythonのWebスクレイピングを用いて、Webの品質管理を考えてみた',
            start: '2020-12-20'
          },
          {
            title: 'aria-current属性と一般兄弟結合子で作るステップUI',
            start: '2020-12-21'
          },
          {
            title: 'ハイコントラスト表示とメディアクエリー',
            start: '2020-12-22'
          },
          {
            title: 'サイトデザインの品質を上げる3つのセルフチェックリスト',
            start: '2020-12-23'
          },
          {
            title: 'エラーを繰り返さないためのコミュニケーション',
            start: '2020-12-24'
          },
          {
            title: 'Comlinkを使って手軽にWorkerを扱う',
            start: '2020-12-25'
          }
        ]
    });

    calendar.render();
}());

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.