utamaro’s blog

誰かの役に立つ情報を発信するブログ

javascriptでカレンダーを作成する

html、cssjavascriptを使ってカレンダーを作成します。

この記事では、htmlとcssの部分についてはcodepenで見つけたデザインを使用しています。

なので、javascriptをメインで紹介したいと思います。

参考にしたデザインはこちらです。

https://codepen.io/jamiemggs/pen/xdvaJv

最終的に、このようなカレンダーができます。

f:id:miyaji-y26:20181007110243p:plain

成果物について

表示する項目

  • 今月のカレンダーを表示する
  • 月の移動はしない
  • 先月、来月の日付を表示する
  • 先月、来月の日付を表示しないこともできる

html

jsCalendarに対してdomを追加します。

javascriptを使って、jsCalendarにhandlebars.jsで生成したdomを追加します。

<div id="jsCalendar" class="calendar"></div>

css

cssについてはcodepenのをそのまま使用します。

handlebar

この例ではテンプレートにhandlebars.jsを使用しています。

handlebars.jsについてはこちらを確認してください。

https://github.com/wycats/handlebars.js/

<div class="jzdbox1 jzdcal">
    <div class="jzdcalt">{{year}}年{{month}}月</div>

    <span>Su</span>
    <span>Mo</span>
    <span>Tu</span>
    <span>We</span>
    <span>Th</span>
    <span>Fr</span>
    <span>Sa</span>

    {{#each dates}}
        {{#if this }}
            <span>{{date}}</span>
        {{else}}
            <span class="jzdb"><!--BLANK--></span>
        {{/if}}
    {{/each}}
</div>

{{#if this }}に気がつくまで時間がかかりました。

このテンプレートに渡されるデータの構造について。

year: 2018
month: 10
dates: [
    {
        month: 10
        date: 1
    }
]

datesの配列にはnullが入ることもある。

nullの項目が日付の非表示に対応する形です。

javascript

ES2015の書き方をしている箇所があります。

import $ from 'jquery';
import hb_calendar from 'HandleBars/calendar';

(function() {
    class Calendar {
        constructor() {
            this.element = {
                template_target: {
                    calendar: "#jsCalendar",
                }
            }
        }

        render(calendar_data) {
            // handlebarsは入れるtemplateを入れるtargetを作って
            let target = $(this.element.template_target.calendar);
            // templateからhtml文字列を作って
            let html = hb_calendar({
                year: calendar_data.year,
                month: calendar_data.month,
                dates: calendar_data.dates,
            });
            // targetにhtmlをappendする。これだけ!
            target.append(html);
        }

        createCalendarData(allowBlank) {
            allowBlank = allowBlank || false;
            let today = new Date();
            let year = today.getFullYear();
            let month = today.getMonth();

            let lastMonthDateObj = new Date(year, month, 0);  // 先月の最終日
            let nextMonthDateObj = new Date(year, month + 1, 1);  // 来月の初日
            let startDate = new Date(year, month, 1); // 今月の初日
            let endDate  = new Date(year, month + 1 , 0); // 今月の最終日

            // Sunday is 0, Monday is 1, and so on.
            let firstDateNum = startDate.getDate();
            let lastDateNum = endDate.getDate();

            let dates = []
            // まずは、先月の日付を入れる。
            for (let di = 0; di < startDate.getDay(); di++) {
                if (allowBlank) {
                    dates.push(null)
                } else {
                    dates.push(
                        {
                            month: lastMonthDateObj.getMonth() + 1,
                            date: lastMonthDateObj.getDate() - di,
                        }
                    );
                }
            }
            
            // 次に日付を入れる
            for (var di = firstDateNum; di <= lastDateNum; di++) {
                dates.push(
                    {
                        month: month + 1,
                        date: di,
                    }
                )
            }

            // 最後に来月の日付をいれる
            for (let di = 0; di < endDate.getDay(); di++) {
                if (allowBlank) {
                    dates.push(null);
                } else {
                    dates.push(
                        {
                            month: nextMonthDateObj.getMonth() + 1,
                            date: 1 + di,
                        }
                    )
                }
            }
            // datesにカレンダーの情報が入っている。
            // あとはレンダリングするだけ
            console.log(dates);
            return {
                year: year,
                month: month + 1,
                dates: dates,
            };
        }
    }

    function init() {
        let calendar = new Calendar();
        let datas = calendar.createCalendarData(false);
        calendar.render(datas);
    }

    $(window).on('load', function() {
        console.log("called ready function");
        init();
    })

})();