reptile7's JavaScript blog
Tuesday, April 07, 2015
 
Calendar and Datebook 2.0
Blog Entry #348

We are at present working through the if...else if...else construct that fills in the date cells of the display month for the calendar coded by the Java Goodies Calendar and Datebook script. We discussed the construct's if clause in the Leading up to today section of the previous post; here's the calendar we would have so far if today were 11 April 2015:

April 2015
SundayMondayTuesdayWednesdayThursdayFridaySaturday
123
Dentist Appointment
4
567
Take puppies to the vet
8910
12
Blah blah blah
19
Blah blah blah
26
Blah blah blah

Now, and look into the future

The construct's else if clause

else if (this.m_myDate.getDate( ) == this.m_now.getDate( ) && this.m_myDate.getMonth( ) == this.m_now.getMonth( )) document.writeln("<td valign=\"top\" width=\"14%\" bgcolor=\"#" + this.m_strNow + "\"><b>" + "<font face=\"" + this.font + "\" size=\"" + this.fontSize + "\">" + this.m_myDate.getDate( ) + "</b><br>" + this.getText(this.m_myDate.getDate( )) + "</font></td>");

handles the cell for the this.m_now date of the this.m_now month regardless of year; if today were 11 April 2015, it would apply to 11 April in 2014 or 2015 or 2016 or any other year. The else if cell is given a this.m_strNow (lightcoral) background color but is otherwise processed à la the this.m_strPast cells.

The construct's else clause

else document.writeln("<td valign=\"top\" width=\"14%\" bgcolor=\"#" + this.m_strFutr + "\"><b>" + "<font face=\"" + this.font + "\" size=\"" + this.fontSize + "\">" + this.m_myDate.getDate( ) + "</b><br>" + this.getText(this.m_myDate.getDate( )) + "</font></td>");

covers all other date cell possibilities, more specifically, it is operative for
(a) the this.m_now date and dates that follow the this.m_now date for months prior to the this.m_now month and
(b) dates that follow the this.m_now date for the this.m_now month and
(c) all dates for months that follow the this.m_now month
regardless of year; for example, it would apply to 11 March through 31 March, 12 April through 30 April, and 1 May through 31 May if today were 11 April. The else cells are given a this.m_strFutr (wheat) background color but are otherwise processed à la the this.m_strPast and this.m_strNow cells.

Curtain call

When the for (j = 0; j < 5; j++) { ... } loop has run its course and the calTable table is complete, the ampCalendar_Display( ) function writes out a closing credit:

document.writeln("</table>");
document.writeln("<font size=\"1\" face=\"Verdana, Arial, Helvetica\">" + "Calendar by " + "<a href=\"http://www.geocities.com/SiliconValley/Bay/8267/ampcal.html\">" + "ampCal</a>, Copyright ©, 1998, Andrew M. Pierce</font>"); }


Output:
Calendar by ampCal, Copyright ©, 1998, Andrew M. Pierce

• A size='1' font element attribute maps onto a font-size:x-small; style declaration.
• As was noted in Blog Entry #345, the http://www.geocities.com/SiliconValley/Bay/8267/ampcal.html resource is no longer available.
• The copyright notice contains a literal © character, which should be encoded as \u00A9.

Overflowing cases

The for (j = 0; j < 5; j++) { ... } loop accommodates most months but would cut off
(1) the last Sunday of a 31-day month that begins on a Friday (e.g., May 2015),
(2-3) the last Sunday and last Monday of a 31-day month that begins on a Saturday (e.g., August 2015), and
(4) the last Sunday of a 30-day month that begins on a Saturday (e.g., November 2014).
The easy way to code a 6th data row for these days is to bump up the loop's j endpoint to 6, but we can do better than that.

I thought back to what Joe Burns said about the differing applications of for and while loops in HTML Goodies' JavaScript Primers #24:
In general, you use for loops when you know how many times you want to perform a loop. Use while loops when you are not sure how many times you want to perform a loop.
So perhaps we should be using a while loop to determine the number of rows in the table. As regards the while condition, it occurred to me that the x = 0, 7, 14, ... cell counter could be repurposed as a date counter that
(i) tracks the this.m_myDate.getDate( ) return but
(ii) keeps incrementing (is not reset to 1) when this.m_myDate transitions from the display month to the following month and
(iii) green-lights the creation of a 6th data row if it is still equal to this.m_myDate.getDate( ) at the end of the 5th data row.

var x = this.m_myDate.getDate( ); while (x == this.m_myDate.getDate( )) { document.write("<tr>"); for (i = 0; i < 7; i++) { ... this.m_myDate.setDate(this.m_myDate.getDate( ) + 1); x++; ... } document.write("<\/tr>"); }

As for how this approach works in practice, you may test it yourself via the demo at the end of the post.

Cutting out the memo middlemen

If we give ordinalized cal1, cal2, cal3, ... ids to the display month's date cells, then we can directly append memos to the innerHTML of those cells without having to respectively store and retrieve them via the ampCalendar_setItem( ) and ampCalendar_getText( ) functions, e.g.:

if (this.m_myDate.getDate( ) < this.m_now.getDate( ) && this.m_myDate.getMonth( ) <= this.m_now.getMonth( )) document.write("<td class='preDates' id='cal" + this.m_myDate.getDate( ) + "'><span>" + this.m_myDate.getDate( ) + "<\/span><br><\/td>");

/* In the script1 script in the example.html document: */
ampCal.display( );
document.getElementById("cal3").innerHTML += "Dentist Appointment";
document.getElementById("cal7").innerHTML += "Take puppies to the vet";


Demo

The original Calendar and Datebook script isn't interactive in any way, so I thought it would be a good idea to craft a demo therefor that allows the user to create calendars for month <option>s of a <select> menu.



• Rather than 'outputting as we go' via a bunch of document.write( ) commands, the demo assembles the calTable table in one big calString string and then writes calString to the innerHTML of a calDiv div.

• The ampCal object has been 'put out to pasture' because a majority of its properties are either outsourceable to a style sheet (the cell background-colors, the font-size and font-family data) or superfluous (the days per month stuff, the memo storage stuff, the display method if we're going to put the whole shebang in one document) and also because doing so simplifies the code a bit; re the remaining properties, the month and <caption> data are built into the <select>/<option> menu, the year year is prechosen for the user, and the m_now and m_myDate dates are stored in freestanding variables.

Comments: Post a Comment

<< Home

Powered by Blogger

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