/* * カレンダー設定 * * monthOffset: カレンダーを生成する月(yyyy/mm) * publicHolidays: 祝日 */ const CALENDAR_SETTINGS = [ { monthOffset: '2019/12', publicHolidays: [], }, { monthOffset: '2020/01', publicHolidays: [1, 13], }, ]; $(window).on('load', function() { // 営業日カレンダーを出力 $.each(CALENDAR_SETTINGS, function(index, settings) { rendarCalendar(settings); }); }); /** * カレンダーを出力する * * @param object settigs 設定オブジェクト * @return void */ function rendarCalendar(settings) { const weekLabels = ['日', '月', '火', '水', '木', '金', '土']; const classes = { container: 'p-calendars__container', table: 'c-calendar', caption: 'c-calendar__caption', today: 'c-calendar__today', sunday: 'c-calendar__sunday', saturday: 'c-calendar__saturday', publicholidays: 'c-calendar__public-holidays', } const today = new Date(); const monthOffset = settings.monthOffset ? new Date(settings.monthOffset + '/01') : today; const currentYear = monthOffset.getFullYear(); const currentMonth = monthOffset.getMonth(); const firstDay = new Date(currentYear, currentMonth, 1); const nextMonth = new Date(currentYear, firstDay.getMonth() + 1).getMonth(); const year = firstDay.getFullYear(); const month = firstDay.getMonth(); const day = new Date(year, month, firstDay.getDate() - firstDay.getDay()); const calendars = $('.p-calendars'); const calendar_container = $('<div>').addClass(classes.container); const calendar = $('<table>').addClass(classes.table); const caption = $('<caption>').addClass(classes.caption); appendCaption(); appendWeeks(); appendBody(); calendars.append(calendar_container.append(calendar)); /** * キャプション(年月)と追加する * * @return void */ function appendCaption() { caption.append(year + '年 ' + (month + 1) + '月'); calendar.append(caption); } /** * 曜日を追加する * * @return void */ function appendWeeks() { const thead = $('<thead>'); const weeks = $('<tr>'); $.each(weekLabels, function(index, value) { const th = $('<th>' + value + '</th>').attr('scope','col'); // 日曜日 if (index === 0) { th.addClass(classes.cellSunday); // 土曜日 } else if (index === 6) { th.addClass(classes.cellSaturday); } weeks.append(th); }); thead.append(weeks) calendar.append(thead); } /** * 日付を追加する * * @return void */ function appendBody() { const tbody = $('<tbody>'); for (let row = 0; row < 10; row++) { const daysLine = $('<tr>'); for(let col = 0; col < 7; col++) { const td = $('<td>'); if (day.getMonth() === month) { td.text(day.getDate()); // 当日 if (isSameDate(day, today)) { td.addClass(classes.today); } // 日曜日 if (day.getDay() === 0) { td.addClass(classes.sunday); // 祝日 } else if ($.inArray(day.getDate(), settings.publicHolidays) !== -1) { td.addClass(classes.publicholidays); // 土曜日 } else if (day.getDay() === 6) { td.addClass(classes.saturday); } } else { td.html(' '); } daysLine.append(td); day.setDate(day.getDate() + 1); } tbody.append(daysLine) if (day.getMonth() === nextMonth) break; } calendar.append(tbody); } /** * 2つの年月日が同じかを返す * * @param Date date1 * @param Date.date2 * @return bool */ function isSameDate(date1, date2) { if ( date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate() ) { return true; } return false; } }
<div class="p-calendars"></div>
.p-calendars { max-width: 200px; > *:nth-child(n+2) { margin-top: 20px; } } .c-calendar { table-layout: fixed; border-collapse: collapse; width: 100%; th, td { vertical-align: middle; text-align: center; line-height: 1.75; } &__caption { margin-bottom: 5px; padding-bottom: 5px; border-bottom: 1px solid #ccc; font-weight: 700; } &__today { font-weight: 700; } &__sunday { color: #f00; } &__saturday { color: #00f; } &__public-holidays { color: #f00; } }