3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【jQuery】カレンダーの作り方

Posted at

【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で整形

用途不明だが、カレンダーでフォームの日付入力するのに役立つかも…

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?