【実践プログラミング②】JavaScript カレンダーを作成する ver2 / 難易度　★★★☆☆

#プロローグ

[前回](https://qiita.com/natsumi_23/items/eedb37c782e6e40edba4)のカレンダーをよりグレードアップさせようと思い、今回の実践プログラミングを行います。

前回の反省：今日の日付だけ色を変えることができたが、翌月のおなじ日にちも色が変わっている。
**=>何故そうなったのか**
day === today（日にちがX日だったら、色を変える）だけだったので、より詳しく条件を絞る必要があった。
日にちがX日X月X年だったら、色を変える、というように。

ちなみに、難易度の設定はプログラミング歴１１ヶ月、JS歴２ヶ月（2020年11月現在）で
他の方のコードを読み解き理解しながら作れた時間が多いほど、難易度をあげてます。
また、読み解けきれなかった部分が多い場合も難易度をあげてます。

今回は、時間がかかったのと、先にお知らせしておきますが・・・、自分の設定した条件をクリアできなかったので★★★☆☆です…。

また、今回の場合は人のコードを読み解くことがメインすぎて、自力で考えて書いてみたコードはないです。
でも、人のコードを読んで何をしたいのか考えることも、勉強になった気がします。
こういう実践の仕方もありなのかな、と思いました。


ちなみに、コピペは一切しないというルールの元やっています。
タイピングも実践プログラミングの１つです。

#今回の問題
「JSを使用してカレンダーを作成しよう　ver2」　難易度　★★★☆☆
条件：参考記事＋αで、日付指定も加えて、指定した日付に色をつけること

#参考記事
「[javascriptを使ったWEBカレンダー（設置サンプル3種）](https://lpeg.info/html/javascript_css_calendar.html)」
ありがとうございます。勉強になりました。


#コードを書く

前回同様、コード内にコメントでメゾットやら説明を書いてあります。
誤ってたらご報告お願い致します。

まずは、HTMLです。

```ruby:calendar2.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>calendar</title>
    <link rel="stylesheet" href="calendar2.css">
</head>
<body>
   <div class="container-calendar">
       <h4 id="monthAndYear"></h4>
       <div class="button-container-calendar">
           <button id="prev" onclick="prev()">前月</button>
           <button id="next" onclick="next()">翌月</button>
       </div>

       <table class="table-calendar" id="calendar" data-lang="ja">
           <thead id="thead-month"></thead> <!-- 曜日の枠 -->
           <thead id="calendar-body"></thead>
       </table>

       <div class="footer-container-calendar">
           <label for="month">日付指定</label>
           <select id="year" onchange="jump()"></select>
           <select id="month" onchange="jump()">
            <option value=0>1月</option>
            <option value=1>2月</option>
            <option value=2>3月</option>
            <option value=3>4月</option>
            <option value=4>5月</option>
            <option value=5>6月</option>
            <option value=6>7月</option>
            <option value=7>8月</option>
            <option value=8>9月</option>
            <option value=9>10月</option>
            <option value=10>11月</option>
            <option value=11>12月</option>            
           </select>
       </div>
   </div>
</body>
<script src="calendar2.js"></script>
</html>

```
次に、JSです。

```ruby:calendar2.js
unction generate_year_range(start, end) {
    var years = "";
    #varでは再宣言、再代入が可能です。
    for (var year = start; year <= end; year++) {
        years += "<option value='" + year + "'>" + year + "</option>";
    }
    return years;
}

var today = new Date();
var currentMonth = today.getMonth();
var currentYear = today.getFullYear();
var selectYear = document.getElementById("year");
var selectMonth = document.getElementById("month");
#element：HTML や XML 文書における、要素（タグ）に相当

var createYear = generate_year_range(1995, 2050);
#プルダウンの年の範囲

document.getElementById("year").innerHTML = createYear;
#.innerHTML：html要素の中身を変更することができるJavaScriptの便利な関数

var calendar = document.getElementById("calendar");
var lang = calendar.getAttribute('data-lang');
#htmlカレンダー テーブルの表示
#id="calendar" の要素の data-lang の値を表示します。

var months = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",];
var days = ["日","月","火","水","木","金","土"];
#カレンダーにて表示させる文字列

var dayHeader ="<tr>";
for (day in days) {
    dayHeader += "<th data-days='" + days[day] + "'>" + days[day] +"</th>";
}
dayHeader += "</tr>";

document.getElementById("thead-month").innerHTML = dayHeader;
#thead-monthを取得して、そこにdaysを導入してる

monthAndYear = document.getElementById("monthAndYear");
showCalendar(currentMonth, currentYear);
#htmlのh4に当たる部分
#show は要素を表示？ =>すみません、ここは調べてもわからなかった部分です。再度調べます。

function next() {
    currentYear = (currentMonth === 11) ? currentYear + 1 : currentYear;
    currentMonth = (currentMonth + 1) % 12;
    showCalendar(currentMonth, currentYear);
}

function prev() {
    currentYear = (currentMonth === 0) ? currentYear - 1 : currentYear;
    currentMonth = (currentMonth === 0) ? 11 : currentMonth - 1;
    showCalendar(currentMonth, currentYear);
}

function jump() {
    currentYear = parseInt(selectYear.value); #parseIntは整数専用であり、数字だけ解析して取り出すことが可能
    currentMonth = parseInt(selectMonth.value);
    showCalendar(currentMonth, currentYear); 
}


function showCalendar(month, year) {  #カレンダーの数字部分を作成する
    var firstDay = ( new Date( year, month, ) ).getDay();

    tbl = document.getElementById("calendar-body");
    tbl.innerHTML = "";
    #カレンダーの数字部分

    monthAndYear.innerHTML = year + "年 " + months[month] ;
    selectYear.value = year;
    selectMonth.value = month;
    #selectオブジェクトの値（value）

    var date = 1;
    for (  var i = 0; i < 6; i ++) {
        var row = document.createElement("tr");

        for ( var j = 0; j < 7; j++ ) {
            if ( i === 0 && j <firstDay) {
                cell = document.createElement("td");
                cellText = document.createTextNode("");  #.createTextNodeは、「HTML 文書」などの、タグ以外の文字データに相当する
                cell.appendChild(cellText);
                row.appendChild(cell);
            } else if (date > daysInMonth(month, year)) { #日数がその月より多くなったらここで終了
                break;
            } else {
                cell = document.createElement("td");
                cell.setAttribute("data-date", date);
                cell.setAttribute("data-month", month + 1);
                cell.setAttribute("data-year", year);
                cell.setAttribute("data-month_name", months[month]);
                cell.className = "date-picker";
                cell.innerHTML = "<span>" + date + "</span>";

                if ( date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
                    cell.className = "date-picker selected"; #対象要素のクラス名が cellの"td" であった場合の処理をここに記述。今日だった場合、クラス名をつけてcssで色をつける
                }
                #前回は、ここの条件が甘かったので、全部の月の同じ日に色がついてしまった。
                row.appendChild(cell); #.appendChild：要素を指定し、その要素の子要素として、HTMLタグを追加することができます。この場合は"td"？
                date++;
            }
        }

        tbl.appendChild(row);
    }
}

function daysInMonth(iMonth, iYear) {
    return 32 - new Date(iYear, iMonth, 32).getDate();
}


```

最後に、cssです。

```ruby:calendar2.css

.wrapper {
    margin: 15px auto;
    max-width: 700px;
  }
  .container-calendar {
    background: #ffffff;
    padding: 15px;
    width: 100%;
    margin: 0 auto;
    overflow: auto;
  }
  .button-container-calendar button {
    cursor: pointer;
    display: inline-block;
    zoom: 1;
    background: #00a2b7;
    color: #fff;
    border: 1px solid #0aa2b5;
    border-radius: 4px;
    padding: 5px 10px;
  }
  .table-calendar {
    border-collapse: collapse;
    width: 100%;
  }
  .table-calendar th,
  .table-calendar td{
    padding: 10px;
    border: 1px solid #e2e2e2;
    text-align: center;
    vertical-align: top;
  }
  .date-picker.selected {
    font-weight: bold;
    color: #fff;
    background: gold;
  }
  .date-picker.selected span {
    border-bottom: 2px solid currentColor;
  }

  /* 日曜 */
  .date-picker:nth-child(1) {
  color: red;
  }
  /* 土曜 */
  .date-picker:nth-child(7) {
  color: blue;
  }
  #monthAndYear {
    text-align: center;
    margin-top: 0;
  }
  .button-container-calendar {
    position: relative;
    margin-bottom: 1em;
    overflow: hidden;
    clear: both;
  }
  #previous {
    float: left;
  }
  #next {
    float: right;
  }
  .footer-container-calendar {
    margin-top: 1em;
    border-top: 1px solid #dadada;
    padding: 10px 0;
  }
  .footer-container-calendar select {
    cursor: pointer;
    display: inline-block;
    zoom: 1;
    background: #ffffff;
    color: #454545;
    border: 1px solid #bfc5c5;
    border-radius: 3px;
    padding: 5px 1em;
  }

```

#成果物

![スクリーンショット 2020-11-09 23.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664818/e42107c9-5ec0-8735-f36b-2acb02acb9f7.png)

#感想

本当は、日付指定の部分で、日にちもいれて、検索できるようにしたかったです。
どうしても、プルダウンで日にちをいれても、検索日に色がでなかったです。
そもそもプルダウンで日にち検索することはナンセンスなのか・・。

絶対、次の実践プログラミングでは日付も検索して色を出せるようにしたいです（三度目の正直）。

しかし、参考記事の方のコードを読み解くだけで知らなかったり、深く知ろうとしなかったメゾットなどを調べることができて、勉強になりました！
時間はすごくかかっちゃったけど、楽しかったです。

誤ってる説明がございましたらご教授お願い致します🙇‍♂️。