自作のカレンダーの作成方法
Webシステムを作成していると時折出てくる悩みの自作カレンダーの作り方です。
いろんなライブラリがありそれでも良い場合もありますが、デザインや細かいところに手が届かない、特殊な動きをする場合など自作のカレンダーが作りたい場合があります。
今回は以下のようなカレンダーをJavascriptで自作をする方法です。
CodePenの実装例は以下のようになります。
See the Pen Untitled by take it easy (@take-it-easy) on CodePen.
HTML
<div class="calendar_area">
<div class="calendar_header">
<p id="year_month_label"></p>
<button id="prev_year_btn" onClick="prev_year()"><i class="fas fa-angle-double-left"></i></button>
<button id="prev_month_btn" onClick="prev_month()"><i class="fas fa-angle-left"></i></button>
<button id="now_btn" onClick="now_month()"><i class="fas fa-circle"></i></button>
<button id="next_month_btn" onClick="next_month()"><i class="fas fa-angle-right"></i></button>
<button id="next_year_btn" onClick="next_year()"><i class="fas fa-angle-double-right"></i></button>
</div>
<div id="calendar_body"></div>
</div>
3行目の”year_month_label”へJavascriptで年月を表示します。
4行目の”prev_year_btn”は、前年のカレンダーを表示するクリックイベントを設定します。
5行目の”prev_month_btn”は、前月のカレンダーを表示するクリックイベントを設定します。
6行目の”now_btn”は、実行当月のカレンダーを表示するクリックイベントを設定します。
7行目の”next_month_btn”は、前月のカレンダーを表示するクリックイベントを設定します。
8行目の”next_year_btn”は、前年のカレンダーを表示するクリックイベントを設定します。
10行目の”calendar_body”へJavascriptでカレンダーを作成し表示をします。
CSS
/* ヘッダー(年月とボタン) */
div.calendar_header {
text-align: center;
}
/* 年月 */
div.calendar_header > p#year_month_label {
margin: 20px 20px 10px;
font-size: 1.5em;
font-weight: bold;
}
/* ボタン */
button#prev_year_btn,
button#prev_month_btn,
button#now_btn,
button#next_month_btn,
button#next_year_btn {
width: 3em;
height: 2em;
}
/* カレンダーテーブル */
table.calendar_tbl {
min-width: 600px;
margin: 20px auto 0;
border: 1px solid;
border-collapse: collapse;
}
/* カレンダーテーブルの見出し(曜日) */
table.calendar_tbl tr th {
text-align: center;
border: 1px solid #000;
}
/* カレンダーテーブルの見出し(日曜日) */
table.calendar_tbl tr th:first-child {
color: #f00;
}
/* カレンダーテーブルの見出し(土曜日) */
table.calendar_tbl tr th:last-child {
color: #00f;
}
/* カレンダーテーブルの日付部分 */
table.calendar_tbl tr td {
vertical-align: middle;
text-align: center;
border: 1px solid #000;
height: 3em;
}
/* カレンダーテーブルで日付が入らない部分 */
table.calendar_tbl tr td.no_date {
background-color: #f2f2f2;
}
/* カレンダーテーブルの日付の部分(日曜日) */
table.calendar_tbl tr td:first-child {
z-index: 10;
background-color: #fadbda;
color: #f00;
}
/* カレンダーテーブルの日付の部分(土曜日) */
table.calendar_tbl tr td:last-child {
background-color: #ddeeff;
color: #00f;
}
/* マウスオーバー時 */
table.calendar_tbl tr td.with_date:hover {
background-color: #fadfc0;
}
Javascript
// 曜日の定義
const week = ["日", "月", "火", "水", "木", "金", "土"];
// 今日の日付
var today = new Date();
// 表示用の日付
var showDate = new Date(today.getFullYear(), today.getMonth(), 1);
// 表示された時
window.onload = function () {
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
};
/**
* カレンダーの表示
*/
function showCalendar(date) {
// 年
var year = date.getFullYear();
// 月
var month = date.getMonth() + 1;
// ヘッダーの年月に表示する文字列
var showDateStr = year + "年 " + month + "月";
// ヘッダーの年月部分に埋め込み
document.querySelector('#year_month_label').innerHTML = showDateStr;
// カレンダーテーブルを作成する(HTMLが返却される)
var calendarTable = createCalendarTable(year, month);
// カレンダー表示部分に埋め込み
document.querySelector('#calendar_body').innerHTML = calendarTable;
}
/**
* カレンダーテーブルの作成
*/
function createCalendarTable(year, month) {
// HTML用の変数
var _html = '';
// tableタグ
_html += '<table class="calendar_tbl">';
// テーブルのヘッダー(曜日)
_html += '<tr>';
for (var i = 0; i < week.length; i++) {
_html += "<th>" + week[i] + "</th>";
}
_html += '</tr>';
// ---------------------
// 表示するカレンダー年月の1日の曜日を取得
var startDayOfWeek = new Date(year, month - 1, 1).getDay();
// 日付
var countDay = 0;
// 月の末日
var monthOfEndDay = new Date(year, month, 0).getDate()
// 6行分繰り返し
for (var i = 0; i < 6; i++) {
_html += '<tr>';
// 7列(曜日の数)分繰り返し
for (var j = 0; j < week.length; j++) {
// 1行目で開始曜日と同じ場合
if (i == 0 && j == startDayOfWeek) {
// 日付+1
countDay++;
// tdタグ(日付有りが分かるようにクラス属性に"with_date"を設定)
_html += '<td class="with_date">' + countDay + '</td>';
}
// 日付が0以外で、日付が末日より小さい場合
else if (countDay != 0 && countDay < monthOfEndDay) {
// 日付+1
countDay++;
// tdタグ(日付有りが分かるようにクラス属性に"with_date"を設定)
_html += '<td class="with_date">' + countDay + '</td>';
}
else {
// tdタグ(日付無しが分かるようにクラス属性に"no_date"を設定)
_html += '<td class="no_date"></td>';
}
}
_html += '</tr>';
}
_html += '</table>';
// 組み立てたHTMLを返却
return _html;
}
/**
* 前年
*/
function prev_year() {
// 表示用の日付の年-1を設定
showDate.setFullYear(showDate.getFullYear() - 1);
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
}
/**
* 前月
*/
function prev_month() {
// 表示用の日付の月-1を設定
showDate.setMonth(showDate.getMonth() - 1);
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
}
/**
* 今日
*/
function now_month() {
// 表示用の日付に今日の日付を設定
showDate = new Date();
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
}
/**
* 来月
*/
function next_month() {
// 表示用の日付の月+1を設定
showDate.setMonth(showDate.getMonth() + 1);
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
}
/**
* 来年
*/
function next_year() {
// 表示用の日付の年+1を設定
showDate.setFullYear(showDate.getFullYear() + 1);
// カレンダーの表示(引数には表示用の日付を設定)
showCalendar(showDate);
}
処理の内容はコメントを参考にしてみてください。