reptile7's JavaScript blog
Sunday, April 19, 2015
 
Further Adventures in Calendarland
Blog Entry #349

Next up in the Java Goodies Calendars, Clocks, and Calculators sector is a "Today Calendar" script that creates a calendar for the current month or another month of your choosing. The Today Calendar script was authored by David DeLong in 1998.

Unlike the Calendar and Datebook script we've been discussing over the last several entries, the Today Calendar script
(a) is an interactive script that provides controls for changing the calendar month and year and
(b) cleanly separates its HTML and JavaScript.
The script's JavaScript includes no fewer than 11 functions - that should keep us off the streets for a little while, yes?

The script gets the calendar year via the getYear( ) method and duly corrects therefor by adding 1900 to the getYear( ) return. However, for IE 4-8 the getYear( ) and getFullYear( ) returns are equal for years outside the 1900-1999 range and consequently at press time the script creates an April 3915 calendar for those browsers.

Joe provides a functioning script demo at the aforelinked todaycal.html page. The script itself may be accessed here.

Structural overview

The script calendar is laid out via a

<table border="0" cellpadding="0" cellspacing="0"> ... </table>

table that I'll call the table1 table. The table1 table itself sits in a

<table border="1" bgcolor="#000000" cellpadding="1" cellspacing="1"><tr><td align="center"> ... </td></tr></table>

table, which I'll call the table0 table; the table0 table effectively adds a 4px border to the table1 table but otherwise serves no purpose and can be thrown out. The table0 and table1 tables are horizontally centered on the page via a <center> element.

The table1 table contains 9 rows: the first, second, and ninth rows each contain 3 cells whereas the intervening rows each contain 7 cells. The table is commingled with a <form name="calform"> ... </form> form that contains 44 <input> controls, specifically 40 text inputs and 4 push buttons.
• The calform <form> is the only element in the code with an identifier; however, the Strict and Transitional DTDs both say that the name attribute is required for all <input> types except submit buttons and reset buttons.
• The calform form is placed just inside the table1 table in violation of the table element's (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+) content model.

The chrome

The table's first and second rows contain small text inputs

<th cellpadding="0" cellspacing="0" bgcolor="#aaaaaa" colspan="5" align="center"><input size="4" type="text" value="1993"></th>
...
<th bgcolor="#aaaaaa" colspan="5" align="center"><input size="9" type="text" value=" January "></th>
<!-- AFAIK, the #aaaaaa color doesn't have a name. -->


to which we will write the calendar year and month, respectively. The year and month inputs are placed in <th> cells although I would put them in <td> cells as they display heading data vis-à-vis actual headers. FYI: The cellpadding and cellspacing attributes are only valid for the table element.


The year input is flanked by a button that when clicked loads the month-input month for the previous year into the calendar and a button that when clicked loads the month-input month for the following year into the calendar; for example, if the current month were January 1993, then the button would take the user to a January 1992 calendar and the button would take the user to a January 1994 calendar. Similarly, the month input is flanked by and buttons that when clicked respectively load the previous and following months for the year-input year into the calendar.

The viewport

The third row holds a S, M, T, W, T, F, S set of headers.

<tr>
<th bgcolor="#ffcccc">S</td>
<th bgcolor="#ccccff">M</td>
<th bgcolor="#ccccff">T</td>
...
<th bgcolor="#ccccff">S</td>
</tr>
<!-- The #ffcccc and #ccccff colors don't have names either. -->


In the source the above cells have a <th>/</td> tag mismatch but on the page the headers are bolded as you would expect for <th> cells.

SMTWTFS

All of the cells in the fourth, fifth, sixth, seventh, and eighth rows and the first two cells in the ninth row hold very small text inputs

<tr>
<td bgcolor="#ffcccc"><input type="text" size="2"></td>
<td bgcolor="#ccccff"><input type="text" size="2"></td>
<td bgcolor="#ccccff"><input type="text" size="2"></td>
...


to which we'll write the calendar's date numbers as appropriate, e.g.:


We obviously can't put memos in these things, but with 37 of 'em on hand we at least won't have any 'overflowing month' problems.

Depending on what browser you're using, you may or may not see any bgcolor below the header row because the table cellpadding is set to 0.

Finally, the third cell in the ninth row holds a standard-sized text input

<td bgcolor="#aaaaaa" colspan="5"><input type="text"></td>

to which we'll write a Today: Apr 17, 2015-type string.

Style note:
We can much more conveniently apply the #ffcccc and #ccccff background colors to the calendar columns via the HTML col element.

#sunday { background-color: #ffcccc; }
#notsunday { background-color: #ccccff; }

<!-- With Safari, it is necessary to put the col elements right after the <table> start-tag; other browsers are less picky. -->
<table id="table1" cellpadding="" cellspacing="">
<col id="sunday"><col id="notsunday" span="6">
...
<!-- Third row: -->
<tr>
<th>S</th>
<th>M</th>
...


JavaScript intro

The todaycal.html JavaScript first defines a Months array of month names.

<!-- In the document head: -->
<script language="JavaScript"><!--
Months = new Array(12);
Months[0] = "January";
Months[1] = "February";
...
Months[11] = "December";

/* The rest of this script comprises the 11 functions mentioned in the post intro. */
// --></script>


It then creates a myDate Date object for today's date and gets myDate's month index.

<!-- In the document body, after the centering <center> element: -->
<script language="JavaScript"><!--
myDate = new Date( );
var Month = parseInt(myDate.getMonth( ));
/* Do we need to parseInt( ) the month index? Nope, the getMonth( ) return has a number type. */


Subsequently, the current year is written to the size="4" input in the first row.

document.calform.elements[1].value = 1900 + myDate.getYear( );
/* Of course, this statement should be:
document.calform.elements[1].value = myDate.getFullYear( ); */


Next, the name of the current month (Months[Month]) is loaded into the size="9" input in the second row; 0-3 space characters are prepended to the name by a PadSpaces( ) function in order to (approximately) horizontally center the name in the input - January and February and October and November and December are indented by a space, March and April and August are indented by two spaces, May and June and July get three spaces, September doesn't get any spaces at all.

function PadSpaces(TheString) { var Spaces = " "; // That's 13 spaces, folks. len = Math.round((9 - TheString.length) / 2); return Spaces.substring(0, len) + TheString; }

document.calform.elements[4].value = PadSpaces(Months[Month]);

The PadSpaces( ) function is today not necessary as modern browsers will apply a text-align:center; styling to an input value (with IE 4.5 and Communicator 4.61 on my computer, text-align:center; has no effect on the elements[4].value, i.e., the value is left-justified).

After that, a "Today: " string, the first three letters of Months[Month], a space, the myDate date number, a ", " string, and the current year are concatenated and the resulting string is written to the third input in the ninth row.

document.calform.elements[43].value = "Today: " + Months[Month].substring(0, 3) + " " + myDate.getDate( ) + ", " + (1900 + myDate.getYear( ));

Our next task is to load date numbers into the remaining inputs via the script's FillCalendar( ) function, which we'll take on in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)