JS カレンダー

【index.html】

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Selectable Calendar</title>
  <link rel="stylesheet" href="index.css">
    <script src="index.js" defer></script> 
</head>
<body>

    <div class="wrapper">
        <!-- xxxx年xx月を表示 -->
        <h1 id="header"></h1>
    
        <!-- ボタンクリックで月移動 -->
        <div id="next-prev-button">
            <button id="prev" onclick="prev()">1か月前</button>
            <button id="prev" onclick="prev12()">1年前</button>

            <button id="next" onclick="next()">1か月後</button>
            <button id="next" onclick="next12()">1年後</button>

        </div>
    
        <!-- カレンダー -->
        <div id="calendar"></div>
    </div>

</body>
</html>

【index.css】

@charset "utf-8";

/*全体*/
.wrapper{
    max-width: 600px;
    margin: 0 auto;
    color: #666 ;
} #header  {
    text-align: center;
    font-size: 24px;
    width: 100%;
    margin: 1rem 0 0;
}

/*カレンダー*/ #calendar  {
    text-align: center;
    width: 100%;
}
table {
    outline: 2px solid #ddd ;
    border-collapse: collapse;
    width: 100%;
}
th {
    color: #000 ;
}
th, td {
    outline: 1px solid #ddd ;
    padding-top: 10px;
    padding-bottom: 10px;
    text-align: center;
}
/*日曜日*/
td:first-child {
    color: red;
}
/*土曜日*/
td:last-child {
    color: blue;
}
/*前後月の日付*/
td.disabled {
    color: #ccc ;
}
/*本日*/
td.today {
    background-color: #D65E72 ;
    color: #fff ;
}

.selected {
  background-color: #ffffff ;
  color: #fff ;
  border: 1px solid #fff ;
}

/*ボタン*/ #next -prev-button {
    position: relative;
} #next -prev-button button{
    cursor: pointer;
    background: #B78D4A ;
    color: #fff ;
    border: 1px solid #B78D4A ;
    border-radius: 4px;
    font-size: 1rem;
    padding: 0.5rem 2rem;
    margin: 3px;
} #next -prev-button button:hover{
    background-color: #D4BB92 ;
    border-color: #D4BB92 ;
} #prev  {
    float: left;
} #next  {
    float: right;
} #prev12  {
  float: left;
} #next12  {
  float: right;
}

【index.js】

const week = ["日", "月", "火", "水", "木", "金", "土"];
const today = new Date();
var showDate = new Date(today.getFullYear(), today.getMonth(), 1);

window.onload = function () {
    showProcess(showDate);
};

function prev() {
    showDate.setMonth(showDate.getMonth() - 1);
    showProcess(showDate);
}

function next() {
    showDate.setMonth(showDate.getMonth() + 1);
    showProcess(showDate);
}

function prev12() {
    showDate.setMonth(showDate.getMonth() - 12);
    showProcess(showDate);
}

function next12() {
    showDate.setMonth(showDate.getMonth() + 12);
    showProcess(showDate);
}

function showProcess(date) {
    var year = date.getFullYear();
    var month = date.getMonth();
    document.querySelector('#header').innerHTML = year + "年 " + (month + 1) + "月";

    var calendar = createProcess(year, month);
    document.querySelector('#calendar').innerHTML = '';
    document.querySelector('#calendar').appendChild(calendar);
}

function createProcess(year, month) {
    var table = document.createElement('table');

    var dayOfWeekRow = document.createElement('tr');
    for (var i = 0; i < week.length; i++) {
        var th = document.createElement('th');
        th.textContent = week[i];
        dayOfWeekRow.appendChild(th);
    }
    table.appendChild(dayOfWeekRow);

    var count = 0;
    var startDayOfWeek = new Date(year, month, 1).getDay();
    var endDate = new Date(year, month + 1, 0).getDate();
    var lastMonthEndDate = new Date(year, month, 0).getDate();
    var row = Math.ceil((startDayOfWeek + endDate) / week.length);

    for (var i = 0; i < row; i++) {
        var tr = document.createElement('tr');
        for (var j = 0; j < week.length; j++) {
            var td = document.createElement('td');
            if (i == 0 && j < startDayOfWeek) {
                td.textContent = lastMonthEndDate - startDayOfWeek + j + 1;
                td.classList.add('disabled');
            } else if (count >= endDate) {
                count++;
                td.textContent = count - endDate;
                td.classList.add('disabled');
            } else {
                count++;
                td.textContent = count;
                if (year == today.getFullYear() && month == today.getMonth() && count == today.getDate()) {
                    td.classList.add('today');
                }
            }
            tr.appendChild(td);
        }
        table.appendChild(tr);
    }
    return table;
}

選択式

【index.html】

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Selectable Calendar</title>
  <link rel="stylesheet" href="index.css">
    <script src="index.js" defer></script> 
</head>
<body>

    <div class="wrapper">
        <!-- xxxx年xx月を表示 -->
        <h1 id="header"></h1>
    
        <!-- ボタンクリックで月移動 -->
        <div id="next-prev-button">
            <button id="prev" onclick="prev()">1か月前</button>
            <button id="prev" onclick="prev12()">1年前</button>

            <button id="next" onclick="next()">1か月後</button>
            <button id="next" onclick="next12()">1年後</button>

        </div>
    
        <!-- カレンダー -->
        <div id="calendar"></div>

        <div id="selected-dates"></div>
    </div>

</body>
</html>

【index.css】

@charset "utf-8";

/*全体*/
.wrapper {
    max-width: 600px;
    margin: 0 auto;
    color: #666 ;
}
 #header  {
    text-align: center;
    font-size: 24px;
    width: 100%;
    margin: 1rem 0 0;
}

/*カレンダー*/ #calendar  {
    text-align: center;
    width: 100%;
}

table {
    outline: 2px solid #ddd ;
    border-collapse: collapse;
    width: 100%;
}

th {
    color: #000 ;
}

th,
td {
    outline: 1px solid #ddd ;
    padding-top: 10px;
    padding-bottom: 10px;
    text-align: center;
}

/*日曜日*/
td:first-child {
    color: red;
}

/*土曜日*/
td:last-child {
    color: blue;
}

/*前後月の日付*/
td.disabled {
    color: #ccc ;
}

/*本日*/
td.today {
    background-color: #D65E72 ;
    color: #fff ;
}

.selected {
    background-color: #D4BB92 ;
    color: #fff ;
    border: 1px solid #B78D4A ;
}

/*マウスを載せた時のスタイル*/
td:not(.disabled):hover {
    background-color: #f2f2f2 ;
    cursor: pointer;
}

/*ボタン*/ #next -prev-button {
    position: relative;
}
 #next -prev-button button {
    cursor: pointer;
    background: #B78D4A ;
    color: #fff ;
    border: 1px solid #B78D4A ;
    border-radius: 4px;
    font-size: 1rem;
    padding: 0.5rem 2rem;
    margin: 3px;
}
 #next -prev-button button:hover {
    background-color: #D4BB92 ;
    border-color: #D4BB92 ;
}
 #prev  {
    float: left;
}
 #next  {
    float: right;
}
 #prev12  {
    float: left;
}
 #next12  {
    float: right;
}

【index.js】

const week = ["日", "月", "火", "水", "木", "金", "土"];
const today = new Date();
var showDate = new Date(today.getFullYear(), today.getMonth(), 1);
var selectedDates = []; // 日付を保持する配列

window.onload = function () {
    showProcess(showDate);
};

function prev() {
    showDate.setMonth(showDate.getMonth() - 1);
    showProcess(showDate);
}

function next() {
    showDate.setMonth(showDate.getMonth() + 1);
    showProcess(showDate);
}

function prev12() {
    showDate.setMonth(showDate.getMonth() - 12);
    showProcess(showDate);
}

function next12() {
    showDate.setMonth(showDate.getMonth() + 12);
    showProcess(showDate);
}

function showProcess(date) {
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    document.querySelector('#header').innerHTML = year + "年 " + month + "月";

    var calendar = createProcess(year, month - 1); // createProcessの引数で月を0-indexedに変更
    document.querySelector('#calendar').innerHTML = '';
    document.querySelector('#calendar').appendChild(calendar);

    // 選択可能な日付を設定
    var cells = document.querySelectorAll('#calendar td:not(.disabled)');
    cells.forEach(function(cell) {
        cell.addEventListener('click', function() {
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var day = parseInt(this.textContent); // 選択された日付

            var dateStr = year + '/' + month + '/' + day; // 年月日の形式に変換

            var index = selectedDates.indexOf(dateStr); // 日付が配列に含まれているか確認

            if (index === -1) {
                // 日付が配列に含まれていない場合、追加
                selectedDates.push(dateStr);
                this.classList.add('selected');
            } else {
                // 日付が配列に含まれている場合、削除
                selectedDates.splice(index, 1);
                this.classList.remove('selected');
            }

            updateSelectedDates(); // 選択された日付を表示する要素を更新
        });
    });
}

function createProcess(year, month) {
  var table = document.createElement('table');

  var dayOfWeekRow = document.createElement('tr');
  for (var i = 0; i < week.length; i++) {
      var th = document.createElement('th');
      th.textContent = week[i];
      dayOfWeekRow.appendChild(th);
  }
  table.appendChild(dayOfWeekRow);

  var count = 0;
  var startDayOfWeek = new Date(year, month, 1).getDay();
  var endDate = new Date(year, month + 1, 0).getDate();
  var lastMonthEndDate = new Date(year, month, 0).getDate();
  var row = Math.ceil((startDayOfWeek + endDate) / week.length);

  for (var i = 0; i < row; i++) {
      var tr = document.createElement('tr');
      for (var j = 0; j < week.length; j++) {
          var td = document.createElement('td');
          if (i == 0 && j < startDayOfWeek) {
              td.textContent = lastMonthEndDate - startDayOfWeek + j + 1;
              td.classList.add('disabled');
          } else if (count >= endDate) {
              count++;
              td.textContent = count - endDate;
              td.classList.add('disabled');
          } else {
              count++;
              td.textContent = count;
              if (year == today.getFullYear() && month == today.getMonth() && count == today.getDate()) {
                  td.classList.add('today');
              }
          }
          tr.appendChild(td);
      }
      table.appendChild(tr);
  }
  return table;
}

// 追加:選択された日付を表示する要素を更新する関数
function updateSelectedDates() {
  var selectedDatesElement = document.querySelector('#selected-dates');
  selectedDatesElement.innerHTML = ''; // 内容をリセット

  if (selectedDates.length > 0) {
      selectedDatesElement.innerHTML = '選択された日付: ';
      selectedDates.forEach(function(date) {
          selectedDatesElement.innerHTML += date + ' ';
      });
  } else {
      selectedDatesElement.innerHTML = '選択された日付: なし';
  }
}

この記事が気に入ったらサポートをしてみませんか?