NANIGE BLOG
2023.10.24
2023.11.15

jQueryでカレンダーを作る ~パート1~

今回はjqueryを使ってカレンダーを作成していきたいと思います。

htmlを用意

まずはhtmlを用意します。

今回は要素として

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

だけで大丈夫です。

jqueryのコード

お急ぎの方向けにjqueryのコードを貼っておきます。これでカレンダーの骨組みができます。

$(document).ready(function () {
    
    //作成したいカレンダーの年月を入れる
    const year = 2000
    const month = 2


    $(".calendar").html(CreateCalendar(year,month))
});
function CreateCalendar(year,month){
    const weeks = ['日', '月', '火', '水', '木', '金', '土']
    //取得する月の1日の情報
    const startDateOfMonth = new Date(year, month - 1, 1)
    //取得する月の最終日の情報
    const lastDateOfMonth = new Date(year, month, 0)
    //1日の曜日
    const startDay = startDateOfMonth.getDay()
    //取得する月のカレンダーの行数
    const Calendarline = CalendarLine(startDay,lastDateOfMonth.getDate())
    var CalendarElement = "<table>"
    //カレンダーの曜日の行を作成
    CalendarElement += "<tr>"
    for (let w = 0; w < 7; w++) {
        CalendarElement += "<td>" + weeks[w] + "</td>"
    }
    CalendarElement += "</tr>"
    var currentDate = 1;
    for (let line = 0; line < Calendarline;line++){
        CalendarElement += "<tr>"
        for (let w = 0; w < 7; w++){
            //カレンダーの一行目の場合は1日の曜日より前の枠は空欄にする
            //最終日を超えた場合の枠も空欄にする
            if ((line == 0 && w < startDay)){
                CalendarElement += "<td></td>"
                
            }
            else if (currentDate > lastDateOfMonth.getDate()){
                CalendarElement += "<td></td>"
                currentDate++
            }
            else{
                CalendarElement += "<td>"+currentDate+"</td>"
                currentDate++
            }
            
        }
        CalendarElement += "</tr>"
    }
    return CalendarElement
}
// //1日の曜日とその月の日数を引数にしてその月の行を返す関数
function CalendarLine(startDay,lastDateOfMonth){
    //(例)1日が(金)で最終日が31日の場合6行になる。→31日(日)
    if (startDay + lastDateOfMonth >= 36){
        return 6;
    }
    //うるう年でない2月の1日が日曜日の場合
    else if (startDay + lastDateOfMonth <= 28){
        return 4
    }
    //それ以外はすべて5行
    else {
        return 5
    }
}

このコードで出来上がるカレンダーは以下になります。

画像ファイル1

cssで装飾をしていないので味気ないですがちゃんとカレンダーですよね。

このカレンダーは2000年の2月です。先ほどのコードの4行目と5行目を操作すれば好きな年月のカレンダーができます。

コード解説

では一つ一つ解説をしていきましょう。

今回は2000年の2月を想定しています。

大まかな流れ

コードを解説する前に大まかな流れを確認したいと思います。

  1. 月初め(1日)の情報を取得
  2. 対象の月の最終日は何日なのか(28、29、30、31日のどれか)を取得
  3. カレンダーの行数を取得
  4. 1日からカレンダーに日付の要素を追加していく

ざっくりこのような流れになります。

使用する関数

今回は関数を作成して使用します。

まず一つ目にCreateCalendarという関数を作成して引数にyearとmonthを渡しています。

そしてこの関数の中にCalendarLineという関数を作成して対象の月のカレンダーの行を取得する関数を作成します。引数には1日の曜日最終日の値を渡します。

詳しく解説

コードを解説していきます。

まずweeksという配列を作成してそこに曜日を入れていきます。

次にDateオブジェクトを作成します。

以下のように書くことでそれぞれに日付のデータが入ります。

const startDateOfMonth = new Date(year, month - 1, 1)
const lastDateOfMonth = new Date(year, month, 0)

startDateOfMonthには対象の月の1日が入り、lastDateOfMonthには対象の月の最終日が入ります。ここで注意したいポイントですが第二引数のに注意しましょう。

monthは0から11までの値が入るのでもし2月の情報を入れたい場合は1を入れなければなりません。そのため今回はmonth -1という風に対象の月から1を引いています。

対象の月の最終日の取得方法

1日は引数に注意すれば簡単に取得できますが最終日はどうするのかといいますと、

対象の月の次の月の1日から一日戻ればよいのです。

イメージはこんな感じです。

画像ファイル2

ではどのように取得するかというと

画像ファイル3

このように2020年3月0日という情報を入れることにより、2020年3月1日から一日戻った日付を取得できるのです。これによっていちいち面倒なうるう年の計算などをしなくてもよくなります。

もし、自分で最終日を取得したい人は自分で計算式を使って頑張ってください!!

1日の曜日を取得

次に取得した1日のデータから曜日を取得しましょう

const startDay = startDateOfMonth.getDay()

このようにすることでstartDateOfMonthからstartDayという曜日のデータが取得できました。

曜日のデータとはここでは数値が入ります。

日曜日から0、1、2...と続き土曜日が6にあたります。

今回2000年の2月1日は火曜日ですのでstartDayには2が代入されています。

カレンダーの行を取得する

CalendarLineという関数でカレンダーの行を取得していきます。

カレンダーの行と先ほどから言っていますが何のことかといいますと、

画像ファイル4

こういうことです。

可能性として4行、5行、6行になることが考えられます。

実際にコードを見ていきましょう

function CalendarLine(startDay,lastDateOfMonth){
    if (startDay + lastDateOfMonth >= 36){
        return 6;
    }
    else if (startDay + lastDateOfMonth <= 28){
        return 4
    }
    else {
        return 5
    }
}

引数には1日の曜日(今回は2)と最終日(今回は29)を渡します。

このCalendarLine関数では何をしているのかというと条件によって行の数値を返す働きをしています。

6行になる場合

6行になる場合の条件を考えていきます。

皆さんもカレンダーを片手に考えてみましょう。

条件としては

  • 1日が金曜日で最終日が31日
  • 1日が土曜日で最終日が30日もしくは31日

の場合になります。これをごり押しでif文を使ってもいいのですが、せっかく曜日の数値を引数にしているのでエレガントに書いていきましょう。

金曜日は数値に直すと5、土曜日は6になります。

ということは先ほどの条件から曜日と日付を足して36以上になる時に6行になることがわかります。

上記のコードの最初のif文はそれを表しています。

4行になる場合

4行になる場合も同様の考え方をします。

条件は

  • 1日が日曜日で最終日が28日

の場合です。

上記のコードでは不等号を使用していますが等号でもかまいません。

5行になる場合

5行になる場合は多く存在しますが今回は4行でも6行でもない場合はすべて5行になりますのでelse文で書いていきます。

※丁寧に不等号で示したい方はそのように書いても問題ありません

要素を追加する

それでは必要な情報を取得できたので実際に要素を追加していきましょう。

今回はtableタグを使っていきます。

<table>
<tr> <td>1</td><td>2</td><td>3</td></tr>
<tr> <td>4</td><td>5</td><td>6</td></tr>
<tr> <td>7</td><td>8</td><td>9</td></tr>
</table>

tableタグは上記のように使用します。trタグは行をtdタグはセルだと思うと理解がしやすいです。

このように縦横をそろえるカレンダーではtableタグが使いやすいのでこれを使っていきます。

初めの行を作成

    var CalendarElement = "<table>"
    CalendarElement += "<tr>"
    for (let w = 0; w < 7; w++) {
        CalendarElement += "<td>" + weeks[w] + "</td>"
    }
    CalendarElement += "</tr>"

まずはCalendarElementという変数を宣言しそれらに要素を追加していきます。

はじめは「日月火水木金土」という行を追加したいので初めに作成したweeksという配列を回しながら要素を追加していきます。

ここではfor文の解説は割愛します。

日付の要素を作成

    var currentDate = 1;
    for (let line = 0; line < Calendarline;line++){
        CalendarElement += "<tr>"
        for (let w = 0; w < 7; w++){
            if ((line == 0 && w < startDay)){
                CalendarElement += "<td></td>"
                
            }
            else if (currentDate > lastDateOfMonth.getDate()){
                CalendarElement += "<td></td>"
                currentDate++
            }
            else{
                CalendarElement += "<td>"+currentDate+"</td>"
                currentDate++
            }
            
        }
        CalendarElement += "</tr>"
    }

curentDateという変数を作成します。

これは日付を表すカウンターになるのでインクリメントしていきます。

まず始めのfor文ではカレンダーの行の分だけ繰り返します。

先ほどCalendarLineで取得した値を使用します。

二つの目のfor文では曜日の列の分だけ繰り返します。

もちろん7行あります。

ここからが少しややこしいのですが

一行目の一列目から要素を追加していく動作を条件分岐で追加していきます。

  1. 1行目は1日の曜日に該当するまで(今回は3列目まで)は要素は空のtdタグを追加する。currentDateはインクリメントしない
  2. 1日の曜日が該当したらそこからtdタグの中に日付を入れる。
  3. currentDateが最終日を超えたときは空のtdタグを追加する。currentDateはインクリメント(厳密にはどちらでもよい)

このようにして要素を追加していきます。

注意するべきポイントはcurrentDateは最終日を超えることがあることです。

今回(2020年2月)は5行あるため、5行目の7列目(本当なら33日にあたるところ)までcurrentDateはインクリメントします。

ですので途中で空のtdタグを入れないとうまく表示されなくなります。

html要素に追加する

ここまで来たらあとは楽勝です。

関数の中で以下のように値を返してあげましょう。

CalendarElementにはtableタグの要素が文字列で格納されています。

return CalendarElement

最初に戻りますがcalendarというクラス名を持つ要素にhtmlを追加してあげましょう

$(".calendar").html(CreateCalendar(year,month))

これで完成です。

次回はcssで装飾していきます。

あわせて読みたい

jQueryでカレンダーを作る ~パート2~

ABOUT ME
たけし
元教育業界で講師を務め

未経験で転職を成功。

現在はWEBを中心に

SEとして活躍中

djangoやlaravelを主に扱う

保有資格:

・ AWS SAA(ソリューションアーキテクトアソシエイト)

・統計検定2級

・日商簿記2級