reptile7's JavaScript blog
Friday, February 16, 2018
A JavaScript 1.2 Calendar and Clock, Part 7
Blog Entry #389
In today's post, we will create a calendar for February 2018 with the remaining part of the js-calbot2.html*
<script>
.*If you're using a current version of Firefox, Google Chrome, or Opera, then you should be able to view the js-calbot2.html source here; however, you won't see anything at the js-calbot2.html page itself (other than its black background) as the calendar makes use of data generated in the js-caltop1.html document.
We coded and rendered a calendar caption and row of Sunday to Saturday day headers in the previous post: these features will sit atop a date section comprising a 4-to-6-row grid of cells à la a regular calendar. Two key pieces of information enable us to build the date section:
(1) the number of days in the calendar month, which is stored in an a variable;
(2) the getDay( ) index for the first day of the calendar month, which is stored in a d variable.
Our a value is 28 as 2018 is not a leap year; our d value is 4 as 1 February 2018 fell on a Thursday.
The pre-months display
The date section begins in the original calendar table's rows[2] row. The code below writes out four empty td cells for the Sunday to Wednesday days in January that precede 1 February 2018. The c variable serves as an index of sorts: it's 1 for the rows[2].cells[0] cell, 2 for the cell after that, etc.
var c = 0;
while (c < d) {
c++;
document.write("<td></td>"); }
• The rows[2] row's
<tr>
and </tr>
tags are both missing in the source: the latter is in fact optional but the former is required.• I'll show you how to place date numbers (28, 29, 30, 31) in these cells later.
February
After c reaches d (4) and the td for 31 January is written out, the script moves to a b variable to direct the formation of the February part of the date section.
var b = 0;
b = b + c;
Also a cell index of sorts, b picks up where c leaves off and steps us from 1 February 2018 (b = 5) to 28 February 2018 (b = 32).
var t = new Date( );
var week = t.getDay( ) + 1; /* No subsequent use is made of week. */
var day = t.getDate( );
var e = a + c; /* e marks the end of the months month. */
while (b < e) {
b++;
if (b == 8 || b == 15 || b == 22 || b == 29 || b == 36) { document.write("<tr>"); }
if ((b - c) == day) { color = "red"; }
else { color = "white"; }
document.write("<td><center><font color='" + color + "' face='Arial'><b>" + (b - c) + "</b></font></center></td>"); }
document.write("</tr></table>");
</script> /* That's it for the js-calbot2.html script. */
• The Saturday bs are multiples of 7; when
b++
takes b one above those values, the current row is ended and a new row is started.• The
b - c
difference gives the date number for each cell.• The date numbers are horizontally centered (td content aligns left by default), colored - today's date number, day, is red, all other date numbers are white - Arialized, and bolded.
The post-months display
When the
while (b < e) { ... }
loop has run its course, control passes to a document.write("</tr></table>");
command that closes the current row and the calendar table itself. The last day of February 2018 is a Wednesday, and no cells are written out for the last row's Thursday, Friday, and Saturday - there's just blank space there. Nonetheless, it is simple enough to code date cells for the first three days of March:.postmonths { color: #449977; font: bold medium Arial; text-align: center; }
while (b % 7) {
b++;
document.write("<td class='postmonths'>" + (b - e) + "<\/td>"); }
• This loop effectively continues the previous one, moving b beyond e to the next multiple of 7, 35 in this case.
• The caption's teal-ish #449977 color seems right for the March date numbers, don't you think?
Then came the last days of January
Now, what about the date numbers for the pre-months cells? To get those numbers, we'll need to know how many days the previous month had. Toward this end, we could go through the months → a if...else if...else cascade all over again, but working with a corresponding monthdaysArray would be a much more efficient way to go:
var monthNumber = t.getMonth( );
var monthdaysArray = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if ((! (yr % 4) && (yr % 100)) || ! (yr % 400)) monthdaysArray[1] = 29;
var days_in_previous_month = monthNumber ? monthdaysArray[monthNumber - 1] : 31;
With the days_in_previous_month number in hand, we can write( ) the cells + date numbers for the last four days of January with:
.premonths { color: #449977; font: bold medium Arial; text-align: center; }
while (c < d) {
c++;
document.write("<td class='premonths'>" + (days_in_previous_month - d + c) + "<\/td>"); }
Demo
It's time to put it all together via a demo, wouldn't you say?
(This post was written in February 2018; the calendar will update to whatever month it happens to be.)
• The demo is framed by an id="calendarDiv" div.
• Per the original design, the demo content and the styles applied to that content are written JavaScriptically without the aid of any non-script HTML/CSS.
• The document.write( ) operations have been replaced by corresponding document.createElement( )/Node.appendChild( ) operations. Excepting the table border setting, all styles are set via the Element.style.CSSProperty = "value" mechanism.
var calendarTable = document.createElement("table");
calendarTable.id = "calendarTableId";
calendarTable.border = "1";
calendarTable.style.marginLeft = "auto";
calendarTable.style.marginRight = "auto";
document.getElementById("calendarDiv").appendChild(calendarTable);
...
We're not quite done with the Multiple Java Calendar: we have yet to discuss the calendar's month and year controls in the center cell of the js-caltop1.html layout table, and we'll do that in the next post.
Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)