【jQueryでカレンダーを作ってみた】
jQueryの勉強がてらに、カレンダーを作成したので、要点メモ
今回作成する主なカレンダーの機能
・年、月、日、曜日の出力
・前月、次月の切り替え
・表示、非表示の切り替え
以上のようなカレンダーを作っていきます。
用意したHTMLはコチラ
index.html
<!doctype html>
<html lang="ja">
<head>
<meta name="robots" content="noindex"><!-- クローラー回避 -->
<meta charset="utf-8">
<title>カレンダー</title>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="js/schedule.js" type="text/javascript"></script><!-- ここで読み込まなくても可 -->
<script src="js/calendar.js" type="text/javascript"></script>
<!-- css -->
<link href="css/normalize.css" rel="stylesheet" type="text/css">
<link href="css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<form method="post" action="#">
<input type="text" value="日付を入力してください" id="calendar_form">
<button type="submit">送信</button>
</form>
<div id="calendar"></div>
</body>
</html>
jQueryのバージョンは3.4.1
■ schedule.js
まず、休日設定用のデータを作成
schedule.js
// 休日指定したい日付を連想配列で指定しておく
var holidays = {
// 休日設定していない場合のために、デフォルト値を設定
'default':[
{'1':[]},
{'2':[]},
{'3':[]},
{'4':[]},
{'5':[]},
{'6':[]},
{'7':[]},
{'8':[]},
{'9':[]},
{'10':[]},
{'11':[]},
{'12':[]}
],// 設定例:2019年1月1,2,3日が休日の場合 '2019':[{1:[1,2,3]}]
'2019':[
{'1':[]},
// 省略
{'12':[]}
]
}
もっとスマートに描く方法はないものか、、、
連想配列の“キー”に“年”、“月”を設定し、該当の“日”を割り出せるように作成
■ calendar.js
カレンダー本体の作成
・カレンダー本体を出力するボタン作成
・操作ボタンを出力
・日付クリックで日付情報取得
calendar.js
/*global $*/
/* jQuery Contents */
$(function(){
// カレンダー出力ボタンの設置
distBtn.init();
// カレンダーの表示非表示の制御
var clickCount = 0;
dBtn.on('click', function(){
if(closeBtn != 'off'){
clickCount++;
}
if(closeBtn == 'off'){
clickCount = clickCount + 0;
}
if(clickCount%2 == 1){
calendar.init();
calendarPanel.init();
clickToActions.init();
dataDist.init();
closeCalBtn.init();
$('#calendar').css('display', 'none').fadeIn();
}else{
$("#btns").fadeOut(function(){
$(this).remove();
});
calInner.fadeOut(function(){
$(this).remove()
});
}
});
});
// calendar close function
var closeCalBtn = (function(){
function init(){
closeBtn.on('click', function(){
$("#btns").fadeOut(function(){
$(this).remove();
});
calInner.fadeOut(function(){
$(this).remove()
});
closeBtn = 'off';
});
}
return {init:init}
})();
var calInner = '';
var closeBtn = '';
//////////////////////////// calendar close
// calendar dist btn function
var distBtn = (function(){
function init(){
var distBtn = '<div id="calBtn"><span>calendar</span></div>'
$("#calendar").before(distBtn);
dBtn = $("#calBtn");
}
return {init:init}
})();
var dBtn = '';
//////////////////////////// calendar dist
// 祝日設定 html上でなく、ここでも取得可
//$.get('js/schedule.js');
/*-----------------------
variables
------------------------*/
var now, now_m, now_y;
now = new Date();
now_m = now.getMonth()+1;
now_y = now.getFullYear();
var weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var prevText = 'prev';
var nextText = 'next';
var yearData = '';
var monthData = '';
var weekData = '';
var daysArea = '';
var prevdaysArea = '';
var nextdaysArea = '';
/*-----------------------
clickToActions
------------------------*/
var clickToActions = (function(){
function init() {
var _cal = '';
var dt = now;
$("#btns a").on("click", function(){
if($(this).is(":contains("+prevText+")")){
_cal = $("#calInner");
_cal.remove();
dt.setDate(1);
dt.setMonth(dt.getMonth()-1);
now_m = dt.getMonth()+1;
now_y = dt.getFullYear();
calendar.init();
dataDist.init();
closeCalBtn.init();
}
if($(this).is(":contains("+nextText+")")){
_cal = $("#calInner");
_cal.remove();
dt.setDate(1);
dt.setMonth(dt.getMonth()+1);
now_m = dt.getMonth()+1;
now_y = dt.getFullYear();
calendar.init();
dataDist.init();
closeCalBtn.init();
}
});
}
return {init:init};
})();
/*-----------------------
calendar panel
------------------------*/
var calendarPanel = (function(){
function init() {
// 操作パネル追加
var panelHtml = '<div id="btns"><a>'+prevText+'</a><a>'+nextText+'</a></div>';
$("#calendar").append(panelHtml);
}
return {init:init};
})();
/*-----------------------
calendar
------------------------*/
var calendar = (function(){
function init() {
// 月の末日出力
function getMonthDays(year, month) {
return new Date(year, month, 0).getDate();
}
// 引数が当月なら本日の日を返す
var isToday = (function istoday(year, month){
var _ = new Date();
var toYear = _.getFullYear();
var toMonth = _.getMonth()+1;
if(toMonth == month && toYear == year){
return new Date().getDate();
}else{
return false;
}
});
// 当月日数分表示(祝日にはclass="holiday")
var gmd = getMonthDays(now_y, now_m);
var check = '';
if(holidays[now_y]){
check = holidays[now_y][now_m-1];
}else{
check = holidays['default'][now_m-1];
}
var daysHTML = '';
for(var i=1; i<=gmd; ++i){
if(check[now_m].indexOf(i) >= 0){
daysHTML += '<li class="holiday"><span>' + i +'</span></li>';
}else if(isToday(now_y, now_m) == i){
daysHTML += '<li class="today"><span>' + i +'</span></li>';
}else{
daysHTML += '<li><span>' + i +'</span></li>';
}
}
// 前月端数表示
var monthFirstWeekNum = new Date(now_y, now_m - 1, 1).getDay();
var beforeDt = new Date(now_y,now_m - 1, 0);
var prevDays = beforeDt.getDate()+1;
var prevHTML = '';
for(var num=0; num<monthFirstWeekNum; ++num){
prevDays = prevDays -1;
prevHTML = '<li class="prev"><span>'+prevDays+'</span></li>'+prevHTML;
}
// 翌月端数表示
var monthLastWeekNum = new Date(now_y, now_m, 0).getDay();
var nextDays = 0;
var nextHTML = '';
for(var numb=monthLastWeekNum+1; numb<=6; ++numb){
nextDays++;
nextHTML += '<li class="next"><span>'+nextDays+'</span></li>';
}
var html = '';
html = '<div id="calInner">';
html += '<div id="closeBtn"><a>close</a></div>';
html += '<div id="year"><p>'+now_y+'</p></div>';
html += '<div id="month"><p>'+now_m+'</p></div>';
var week = '';
$.each(weekdays, function(index, value){
week += '<li><span>'+value+'</span></li>';
});
html += '<div id="week"><ul>'+week+'</ul></div>';
html += '<ul>' + prevHTML + daysHTML + nextHTML + '</ul></div>';
// id="calendar"取得
var cal = $('#calendar');
// html出力
cal.prepend(html);
calInner = $("#calInner");
closeBtn = $("#closeBtn");
yearData = $("#year");
monthData = $("#month");
daysArea = $("#calInner>ul li:not(.prev, .next)");
prevdaysArea = $("#calInner>ul li.prev");
nextdaysArea = $("#calInner>ul li.next");
weekData = $("#week>ul li");
}
return {init:init};
})();
// クリックで文字列取得
var dataDist = (function(){
function init(){
daysArea.on('click', function(){
daysArea.removeClass("on");
prevdaysArea.removeClass("on");
nextdaysArea.removeClass("on");
$(this).addClass("on");
var otherDt = new Date(yearData.text(), monthData.text() - 1, $(this).text()).getDay();
var otherWeek = weekdays[otherDt];
var dateData = yearData.text() + "年" + monthData.text() + "月" + $(this).text() + "日" + "(" + otherWeek + ")";
$('#calendar_form').attr('value', dateData);
})
prevdaysArea.on('click', function(){
daysArea.removeClass("on");
prevdaysArea.removeClass("on");
nextdaysArea.removeClass("on");
$(this).addClass("on");
var opDt = new Date(yearData.text(), monthData.text() - 2, $(this).text()).getDay();
var opWeek = weekdays[opDt];
var pMonth = monthData.text() - 1;
var pdateData = yearData.text() + "年" + pMonth + "月" + $(this).text() + "日" + "(" + opWeek + ")";
$('#calendar_form').attr('value', pdateData);
})
nextdaysArea.on('click', function(){
daysArea.removeClass("on");
prevdaysArea.removeClass("on");
nextdaysArea.removeClass("on");
$(this).addClass("on");
var onDt = new Date(yearData.text(), monthData.text(), $(this).text()).getDay();
var onWeek = weekdays[onDt];
var nMonth = parseInt(monthData.text()) + parseInt(1);
var ndateData = yearData.text() + "年" + nMonth + "月" + $(this).text() + "日" + "(" + onWeek + ")";
$('#calendar_form').attr('value', ndateData);
})
yearData.on('click', function(){
yearData.removeClass("on");
$(this).addClass("on");
})
monthData.on('click', function(){
monthData.removeClass("on");
$(this).addClass("on");
})
weekData.on('click', function(){
weekData.removeClass("on");
$(this).addClass("on");
})
}
return {init:init}
})();
これでhtmlの出力制御を行い、見た目をcssで整形
用途不明だが、カレンダーでフォームの日付入力するのに役立つかも…