Write a JavaScript function calendar ([day, month, year]) that returns a monthly calendar as HTML table (like in the examples below) by given day, month and year. Weeks start by “Sun” (Sunday) and end by “Sat” (Saturday).
The input comes as array of 3 numbers:
- day (1 ≤ day ≤ 31)
- month (1 ≤ month ≤ 12)
- year (1900 ≤ year ≤ 2100)
The output should be an HTML table, holding the calendar rows and columns, like in the examples below. Display the weeks as table rows: <tr>…</tr>. Display the days as table cells: <td>…</td>. Display the days of the previous month with CSS class “prev-month”, the days of the next month with CSS class “next-month” and the current day with CSS class “today”. See the examples below.
Examples:
Input 1:
24
12
2012
Output 1:
<table> <tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr> <tr><td class="prev-month">25</td><td class="prev-month">26</td><td class="prev-month">27</td><td class="prev-month">28</td><td class="prev-month">29</td><td class="prev-month">30</td><td>1</td></tr> <tr><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td></tr> <tr><td>9</td><td>10</td><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td></tr> <tr><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td></tr> <tr><td>23</td><td class="today">24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td></tr> <tr><td>30</td><td>31</td><td class="next-month">1</td><td class="next-month">2</td><td class="next-month">3</td><td class="next-month">4</td><td class="next-month">5</td></tr> </table>
Preview 1:
Input 2:
4
9
2016
Output 2:
<table> <tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr> <tr><td class="prev-month">28</td><td class="prev-month">29</td><td class="prev-month">30</td><td class="prev-month">31</td><td>1</td><td>2</td><td>3</td></tr> <tr><td class="today">4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr> <tr><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td></tr> <tr><td>18</td><td>19</td><td>20</td><td>21</td><td>22</td><td>23</td><td>24</td></tr> <tr><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td><td class="next-month">1</td></tr> </table>
Preview 2:
HTML Skeleton:
To simplify your work, use the below HTML code and write the missing code in the calendar() function:
<!DOCTYPE html> <html> <head> <title>Monthly Calendar</title> <style> .prev-month, .next-month { color: #CCC } .today { font-weight: bold; background: #DDD; } .title { background: #AAAAFF; margin: 10px 0; padding:5px } table { border: 1px solid #CCC;} td { text-align: center; } #calendarCode { width: 100%; } </style> <script> function calendar([day, month, year]) { // TODO: return the HTML text holding the calendar table } </script> </head> <body> Day: <input id="day" type="number" value="4" /> Month: <input id="month" type="number" value="9" /> Year: <input id="year" type="number" value="2016" /> <input type="button" value="Show" onclick="let calendarHTML = calendar([document.getElementById('day').value, document.getElementById('month').value, document.getElementById('year').value]); document.getElementById('calendar').innerHTML = calendarHTML; document.getElementById('calendarCode').innerText = calendarHTML" /> <div class="title">Calendar:</div> <div id="calendar">Calendar will be shown here</div> <div class="title">HTML:</div> <textarea rows="12" id="calendarCode"></textarea> </body> </html>
Screenshot:
This is how your calendar should look in Web browser, when the calendar() function is implemented correctly:
Here are some hints how to create the monthly calendar with JavaScript and HTML:
- Play with the class Date in JavaScript and make some calculations.
- Print the calendar table headings + days.
- Print the days from the previous month (if any):
- Find the day of week for the first day of the input date.
- If it is not Sunday, days from the previous month exist.
- Go back a few days in the previous month to find the closest Sunday (first week day).
- Start from it and print the days until the end of the previous month.
- Print the days from the current month.
- Print the days, one after another.
- Create a new table row after the last week day (Saturday).
- Print the days from the next month (if any).
- Stop when you reach Saturday (the last week day).
Here is the HTML code first:
<!DOCTYPE html> <html> <head> <title>Monthly Calendar</title> <style> .prev-month, .next-month { color: #CCC } .today { font-weight: bold; background: #DDD; } .title { background: #AAAAFF; margin: 10px 0; padding: 5px } table { border: 1px solid #CCC; } td { text-align: center; } #calendarCode { width: 100%; } </style> </head> <body> Day: <input id="day" type="number" value="4"/> Month: <input id="month" type="number" value="9"/> Year: <input id="year" type="number" value="2016"/> <input type="button" value="Show" onclick="let calendarHTML = calendar([document.getElementById('day').value, document.getElementById('month').value, document.getElementById('year').value]); document.getElementById('calendar').innerHTML = calendarHTML; document.getElementById('calendarCode').innerText = calendarHTML"/> <div class="title">Calendar:</div> <div id="calendar">Calendar will be shown here</div> <div class="title">HTML:</div> <textarea rows="12" id="calendarCode"></textarea> <script src="yourjscode.js"></script> </body> </html>
The JavaScript code (the solution):
function calendar(arr) { let [day,month,year]=arr.map(Number); let html = "<table>\n"; html += " <tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr>\n"; let currentDate = new Date(year, month - 1, 1); let lastDayOfPreviousMonth = new Date(year, month - 1, 0).getDate(); if (currentDate.getDay() !== 0) { currentDate = new Date(year, month - 2, lastDayOfPreviousMonth - currentDate.getDay() + 1); } let previousMonth = new Date(year, month - 2, 1).getMonth(); let nextMonth = new Date(year, month, 1).getMonth(); while (currentDate.getMonth() !== nextMonth || currentDate.getDay() !== 0) { if (currentDate.getDay() === 0) { html += " <tr>"; } if (currentDate.getMonth() === previousMonth) { html += `<td class="prev-month">${currentDate.getDate()}</td>`; } else if (currentDate.getMonth() === nextMonth) { html += `<td class="next-month">${currentDate.getDate()}</td>`; } else if (currentDate.getDate() === day) { html += `<td class="today">${currentDate.getDate()}</td>`; } else { html += `<td>${currentDate.getDate()}</td>`; } if (currentDate.getDay() === 6) { html += "</tr>\n"; } currentDate.setDate(currentDate.getDate() + 1); } html += "</table>"; return html; } console.log(calendar([24, 12, 2012]));