To build a dynamic calendar there are a couple of challenges to address. All months vary in length which means no month starts on the same day, so before we can print out the days we need to find the offset for the month. by setting a new Date() to the first day of the month with .setDate(1) then using .getDay() the day of the week is returned in a numerical value e.g. Friday is returned as a 5, Sunday is 0.
With the offset we can insert blank <td> elements, or use the colspan table attribute to create the same blank space.
Now to loop over the days updating the setDate() with the current loop index, ending the <tr> when the date getDay() is equal to 6.
Now to calculate the offset at the end of the month we use the formula
7 - ((daysInMonth + firstDay) % 7)
By adding the offset from the start to the number of days in the month we get the position of the end date on the grid, but we need to get the number of empty <td> elements that will need to appear afterwards, by subtracting the remainder when dividing by <td> elements in each row we get how many empty space should appear at the end of the table. Because at some point the date will end exactly on the last grid element we break the loop if the offset is equal to 7
Below is code for the example and the output
Visit my Codepen collection to see some styled versions.
S | M | T | W | T | F | S |
---|
<table>
<thead>
<th>S</th>
<th>M</th>
<th>T</th>
<th>W</th>
<th>T</th>
<th>F</th>
<th>S</th>
</thead>
<tbody>
</tbody>
</table>
<script>
var calcDaysInMonth = function(month,year) {
return new Date(year, month, 0).getDate();
};
today=new Date();
thisDay= today.getDay();
thisDate= today.getDate();
thisMonth= today.getMonth();
thisYear= today.getFullYear();
today.setDate(1);
firstDay = today.getDay();
daysInMonth = calcDaysInMonth(thisMonth+1, thisYear);
monthOffset = 7 - ((daysInMonth + firstDay) % 7);
calendarTable = "<tr>";
if (firstDay !== 0){
for (i = 1; i <= firstDay; i++){
calendarTable += "<td></td>";
}
}
for (i = 1; i <= daysInMonth; i++) {
if(i <= daysInMonth){
calendarTable += "<td>"+i+"</td>";
calendarDate = new Date();
calendarDate.setDate(i);
if(calendarDate.getDay() == 6){
calendarTable += "</tr><tr>";
}
} else {
if(monthOffset == 7){
break
} else {
calendarTable +='<td colspan="'+monthOffset+'" class="blankDay"></td>';
break
}
}
}
document.getElementsByTagName("tbody")[0].innerHTML = calendarTable;
</script>