Another JS Date Picker
Posted: Wed Apr 04, 2007 5:06 pm
I hadn't written any JS in eons so last week I decided to whip up a JS calendar / date picker. It took a bit to brush off the JS rust but I got something that worked well and was kinda cool. The original version used a LOT of innerHTML to 'paint' the calendar on the screen. I had Tester Extraordinaire helping me test it and he suggested building the whole thing with the DOM instead of using innerHTML and also suggested that I pull the styles out of the JS and put them into CSS...well thanks to pickle for his wisdom, I decided to tackle both of those feats toward the end of last week and into this one. I also decided to rewrite the whole thing using JSON so I could learning something in the process. I know there are a million and four JS calendar / date pickers out there and this one isn't much different but here it is for your date picking enjoyment.
http://www.burritostand.com/jsonCal.htm
This link has a language selector and a format text field that would not be used in the real deal...the real deal would need to have both of those items statically inserted into the JS file or HTML page in <script> tags (above the call to the JS file)...but the sample above is for demonstration purposes only.
if anyone wants to help me out by adding additional language support, that'd make me happy
I have only tested this with IE and firefox so don't count on it working in any other browsers.
I'm also going to re-add the ability to change the styles within JS constants but that will be version 2.
Lastly, I'm going to change the CSS class names to be something more obscure so they don't conflict with any other classes you might have defined, but frankly, I'm too lazy to do that right this moment.
Usage: look at the HTML file sample below. You need to set the id of whatever element it is that you're calling the calendar with to 'cal-%textfield%' where %textfield% is the id of the text field the date should be inserted into. Example: If my textfield has an id of 'birthday' I would need to set the id of the calling element to 'cal-birthday'. See below for a real example:
http://www.burritostand.com/jsonCal.htm
This link has a language selector and a format text field that would not be used in the real deal...the real deal would need to have both of those items statically inserted into the JS file or HTML page in <script> tags (above the call to the JS file)...but the sample above is for demonstration purposes only.
if anyone wants to help me out by adding additional language support, that'd make me happy
I have only tested this with IE and firefox so don't count on it working in any other browsers.
I'm also going to re-add the ability to change the styles within JS constants but that will be version 2.
Lastly, I'm going to change the CSS class names to be something more obscure so they don't conflict with any other classes you might have defined, but frankly, I'm too lazy to do that right this moment.
Usage: look at the HTML file sample below. You need to set the id of whatever element it is that you're calling the calendar with to 'cal-%textfield%' where %textfield% is the id of the text field the date should be inserted into. Example: If my textfield has an id of 'birthday' I would need to set the id of the calling element to 'cal-birthday'. See below for a real example:
Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Calendar Sample</title>
<script>
calendarLanguage = "spanish";
calendarDateFormat = "%mmmm% %dd%, %yyyy%";
</script>
<script src="cal.js"></script>
<link rel="stylesheet" href="cal.css">
</head>
<body>
<input type="text" name="begindate" id="begindate" size="40">
<img src="calendar.gif" onClick="loadCal(this)" id="cal-begindate"><br>
</body>
</html>Code: Select all
.dateSelects {
background-color:#a09e94;
font-size:10px;
font-family:tahoma;
border:1px #000000 solid;
font-weight:normal;
}
.calTable {
width:225px;
border-top:1px #000000 solid;
border-left:1px #000000 solid;
margin:0px;
padding:0px;
border-spacing:0px;
border-collapse:collapse;
}
.calTd {
width:14%;
background-color:#eae6dd;
height:16px;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.outMonthCalTd {
width:14%;
background-color:#eae6dd;
color:#abaaa6;
height:16px;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.weekendCalTd {
background-color:#bfbdb2;
width:14%;
height:16px;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.weekendOutMonthCalTd {
background-color:#bfbdb2;
color:#abaaa6;
width:14%;
height:16px;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.headCellTd {
background-color:#958f6d;
height:16px;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.headLeftTd {
border-right:0px;
background-color:#958f6d;
height:16px;
text-align: center;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.headMainTd {
border-right:0px;
border-left:0px;
background-color:#958f6d;
height:16px;
text-align: center;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.headCenterTd {
border-right:0px;
border-left:0px;
font-weight:bold;
background-color:#958f6d;
height:16px;
text-align: center;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.headRightTd {
border-left:0px;
background-color:#958f6d;
height:16px;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.topHeadCellTd {
text-align:right;
border-bottom:0px;
font-weight:bold;
background-color:#958f6d;
height:16px;
border-right:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.selectHeadTd {
text-align:left;
border:0px;
font-weight:bold;
background-color:#958f6d;
height:16px;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.mouseOverTd {
background-color:#7e7c6e;
}
.daysOfWeekTd {
background-color:#efead2;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.currentDay {
background-color:#b5e8c8;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}
.selectedDay {
background-color:#87c7df;
cursor:hand;
cursor:pointer;
text-align: center;
border-right:1px #000000 solid;
border-bottom:1px #000000 solid;
margin:0px;
padding:0px;
font-family:tahoma;
font-size:9px;
}Code: Select all
// JSON Calendar By Burrito 04/02/2007 - Released under GPL License
// feel free to use and distribute this as much as you
// want. All I ask is that you maintain this comment
// block to give me credit for enjoying cheesecake.
// mmmmmm....cheesecake
// create the div to house the calendar
document.write("<div id=\"____myCalendar\" style=\"display:none;position:absolute;top:0px;left:0px;filter:alpha(opacity=30);-moz-opacity:0.3;\"></div>");
//loadCal function is called from an element on the page to load the calendar
function loadCal()
{
if(document.getElementById('____calendar'))
{
calTable = document.getElementById('____calendar');
calTable.parentNode.removeChild(calTable);
}
calendar.calCaller = arguments[0];
todaysDate = new Date();
calendar.month = (arguments[1] != null ? arguments[1] : todaysDate.getMonth());
calendar.year = (arguments[2] != null ? arguments[2] : todaysDate.getFullYear());
calendar.init();
calendar.dateFormat = calendarDateFormat;
calendar.language = calendarLanguage;
calendar.set();
calendar.displayCalendar();
}
//objDisplayMonth object creates the date object to be used for the month/year being displayed also creates todays date information
var objDisplayMonth = {
// initialize the members
date : Object,
element : Object,
currentDate : null,
currentMonth : null,
currentYear : null,
// init to create the date object for the month / year displayed
init : function() {
this.date = new Date();
this.currentDate = this.date.getDate();
this.currentMonth = this.date.getMonth();
this.currentYear = this.date.getFullYear();
},
// setDisplayMonth method sets month and year passed to it
setDisplayMonth : function() {
// set date to first day of month so when changing months, the calendar doesn't get screwed up if on a day over the previous months end date and to get padding for first of month
this.date.setDate(1);
this.date.setMonth(arguments[0]);
this.date.setFullYear(arguments[1]);
return this.getDisplayMonth()
},
// getDisplayMonth method returns the date
getDisplayMonth : function() {
return this.date;
}
};
// dateInfo object used to format the date properly and to show months and days of week on the calendar
// TODO: add other language support
var dateInfo = {
english : {
monthLongNames : ["January","February","March","April","May","June","July","August","September","October","November","December"],
monthShortNames : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
daysShortNames : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
daysLongNames : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
},
spanish : {
monthLongNames : ["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],
monthShortNames : ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],
daysShortNames : ["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"],
daysLongNames : ["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"]
},
french : {
monthLongNames : ["Janvier","Février","Mars","Avril","Mai","Juin","Julliet","Août","Septembre","Octobre","Novembre","Décembre"],
monthShortNames : ["Jan","Fév","Mar","Avr","Mai","Jui","Jul","Aoû","Sep","Oct","Nov","Déc"],
daysShortNames : ["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],
daysLongNames : ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
},
monthLeadZero : ["01","02","03","04","05","06","07","08","09","10","11","12"]
};
// calendar object used for the set up of the calendar, to place the calendar on the page, and to add the date to the text field.
var calendar = {
// initialize the members
month : null,
selectYearRange : "1990-2020",
year : null,
dateFormat : "",
fadeIn : true,
language : "",
calCaller : Object,
callerField : Object,
objMonthYear : Object,
selectedDate : null,
selectedDay : null,
selectedMonth : null,
selectedYear : null,
calendarDisplayed : false,
daysInCurrentMonth : null,
isIE : false,
init : function() {
this.callerField = document.getElementById(this.calCaller.id.substring(4,this.calCaller.id.length));
if(!this.calendarDisplayed && this.callerField.value != "")
this.preSelectDate();
this.objMonthYear = objDisplayMonth;
this.objMonthYear.init();
this.isIE = (navigator.appVersion.toLowerCase().indexOf("msie") > -1 ? true : false);
if(this.isIE)
this.showHideSelects(true);
this.getPlacement();
},
// showHideSelects method toggles the visibility property of selects for Internet Explorer
showHideSelects : function() {
selArr = document.getElementsByTagName("select");
for(i=0;i<selArr.length;i++)
{
if(selArr[i].id != "____monthSelect" && selArr[i].id != "____yearSelect")
selArr[i].style.visibility = (arguments[0] ? 'hidden' : 'visible');
}
},
// preSelectDate method selects the date (if possible) that is in the text box on the calendar
preSelectDate : function() {
this.selectedDate = new Date(this.callerField.value);
if(this.selectedDate.getDate())
{
this.selectedDay = this.selectedDate.getDate();
this.selectedMonth = this.selectedDate.getMonth();
this.selectedYear = this.selectedDate.getFullYear();
this.month = this.selectedDate.getMonth();
this.year = this.selectedDate.getFullYear();
//alert(this.month+" "+this.year);
}
else
this.selectedDate = null;
},
set : function() {
this.objMonthYear.setDisplayMonth(this.month,this.year);
// daysInCurrentMonth property is the number of days in the current month
this.daysInCurrentMonth = this.getDaysInMonth(this.objMonthYear.getDisplayMonth().getMonth(),this.objMonthYear.getDisplayMonth().getFullYear());
},
// close method closes the calendar when the 'X' is clicked
close : function() {
calendar.calendarDisplayed = false;
document.getElementById('____myCalendar').style.display = "none";
calendar.showHideSelects(false);
},
//getPlacement method determines where to display the div for the calendar then displays it
getPlacement : function () {
theCalDiv = document.getElementById('____myCalendar').style;
calCallerObjLeft = this.calCaller;
calCallerObjTop = this.calCaller;
var left = 0;
//alert(this.calCaller.id);
while (calCallerObjLeft)
{
left += calCallerObjLeft.offsetLeft;
calCallerObjLeft = calCallerObjLeft.offsetParent;
}
var top = 0;
while (calCallerObjTop)
{
top += calCallerObjTop.offsetTop;
calCallerObjTop = calCallerObjTop.offsetParent;
}
//alert(this.calCaller.id);
//alert(top);
theCalDiv.left = left+"px";
theCalDiv.top = top+"px";
if(this.fadeIn && !this.calendarDisplayed)
{
this.calendarDisplayed = true;
cDiv = document.getElementById('____myCalendar');
if(cDiv.filters)
cDiv.filters.alpha.opacity = 30;
else
cDiv.style.MozOpacity = 0.3;
this.fadeCalendarIn();
}
else
{
this.calendarDisplayed = true;
cDiv = document.getElementById('____myCalendar');
if(cDiv.filters)
cDiv.filters.alpha.opacity = 100;
else
cDiv.style.MozOpacity = 1.0;
this.fadeCalendarIn();
theCalDiv.display = "block";
}
},
// fadeCalendarIn method fades the calendar to 100% opacity
fadeCalendarIn : function() {
cDiv = document.getElementById('____myCalendar');
cDiv.style.display = "block";
if(cDiv.filters && cDiv.filters.alpha.opacity < 100)
{
cDiv.filters.alpha.opacity += 10;
setTimeout("calendar.fadeCalendarIn()",50);
}
if(cDiv.style.MozOpacity && cDiv.style.MozOpacity < 1.0)
{
cDiv.style.MozOpacity = parseFloat(cDiv.style.MozOpacity) + 0.1;
setTimeout("calendar.fadeCalendarIn()",50);
}
},
// getDaysInMonth method returns the number of days for the month based on set month and year
getDaysInMonth : function() {
// create two arrays for number of days in months (leap year and not)
// Non-Leap year Month days..
noLeapMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// Leap year Month days..
leapMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// check for leap years and use appropriate array
if ((arguments[1] % 4) == 0)
{
if ((arguments[1] % 100) == 0 && (arguments[1] % 400) != 0)
return noLeapMonth[arguments[0]];
return leapMonth[arguments[0]];
}
else
return noLeapMonth[arguments[0]];
},
//addDate method adds the date to the form field after being formatted by the dateInfo object
addDate : function(event) {
theDiv = document.getElementById('____myCalendar').style;
event = event || window.event;
var target = event.srcElement || event.target;
dateArr = target.id.split("-");
returnDate = new Date(dateArr[0],dateArr[1],dateArr[2]);
retDate = calendar.dateFormat.toLowerCase();
retDate = retDate.replace(/%mmmm%/g,dateInfo[calendar.language].monthLongNames[dateArr[1]]);
retDate = retDate.replace(/%mmm%/g,dateInfo[calendar.language].monthShortNames[dateArr[1]]);
retDate = retDate.replace(/%mm%/g,dateInfo.monthLeadZero[dateArr[1]]);
retDate = retDate.replace(/%m%/g,(parseFloat(dateArr[1])+1));
retDate = retDate.replace(/%dddd%/g,dateInfo[calendar.language].daysLongNames[returnDate.getDay()]);
retDate = retDate.replace(/%ddd%/g,dateInfo[calendar.language].daysShortNames[returnDate.getDay()]);
retDate = retDate.replace(/%dd%/g,(dateArr[2].length == 1 ? "0"+dateArr[2] : dateArr[2]));
retDate = retDate.replace(/%d%/g,dateArr[2]);
retDate = retDate.replace(/%yyyy%/g,dateArr[0]);
retDate = retDate.replace(/%yy%/g,dateArr[0].substring(2));
calendar.callerField.value = retDate;
calendar.calendarDisplayed = false;
theDiv.display = "none";
calendar.showHideSelects(false);
},
// getFirstOfMonthPad returns the number of days at the beginning of the month that need to be padded from the previous month
getFirstOfMonthPad : function() {
currentMonthYear = this.objMonthYear.getDisplayMonth();
return currentMonthYear.getDay();
},
displayCalendar : function() {
currentMonthYear = this.objMonthYear.getDisplayMonth();
theDiv = document.getElementById('____myCalendar');
theDiv.appendChild(calendarBuilder.build(this.getFirstOfMonthPad(), this.getDaysInMonth((currentMonthYear.getMonth() == 0 ? 11 : (currentMonthYear.getMonth()-1)), currentMonthYear.getFullYear())));
}
};
// calendarBuilder object builds the actual calendar using the DOM
var calendarBuilder = {
table : Object,
monthEndDay : 0,
monthDays : 1,
week : Object,
// init method initializes all of the properties and objects for each load of the calendar
init : function() {
this.table = document.createElement('table');
this.monthDays = 1;
this.week = null;
},
// addFirstWeek method builds the first week by padding the first few days with the previous month's end then starts the new month out to finish the week.
addFirstWeek : function() {
var firstWeek = this.table.insertRow(3);
var paddedPrevious = ((arguments[1]+1) - arguments[0]);
for(var i=0;i<arguments[0];i++)
{
daysInFirstWeek = firstWeek.insertCell(i);
daysInFirstWeek.className = (i==0 ? "weekendOutMonthCalTd" : "outMonthCalTd");
daysTextNode = document.createTextNode(paddedPrevious);
daysInFirstWeek.appendChild(daysTextNode);
daysInFirstWeek.onmouseover = this.changeBackground;
daysInFirstWeek.onmouseout = this.changeBackgroundBack;
daysInFirstWeek.id = (objDisplayMonth.getDisplayMonth().getMonth() == 0 ? (objDisplayMonth.getDisplayMonth().getFullYear()-1) : objDisplayMonth.getDisplayMonth().getFullYear())+"-"+(objDisplayMonth.getDisplayMonth().getMonth() == 0 ? 11 : (objDisplayMonth.getDisplayMonth().getMonth()-1))+"-"+paddedPrevious;
daysInFirstWeek.onclick = calendar.addDate;
paddedPrevious++;
}
for(j=arguments[0];j<7;j++)
{
daysInFirstWeek = firstWeek.insertCell(j);
//alert(objDisplayMonth.currentDate+" "+this.monthDays);
if(objDisplayMonth.currentDate == this.monthDays && objDisplayMonth.currentMonth == objDisplayMonth.getDisplayMonth().getMonth() && objDisplayMonth.currentYear == objDisplayMonth.getDisplayMonth().getFullYear())
daysInFirstWeek.className = "currentDay";
else if(calendar.selectedDate != null && (this.monthDays == calendar.selectedDay && objDisplayMonth.getDisplayMonth().getMonth() == calendar.selectedMonth && objDisplayMonth.getDisplayMonth().getFullYear() == calendar.selectedYear))
daysInFirstWeek.className = "selectedDay";
else
daysInFirstWeek.className = (j==6 || j==0 ? "weekendCalTd" : "calTd");
daysTextNode = document.createTextNode(this.monthDays);
daysInFirstWeek.appendChild(daysTextNode);
daysInFirstWeek.onmouseover = this.changeBackground;
daysInFirstWeek.onmouseout = this.changeBackgroundBack;
daysInFirstWeek.id = objDisplayMonth.getDisplayMonth().getFullYear()+"-"+objDisplayMonth.getDisplayMonth().getMonth()+"-"+this.monthDays;
daysInFirstWeek.onclick = calendar.addDate;
this.monthDays++;
}
},
//addAdditionalWeeks method builds the rest of the weeks for the given month
addAdditionalWeeks : function() {
var endOfMonth = false;
for(var j=2;j<7;j++)
{
// break out of outer loop if end of month is reached
if(endOfMonth)
break;
// we need to add 2 to the index to take into account the rows that have been added above
this.week = this.table.insertRow(j+2);
// create embedded loop to build the cells for each day
for(var k=0;k<7;k++)
{
if(this.monthDays <= calendar.daysInCurrentMonth)
{
daysInWeek = this.week.insertCell(k);
if(objDisplayMonth.currentDate == this.monthDays && objDisplayMonth.currentMonth == objDisplayMonth.getDisplayMonth().getMonth() && objDisplayMonth.currentYear == objDisplayMonth.getDisplayMonth().getFullYear())
daysInWeek.className = "currentDay";
else if(calendar.selectedDate != null && (this.monthDays == calendar.selectedDay && objDisplayMonth.getDisplayMonth().getMonth() == calendar.selectedMonth && objDisplayMonth.getDisplayMonth().getFullYear() == calendar.selectedYear))
daysInWeek.className = "selectedDay";
else
daysInWeek.className = (k==0 || k== 6 ? "weekendCalTd" : "calTd");
daysTextNode = document.createTextNode(this.monthDays);
daysInWeek.appendChild(daysTextNode);
daysInWeek.onmouseover = this.changeBackground;
daysInWeek.onmouseout = this.changeBackgroundBack;
daysInWeek.id = objDisplayMonth.getDisplayMonth().getFullYear()+"-"+objDisplayMonth.getDisplayMonth().getMonth()+"-"+this.monthDays;
daysInWeek.onclick = calendar.addDate;
this.monthDays++;
// break out of inner loop and set endOfMonth boolean if days of month is met
}
else
{
endOfMonth = true;
break;
}
}
}
//set monthEndDay property to determine if addLastWeek method needs to be called for next month
this.monthEndDay = k;
},
// addLastWeek method creates the start of the next month on the last week of the calendar
addLastWeek : function() {
var numberOfNextDays = (6 - this.monthEndDay);
//alert(numberOfNextDays);
//alert(this.monthEndDay);
var startNextMonth = 1;
for(var m=this.monthEndDay; m<(numberOfNextDays+this.monthEndDay+1); m++)
{
//alert(m);
lastDaysInWeek = this.week.insertCell(m);
lastDaysInWeek.className = (m==(numberOfNextDays+this.monthEndDay) ? "weekendOutMonthCalTd" :"outMonthCalTd");
daysTextNode = document.createTextNode(startNextMonth);
lastDaysInWeek.appendChild(daysTextNode);
lastDaysInWeek.onmouseover = this.changeBackground;
lastDaysInWeek.onmouseout = this.changeBackgroundBack;
lastDaysInWeek.id = (objDisplayMonth.getDisplayMonth().getMonth() == 11 ? (objDisplayMonth.getDisplayMonth().getFullYear()+1) : objDisplayMonth.getDisplayMonth().getFullYear())+"-"+(objDisplayMonth.getDisplayMonth().getMonth() == 11 ? 0 : (objDisplayMonth.getDisplayMonth().getMonth()+1))+"-"+startNextMonth;
lastDaysInWeek.onclick = calendar.addDate;
startNextMonth++;
}
},
// changeBackground method changes the background color for onmouseover events of table cells.
changeBackground : function(event) {
event = event || window.event;
var target = event.srcElement || event.target;
target.className += " mouseOverTd";
},
// changeBackground method changes the background color for onmouseover events of table cells.
changeBackgroundBack : function(event) {
event = event || window.event;
var target = event.srcElement || event.target;
target.className = target.className.replace("mouseOverTd","");
},
// shiftDate method changes the calendar month/year from the spans that list them when clicked
shiftDate : function(event) {
event = event || window.event;
var target = event.srcElement || event.target;
monthYear = target.id.split(",");
loadCal(calendar.calCaller,monthYear[0],monthYear[1]);
},
// changeByMonthYear method changes the calendar based on the options selected in the month or year select boxes
changeByMonthYear : function () {
theMonth = document.getElementById("____monthSelect").value;
theYear = document.getElementById("____yearSelect").value;
calTable = document.getElementById('____calendar');
calTable.parentNode.removeChild(calTable);
calendar.init();
calendar.month = theMonth;
calendar.year = theYear;
calendar.set();
calendar.displayCalendar();
},
// buildMOnthSelect method creates the select element for the months to be selected in the calendar header
buildMonthSelect : function() {
monthSelect = document.createElement("SELECT");
monthSelect.id = "____monthSelect";
monthSelect.name = "____monthSelect";
monthSelect.onchange = this.changeByMonthYear;
monthSelect.className = "dateSelects";
for(i=0;i<12;i++)
{
monthOption = document.createElement("OPTION");
monthOption.value = i;
monthOption.text = dateInfo[calendar.language].monthLongNames[i];
monthSelect.options.add(monthOption,i);
if(i == objDisplayMonth.getDisplayMonth().getMonth())
monthOption.selected = true;
}
return monthSelect;
},
// buildYearSelect method creates the select element for the years to be selected in the calendar header
buildYearSelect : function() {
var yearRange = calendar.selectYearRange.split("-");
var yearStart = parseInt(yearRange[0]);
var yearEnd = parseInt(yearRange[1]);
yearSelect = document.createElement("SELECT");
yearSelect.id = "____yearSelect";
yearSelect.name = "____yearSelect";
yearSelect.onchange = this.changeByMonthYear;
yearSelect.className = "dateSelects";
for(i=yearStart;i<yearEnd+1;i++)
{
yearOption = document.createElement("OPTION");
yearOption.value = i;
yearOption.text = i;
yearSelect.options.add(yearOption,i);
if(i == objDisplayMonth.getDisplayMonth().getFullYear())
yearOption.selected = true;
}
return yearSelect;
},
// addHeader method adds the calendar header with Month and Year
addHeader : function() {
// first row with selects
var headRow = this.table.insertRow(0);
var headCell = headRow.insertCell(0);
headCell.colSpan = 6;
headCell.className = "selectHeadTd";
headCell.appendChild(this.buildMonthSelect());
headCell.appendChild(this.buildYearSelect());
// add cell to close the calendar
headCell = headRow.insertCell(1);
// create the span that will actually close the calendar
headCellCloseSpan = document.createElement("span");
headCellCloseSpanText = document.createTextNode("X \u00a0");
headCellCloseSpan.appendChild(headCellCloseSpanText);
headCellCloseSpan.style.cursor = "hand";
headCellCloseSpan.style.cursor = "pointer";
headCellCloseSpan.onclick = calendar.close;
headCell.appendChild(headCellCloseSpan);
headCell.className = "topHeadCellTd";
// second row with month year and date selectors
headRow = this.table.insertRow(1);
// add first cell with year selector
headCell = headRow.insertCell(0);
headCellSpan = document.createElement("span");
headCellSpanText = document.createTextNode("\u00ab"+(objDisplayMonth.getDisplayMonth().getFullYear()-1));
headCellSpan.appendChild(headCellSpanText);
headCellSpan.style.cursor = "hand";
headCellSpan.style.cursor = "pointer";
headCellSpan.id = objDisplayMonth.getDisplayMonth().getMonth()+","+(objDisplayMonth.getDisplayMonth().getFullYear()-1);
headCellSpan.onclick = this.shiftDate;
headCell.appendChild(headCellSpan);
headCell.className = "headLeftTd";
// add second cell with month selector
headCell = headRow.insertCell(1);
headCellSpan = document.createElement("span");
headCellSpanText = document.createTextNode("\u00ab"+dateInfo[calendar.language].monthShortNames[(objDisplayMonth.getDisplayMonth().getMonth() != 0 ? (objDisplayMonth.getDisplayMonth().getMonth()-1) : 11)]);
headCellSpan.appendChild(headCellSpanText);
headCellSpan.style.cursor = "hand";
headCellSpan.style.cursor = "pointer";
headCellSpan.id = (objDisplayMonth.getDisplayMonth().getMonth() != 0 ? (objDisplayMonth.getDisplayMonth().getMonth()-1) : 11)+","+(objDisplayMonth.getDisplayMonth().getMonth() != 0 ? objDisplayMonth.getDisplayMonth().getFullYear() : (objDisplayMonth.getDisplayMonth().getFullYear()-1));
headCellSpan.onclick = this.shiftDate;
headCell.appendChild(headCellSpan);
headCell.className = "headMainTd";
// add third cell with month and year text
headCell = headRow.insertCell(2);
headCell.colSpan = 3;
headCell.className = "headCenterTd";
headCellText = document.createTextNode(dateInfo[calendar.language].monthLongNames[objDisplayMonth.getDisplayMonth().getMonth()]+" - "+objDisplayMonth.getDisplayMonth().getFullYear());
headCell.appendChild(headCellText);
// add fourth cell with month selector
headCell = headRow.insertCell(3);
headCellSpan = document.createElement("span");
headCellSpanText = document.createTextNode(dateInfo[calendar.language].monthShortNames[(objDisplayMonth.getDisplayMonth().getMonth() != 11 ? (objDisplayMonth.getDisplayMonth().getMonth()+1) : 0)]+"\u00bb");
headCellSpan.appendChild(headCellSpanText);
headCellSpan.style.cursor = "hand";
headCellSpan.style.cursor = "pointer";
headCellSpan.id = (objDisplayMonth.getDisplayMonth().getMonth() != 11 ? (objDisplayMonth.getDisplayMonth().getMonth()+1) : 0)+","+(objDisplayMonth.getDisplayMonth().getMonth() != 11 ? objDisplayMonth.getDisplayMonth().getFullYear() : (objDisplayMonth.getDisplayMonth().getFullYear()+1));
headCellSpan.onclick = this.shiftDate;
headCell.appendChild(headCellSpan);
headCell.className = "headMainTd";
// add fifth cell with year selector
headCell = headRow.insertCell(4);
headCellSpan = document.createElement("span");
headCellSpanText = document.createTextNode((objDisplayMonth.getDisplayMonth().getFullYear()+1)+"\u00bb");
headCellSpan.appendChild(headCellSpanText);
headCellSpan.style.cursor = "hand";
headCellSpan.style.cursor = "pointer";
headCellSpan.id = objDisplayMonth.getDisplayMonth().getMonth()+","+(objDisplayMonth.getDisplayMonth().getFullYear()+1);
headCellSpan.onclick = this.shiftDate;
headCell.appendChild(headCellSpan);
headCell.className = "headRightTd";
},
addDaysOfWeek : function() {
daysOfWeekRow = this.table.insertRow(2);
for(u=0;u<7;u++)
{
daysOfWeekCell = daysOfWeekRow.insertCell(u);
daysOfWeekCell.className = "daysOfWeekTd";
daysOfWeekCellText = document.createTextNode(dateInfo[calendar.language].daysShortNames[u]);
daysOfWeekCell.appendChild(daysOfWeekCellText);
}
},
// build method builds the actual table and returns it as an object
build : function() {
this.init();
this.addHeader();
this.addDaysOfWeek();
this.addFirstWeek(arguments[0],arguments[1]);
this.addAdditionalWeeks(arguments[0],arguments[1]);
if(this.monthEndDay)
this.addLastWeek(arguments[0],arguments[1]);
this.table.id = "____calendar";
this.table.className = "calTable";
return this.table;
}
};