reptile7's JavaScript blog
Monday, March 05, 2018
 
A JavaScript 1.2 Calendar and Clock, Part 8
Blog Entry #390

We return now to the js-caltop1.html document and its isnform form, whose
(mm) selection list allows us to change the calendar month and
(yyyy) and buttons allow us to change the calendar year.

Changing the calendar month

var t = new Date( );
var v = t.getMonth( ) + 1;
function navigator(isnform) {
    var durl = (isnform.isnlist.options[isnform.isnlist.selectedIndex].value);
    document.line.month.value = durl; }
document.write("<form name='isnform'>");
document.write("<select name='isnlist' onchange='navigator(this.form);'>");
document.write("<option value='1'>January");
document.write("<option value='2'>February");
...
document.write("<option value='12'>December");
document.write("<\/select>");
document.isnform.isnlist.selectedIndex = v - 1;


The isnlist menu is initialized to the v - 1th option for the current month (March at present). Choosing a new month option calls a navigator( ) function that gets the new option's value and stores it in the line form's month field via the intermediacy of a durl variable. As detailed in Part 5 and Part 6 of this series, the document.line.month.value is used to determine
(i) the day of the week that the first day of the calendar month falls on and
(ii) how many days the calendar month has
upon setting the calendar code in motion, and is ultimately placed in the calendar caption.

Today we can directly pass this.value to the navigator( )changeMonth( ) function - recall that the pre-DOM client-side Select object didn't have a value property - subsequently, I would numberify* the newOptionValue and then assign it to v and, as v has a global scope, just work with v versus the month field in going forward.

function changeMonth(newOptionValue) { v = Number(newOptionValue); }

<select name='isnlist' onchange='changeMonth(this.value);'>


Other codings are of course possible but this is as simple and straightforward as any.

*Re the days_in_previous_month calculation in the previous post, a string newOptionValue leads to NaNs and not date numbers in December cells of January calendars.

Changing the calendar year

Sandwiched between the and buttons is a showyear text field whose value is initialized to '19' + t.getYear( ) so as to display the current year number.

var y = t.getYear( );
document.write("<input name='raise' type='button' value='<<' onclick='down( );'>");
document.write("<input name='showyear' type='text' value='19" + y + "' size='4'>");
document.write("<input name='raise' type='button' value='>>' onclick='up( );'>");
document.write("<\/form>");


Clicking the button calls an up( ) function that increases the showyear.value year number by one and then stores the incremented number in the line form's year field.

var th = 0;
var th2 = -1;
var qw = 0; /* No subsequent use is made of qw. */
var q = new Date( );
var newyr = q.getYear( );
function up( ) {
    th++;
    document.isnform.showyear.value = "19" + (newyr + th);
    if (document.isnform.showyear.value > 1999) {
        th2++;
        if (th2 < 10) { th2 = "0" + th2; }
        document.isnform.showyear.value = "20" + th2; }
    document.line.year.value = document.isnform.showyear.value; }


Again, the document.line.year.value is used to determine the day of the week that the first day of the calendar month falls on and is ultimately placed in the calendar caption.

Clicking the button calls a down( ) function that decreases the showyear.value year number by one and stores the decremented number in the year field: it replaces th++ with th-- and th2++ with th2-- but is otherwise identical to the up( ) function.

This code was adequate back in the day but even without access to the getFullYear( ) method there was room for improvement here. The up( ) and down( ) functions use "19", "0", and/or "20" strings and number-holding th and th2 variables to piece together a 4-digit year as a numeric string - not the most efficient way of doing things, is it? Instead, we could get a 4-digit year number and store it in the newyr variable and the showyear field from the get-go via:

var t = new Date( );
var newyr = t.getYear( );
if (0 <= newyr && newyr <= 99) newyr += 1900; /* No adjustment is necessary for years after 1999 or before 1900. */
document.isnform.showyear.value = newyr;


We can increment or decrement a 4-digit newyr in a merged up_or_down( ) function

function up_or_down(adjustYear) {
    adjustYear == "up" ? newyr++ : newyr--;
    document.isnform.showyear.value = newyr; }

<input name="lower" type="button" value="<<" onclick="up_or_down('down');"> ...
<input name="raise" type="button" value=">>" onclick="up_or_down('up');">


and then work with newyr versus the year field in going forward.

The if (0 <= newyr && newyr <= 99) newyr += 1900; getYear( ) adjustment for the years 1900-1999 is needed for JavaScript 1.0-1.2; a var newyr = 1900 + t.getYear( ); statement would correctly handle all years for later versions of JavaScript à la var newyr = t.getFullYear( );, which is what we should be using, needless to say.

A little reminder: You'll get Gregorian calendars and not Julian calendars if you take the year back to 1752 or earlier, e.g., February 1700 will have 28 days.

One more point before moving on:
The user can impart focus to the showyear field and change its value but the calendar code will not detect that change. It would be a good idea to give the field a readonly attribute; alternatively, we could convert the field to a newyr-holding <samp> or <span> although I think the former looks nicer on the page than does the latter.

No reset

Preceding the up( ) and down( ) functions in the js-caltop1.html source is a reseter( ) function

function reseter( ) {
    document.line.year.value = "19" + t.getYear( );
    document.isnform.showyear.value = "19" + t.getYear( ); }


that resets the year and showyear fields' values to "19" + t.getYear( ) when the user unloads (exits) the js-caltop1.html document.

<body onload="date( );" bgcolor="black" onunload="reseter( );" text="white">

The reseter( ) function serves no useful purpose, and may be safely discarded.

Demo

Not mentioned previously:
Pagetools.de has posted a Multiple Java Calendar demo here: its date string and calendar parts are marred by getYear( ) vs. getFullYear( ) calls but at least the clock part is OK.

We conclude our Multiple Java Calendar odyssey with our own demo - check the page source for the full coding.

This Is A Simple Calendar That You Can Change To Any Month Or Year You Want.

Demo notes

(1) The left, center, and right cells of the js-caltop1.html layout table are now clock_and_date_string, month_and_year_controls, and calendar_trigger divs, respectively. A display:inline-block; styling places the divs in the same line box; a vertical-align:top; styling aligns their top edges; their heights are harmonized with:

document.getElementById("calendar_trigger").style.height =
document.getElementById("month_and_year_controls").style.height =
document.getElementById("clock_and_date_string").clientHeight + "px";


(2) On updating a calendar, the to-be-changed calendar's date rows are removed with:

var calendarTable2 = document.getElementById("calendarTableId2");
for (var i = calendarTable2.rows.length - 1; 0 < i; i--) {
    calendarTable2.removeChild(calendarTable2.rows[i]) };


It's necessary to start at the last row and go upward in doing this; a top-down approach removes only every other row.

(3) The current day's date number is reddened for only the current month

datecolor2 = b2 - c2 == dates2 && t2.getMonth( ) == today2.getMonth( ) && t2.getFullYear( ) == today2.getFullYear( ) ? "red" : "black";

whereas the original code reddened it for all months.
I'll be working at my (seriously neglected) other blog for a while.


Powered by Blogger

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