Domino Code Fragment

Code Name*
JavaScript pop-up calendar
Date*
04/06/2000
Source (or email address if you prefer)*
esuez@mail.utexas.edu, jake.ochs@binarytree.com
IP address:.
Description*
Allows user to select a date from a calendar, change months, years.
Type*
JavaScript
Categories*
Date/Time Handling, User Interface (Web)
Implementation:
None (plug and play)
Required Client:
Server:
Limitations:
Comments:
Files/Graphics attachments (if applicable): Code:

In place of DateFieldName in the <INPUT...> tag below, use the name of your Domino or HTML field that will contain the date. Then place the following code where you want the Calendar button to show up (usually next to the field).
<INPUT TYPE=BUTTON NAME=putcalbutton VALUE="Calendar..." onclick="getMonth_and_Date(document.forms[0],'DateFieldName');putcal(document.forms[0],'DateFieldName')">

Make sure this code below is anywhere on your HTML page, before the <INPUT> code above.


//globals

var month; var day; var year;
var delim = new Array(":","/","\\","-"," ",".");
var monthArray = new Array(0,31,29,31,30,31,30,31,31,30,31,30,31);


function vd(frm, fieldName,fieldLabel) {
//init
dtString = eval("frm." + fieldName + ".value");

// trim date string
while ((dtString.charAt(0) == " ") && (dtString.length != 0))
dtString = dtString.substring(1,dtString.length - 1)
while ((dtString.charAt(dtString.length - 1) == " ") && (dtString.length != 0))
dtString = dtString.substring(0,dtString.length - 1)
//get date components
i = 0; startPos = 0; pos = 0;
//get month
do {
pos = dtString.indexOf(delim[i], startPos);
i++
}
while ((pos == -1) && (i < delim.length));
if (pos == -1) return false;
month = parseInt(dtString.substring(startPos,pos),10);
startPos = pos + 1;
if ((month < 1) || (month > 12)) return false;
//get day
i = 0;
do {
pos = dtString.indexOf(delim[i], startPos);
i++
}
while ((pos == -1) && (i < delim.length));
if (pos == -1)return false;
day = parseInt(dtString.substring(startPos,pos),10);
startPos = pos + 1;
if ((day < 1) || (day > monthArray[month])) return false;
//get year
year = parseInt(dtString.substring(startPos,dtString.length),10);

//check for leap year
if ((month == 2) && (day == 29))
if ((((year % 4) == 0) && ((year % 100) != 0)) == false){
return false;
}
//if we've gotten this far, return true
return true;
} // end function vd


function validateDate(form, dateFieldName,fieldLabel){
if (!vd(frm,fieldName,fieldLabel))
alert(fieldLabel + " does not have a valid date")
}//end function validateDate


function getToday(){
today = new Date();
day = today.getDate();
month = today.getMonth();
month++;
year = today.getYear();
year = (year < 100) ? 1900 + year : year;
}


function getMonth_and_Date(form,fieldName){
dtString = eval("form." + fieldName + ".value");
// trim date string
while ((dtString.charAt(0) == " ") && (dtString.length != 0))
dtString = dtString.substring(1,dtString.length - 1)
while ((dtString.charAt(dtString.length - 1) == " ") && (dtString.length != 0))
dtString = dtString.substring(0,dtString.length - 1)
//get date components
i = 0; startPos = 0; pos = 0;
//get month
do {
pos = dtString.indexOf(delim[i], startPos);
i++
}
while ((pos == -1) && (i < delim.length));
if (pos == -1){//there's no month
getToday();
return;
}
month = parseInt(dtString.substring(startPos,pos),10) - 1;
startPos = pos + 1;
if ((month < 0) || (month > 12)){ //no valid month
getToday();
return;
}
else
month++;
//get day
i = 0;
do {
pos = dtString.indexOf(delim[i], startPos);
i++
}
while ((pos == -1) && (i < delim.length));
if (pos == -1){
getToday();
return;
}
day = parseInt(dtString.substring(startPos,pos),10);
startPos = pos + 1;

if ((day < 1) || (day > monthArray[month])){
getToday();
return;
}
//get year
year = parseInt(dtString.substring(startPos,dtString.length),10)
year = (year < 100) ? 1900 + year : year;
}//getMonth_and_Date


function putDate(form,fieldName,value){
eval("form." + fieldName + ".value=" + value)
}


function gm(num) {
var mydate = new Date();
mydate.setDate(1);
mydate.setMonth(num-1);
var datestr = "" + mydate;
return datestr.substring(4,7);
}


function gy(num) {
var mydate = new Date();
return (1900 + eval(mydate.getYear()) - 4 + num);
}


function ud(mon) {
var i = mon.selectedIndex;


if(mon.options[i].value == "2") {
document.myform.day.options[30] = null;
document.myform.day.options[29] = null;
var j = document.myform.year.selectedIndex;
var year = eval(document.myform.year.options[j].value);
if ( ((year%400)==0) || (((year%100)!=0) && ((year%4)==0)) ) {
if (document.myform.day.options[28] == null) {
document.myform.day.options[28] = new Option("29");
document.myform.day.options[28].value = "29";
}
} else {
document.myform.day.options[28] = null;
}
}


if(mon.options[i].value == "1" ||
mon.options[i].value == "3" ||
mon.options[i].value == "5" ||
mon.options[i].value == "7" ||
mon.options[i].value == "8" ||
mon.options[i].value == "10" ||
mon.options[i].value == "12")
{
if (document.myform.day.options[28] == null) {
document.myform.day.options[28] = new Option("29");
document.myform.day.options[28].value = "29";
}
if (document.myform.day.options[29] == null) {
document.myform.day.options[29] = new Option("30");
document.myform.day.options[29].value = "30";
}
if (document.myform.day.options[30] == null) {
document.myform.day.options[30] = new Option("31");
document.myform.day.options[30].value = "31";
}
}


if(mon.options[i].value == "4" ||
mon.options[i].value == "6" ||
mon.options[i].value == "9" ||
mon.options[i].value == "11")
{
if (document.myform.day.options[28] == null) {
document.myform.day.options[28] = new Option("29");
document.myform.day.options[28].value = "29";
}
if (document.myform.day.options[29] == null) {
document.myform.day.options[29] = new Option("30");
document.myform.day.options[29].value = "30";
}
document.myform.day.options[30] = null;
}


if (document.myform.day.selectedIndex == -1)
document.myform.day.selectedIndex = 0;
}



function showdate() {
var i = document.myform.month.selectedIndex;
var j = document.myform.day.selectedIndex;
var k = document.myform.year.selectedIndex;
alert(document.myform.month.options[i].value + "/" +
document.myform.day.options[j].value + "/" +
document.myform.year.options[k].value)
}



function putcal(form, dateFieldName) {
var version = navigator.appVersion;
if (navigator.appVersion.indexOf("Mac") != -1) {
calwin = open("","calwin","width=300,height=300,resizable=yes");
} else {
calwin = open("","calwin","width=230,height=280,resizable=yes");
}


calccal(calwin,form,dateFieldName);
}


function calccal(targetwin,form,dateFieldName) {
var monthname = new Array(12);
monthname[0] = "January";
monthname[1] = "February";
monthname[2] = "March";
monthname[3] = "April";
monthname[4] = "May";
monthname[5] = "June";
monthname[6] = "July";
monthname[7] = "August";
monthname[8] = "September";
monthname[9] = "October";
monthname[10] = "November";
monthname[11] = "December";


var endday = calclastday(eval(month),eval(year));

mystr = month + "/01/" + year;
mydate = new Date(mystr);
firstday = mydate.getDay();


var cnt = 0;

var day = new Array(6);
for (var i=0; i<6; i++)
day[i] = new Array(7);


for (var r=0; r<6; r++)
{
for (var c=0; c<7; c++)
{
if ((cnt==0) && (c!=firstday))
continue;
cnt++;
day[r][c] = cnt;
if (cnt==endday)
break;
}
if (cnt==endday)
break;
}
targetwin.document.open()
targetwin.document.writeln("<FORM><TABLE><TR VALIGN=TOP>");


var prevyear = eval(year) - 1;
targetwin.document.writeln("<TD><INPUT TYPE=BUTTON NAME=prevyearbutton VALUE='<<'"+
" onclick='opener.month = " + month + "; opener.year = " + prevyear + ";document.clear();opener.calccal(opener.calwin,opener.document." + form.name + ",\"" + dateFieldName + "\")'></TD>");


var prevmonth = (month == 1) ? 12 : month - 1;
var prevmonthyear = (month == 1) ? year - 1 : year;
targetwin.document.writeln("<TD><INPUT TYPE=BUTTON NAME=prevmonthbutton VALUE='&nbsp;<&nbsp;'"+
" onclick='opener.month = " + prevmonth + "; opener.year = " + prevmonthyear + ";document.clear();opener.calccal(opener.calwin,opener.document." + form.name + ",\"" + dateFieldName + "\")'></TD>");


targetwin.document.writeln("<TD COLSPAN=3 ALIGN=CENTER>");
var index = eval(month) - 1;
targetwin.document.writeln("<B>" + monthname[index] + " " + year + "</B></TD>");


var nextyear = eval(year) + 1;
var nextmonth = (month == 12) ? 1 : month + 1;
var nextmonthyear = (month == 12) ? year + 1 : year;
targetwin.document.writeln("<TD><INPUT TYPE=BUTTON NAME=nextmonthbutton VALUE='&nbsp;>&nbsp;'"+
" onclick='opener.month = " + nextmonth + "; opener.year = " + nextmonthyear + ";document.clear();opener.calccal(opener.calwin,opener.document." + form.name + ",\"" + dateFieldName + "\")'></TD>");


targetwin.document.writeln("<TD><INPUT TYPE=BUTTON NAME=nextyearbutton VALUE='>>'"+
" onclick='opener.month = " + month + "; opener.year = " + nextyear + ";document.clear();opener.calccal(opener.calwin,opener.document." + form.name + ",\"" + dateFieldName + "\")'></TD>");


targetwin.document.writeln("</TR><TR>");
targetwin.document.writeln("<TD>Su</TD>");
targetwin.document.writeln("<TD>Mo</TD>");
targetwin.document.writeln("<TD>Tu</TD>");
targetwin.document.writeln("<TD>We</TD>");
targetwin.document.writeln("<TD>Th</TD>");
targetwin.document.writeln("<TD>Fr</TD>");
targetwin.document.writeln("<TD>Sa</TD>");
targetwin.document.writeln("</TR>");


targetwin.document.writeln("<TR><TD COLSPAN=7><HR NOSHADE></TD></TR>");
targetwin.document.writeln("<TR><TD COLSPAN=7><TABLE WIDTH=\"100%\" BORDER=\"1\">");


var selectedmonth = eval(month) - 1;
var today = new Date();
var thisyear = today.getYear() + 1900;
var selectedyear = eval(year) - thisyear + 4;


var conditionalpadder = "";

for(r=0; r<6; r++)
{
targetwin.document.writeln("<TR>");
for(c=0; c<7; c++)
{
targetwin.document.writeln("<TD>");
if(day[r][c] != null) {
if (day[r][c] < 10)
conditionalpadder = "&nbsp;"
else
conditionalpadder = "";
targetwin.document.writeln("<a href=\"
javascript:window.close();" +
"opener.document." + form.name + "." + dateFieldName + ".value = '" + month + "/" + day[r][c] + "/" + year + "'" +
"\">" + conditionalpadder + day[r][c] + conditionalpadder + "</a>")
}
targetwin.document.writeln("</TD>");
}
targetwin.document.writeln("</TR>");
}
targetwin.document.writeln("</TABLE></TABLE></FORM>");
targetwin.document.close()
}


function calclastday(month,year) {
if ((month==2) && ((year%4)==0))
return 29;


if ((month==2) && ((year%4)!=0))
return 28;


if ((month==1) || (month == 3) || (month == 5) || (month == 7) ||
(month==8) || (month == 10) || (month ==12))
return 31;


return 30;
}


function calcnextmonth(month) {
if (month=="12")
return "1";
else
return (eval(month)+1);
}


function calcnextyear(month,year) {
if (month=="12")
return (eval(year)+1);
else
return (year);
}


function calcprevmonth(month) {
if (month=="1")
return "12";
else
return (eval(month)-1);
}


function calcprevyear(month,year) {
if (month=="1")
return (eval(year)-1);
else
return (year);
}


//-->



API
There are three main functions that you should be concerned with:


putccal(form,dateFieldName)
form is the form object where the current data field is located (ex: document.forms[0], document.myform.)
and dateFieldName is name of the date field to be manipulated.


getMonth_and_Date(form,dateFieldName)
form is the form object where the current data field is located (ex: document.forms[0], document.myform.)
and dateFieldName is name of the date field to be manipulated.
validateDate(form, dateFieldName,fieldLabel)
form is the form object where the current data field is located (ex: document.forms[0], document.myform.)
dateFieldName is name of the date field to be manipulated. fieldLabel is the text literal for the field name (ex: a field called createdDate may have a field label of "Created Date.") This function will evaluate the field and alert the user if the field specified does not contain a valid date value.

Instructions
The variables in the "//globals" section must be instantiated on the form in the header.
To instantiate a calendar pop-up for a given date field, create a button or hotspot next to the field annd call the getMonth_and_Date function followed by the putcal function in the button or link handler. You must call getMonth_and_Date first to set up the environment for the particular date field in question. This function sets global document variables for the day, month and year that the putcal function uses to compute the calendar to display.

Note: If the field denoted by dateFieldName is empty or cannot be evaluated into a valid date, then the calendar pop-up defaults to the current month and year.

Miscellaneous
This calendar is also being provided as a .js file that can be used in r4 browsers without cluttering up your html. Additionally, scripts loaded in this fashion will be cached by the browser, for increased download time.Please note that the gobal variables must still be instantiated in the main html page.


Jake Ochs
Binary Tree, Inc.



--------------------------------------------------------------------------------

Comments from original author (may no longer be valid:)
--------------------------------------------------------------------------------


Note: The core calendar rendering code was written by Mr. Suez and posted on the scriptbuilder.com website.

This utility has been tested to work on both Windows95 and Macintosh platforms. Since this is javascript, you can simply view the source from within your browser to see the code. Thanks for visiting.

Comments to E. Suez (core oce author)