// ***************************************************************************** // Cross-Browser Javascript pop-up calendar. // // Author : Anthony Garrett // // Credits : I wrote this from scratch myself but I couldn't have done it // without the superb "JavaScript The Definitive Guide" by David // Flanagan (Pub. O'Reilly ISBN 0-596-00048-0). I also recognise // a contribution from my experience with PopCalendar 4.1 by // Liming(Victor) Weng. // // Rights : Feel free to copy and change this as you like except that I // regard it as polite to leave the first twenty-one lines as is. // // Contact : Sorry, I can't offer support for this but if you find a problem // (or just want to tell me how useful you find it), please send // me an email at scwfeedback@tarrget.info (Note the two Rs in // tarrget). I will try to fix problems quickly but this is a // spare time thing for me. // // ***************************************************************************** // // Features: Easily customised // (output date format, colours, language, year range and // week start day) // Accepts a date as input // (see comments below for formats). // Cross-browser code tested against; // Internet Explorer 6.0.28 Mozilla 3.0.5 // Opera 7.52+ Firefox 0.9.1+ // Flock 0.4.9 // // How to add the Calendar to your page: // This script needs to be defined for your page so, immediately after // the BODY tag add the following line; // // // // How to use the Calendar once it is defined for your page: // Simply choose an event to trigger the calendar (like an onClick or // an onMouseOver) and an element to work on (for the calendar to take // its initial date from and write its output date to) then write it // like this; // <>="scwShow(<>,this);" // // e.g. onClick="scwShow(document.getElementById('myElement'),this);" // or onMouseOver="scwShow(this,this);" // // ***************************************************************************** // // Version Date By Description // ======= ==== =============== =========== // 1.0 2004-08-02 Anthony Garrett Initial release // 1.1 2005-10-17 Anthony Garrett Added requested feature to allow // a click anywhere on the calling page // to cancel the calendar. // Added "How to" paragraphs to // documentation (above). // Corrected bug that misread numeric // seed months as one less than entered. // 1.2 2005-10-26 Anthony Garrett Allow start of week to be any day. // 2.0 2005-11-03 Anthony Garrett Add an IFRAME behind the calendar to // deal with IE SELECT boxes. // Renamed all exposed variables and // functions but kept showCal as entry // point for backward compatibility. // Added classes to all HTML elements // and moved all style attributes to // inline stlye sheet in customisation // section. // 2.1 2005-11-10 Anthony Garrett Fixed a bug which causes the calendar // not to display in Firefox when the // event trigger element's parent was // not the data element's parent. // NOTE: This has forced me to add a // second interface parameter! // 2.2 2005-11-17 Anthony Garrett Added input date validation. // Added input date highlighting (thanks // to Brad Allan for that suggestion). // Added optional strict date processing // (e.g. making 31-Sep an error instead // of returning 1-Oct). Improved the // calendar positioning so that CSS // positioning using DIVs is handled // correctly. // 2.3 2005-11-23 Anthony Garrett Corrected input validation for US // and other date formats. Added // examples for US date processing. // 2.4 2005-12-10 Anthony Garrett Added feature to allow disabling // of specific days of the week, dates // and date ranges. Made it optional // that clicking on the calendar itself // causes the pop-up to be hidden. // Thanks to Felix Joussein for the // feedback. // 2.41 2005-12-12 Anthony Garrett Small fix for "Today" display when // there are no disabled dates. // 2.42 2005-12-15 Anthony Garrett Fixed bug where calendar could exceed // end of range by one month. // 2.45 2008-06-23 Yorick Hopmans Update Calender position for styled/css pages. // Note: this is browser specific. // // // Note : The year range is honoured by all the ways of changing between // months however I have decided not to prevent a user from selecting // a display day that is outside the range (it can happen if the day // falls in the week that starts or ends the range). This can be // handled by the date disabling feature if you wish to trap those // days. // // ***************************************************************************** // This date is used throughout to determine today's date. var scwDateNow = new Date(Date.parse(new Date().toDateString())); //------------------------------------------------------------------------------ // Customisation section //------------------------------------------------------------------------------ // Set the bounds for the calendar here... // If you want the year to roll forward you can use something like this... // var scwBaseYear = scwDateNow.getFullYear()-5; // alternatively, hard code a date like this... // var scwBaseYear = 1990; // var scwBaseYear = scwDateNow.getFullYear()-10; var scwBaseYear = scwDateNow.getFullYear()-80; // How many years do want to be valid and to show in the drop-down list? // var scwDropDownYears = 20; var scwDropDownYears = 90; // All language dependent changes can be made here... var scwToday = 'Today:', scwInvalidDateMsg = 'The entered date is invalid.\n', scwOutOfRangeMsg = 'The entered date is out of range.', scwDoesNotExistMsg = 'The entered date does not exist.', scwInvalidAlert = ['Invalid date (',') ignored.'], scwDateDisablingError = ['Error ',' is not a Date object.'], scwRangeDisablingError = ['Error ',' should consist of two elements.'], scwArrMonthNames = ['Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'], scwArrWeekInits = ['S','M','T','W','T','F','S']; // Note: Always start the scwArrWeekInits array with your string for // Sunday whatever scwWeekStart (below) is set to. // scwWeekStart determines the start of the week in the display // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc.. var scwWeekStart = 0; // Set the allowed date delimiters here... // E.g. To set the rising slash, hyphen, full-stop (aka stop or point) // and comma as delimiters use // var scwArrDelimiters = ['/','-','.',',']; var scwArrDelimiters = ['/','-','.',',']; // scwZindex controls how the pop-up calendar interacts with the rest // of the page. It is usually adequate to leave it as 1 (One) but I // have made it available here to help anyone who needs to alter the // level in order to ensure that the calendar displays correctly in // relation to all other elements on the page. var scwZindex = 1; // Personally I like the fact that entering 31-Sep-2005 displays // 1-Oct-2005, however you may want that to be an error. If so, // set scwBlnStrict = true. That will cause an error message to // display and the selected month is displayed without a selected // day. Thanks to Brad Allan for his feedback prompting this feature. var scwBlnStrict = false; // If you wish to disable any displayed day, e.g. Every Monday // you can do it by setting the following array. The array elements // match the displayed cells. // // You could put something like the following in your calling page // to disable all weekend days; // // for (var i=0;i"); document.writeln( '.scw {padding:1px;vertical-align:middle;}'); document.writeln( 'iframe.scw {position:absolute;z-index:' + scwZindex + ';top:0px;left:0px;visibility:hidden;' + 'width:1px;height:1px;}'); document.writeln( 'table.scw {padding:0px;visibility:hidden;' + 'position:absolute;width:200px;' + 'top:0px;left:0px;z-index:' + (scwZindex+1) + ';text-align:center;' + 'padding:1px;vertical-align:middle;' + 'background-color:' + scwBackground + ';border:ridge 2px;font-size:8pt;' + 'font-family:Arial,Helvetica,Sans-Serif;' + 'font-weight:bold;}'); document.writeln( 'td.scwHead {padding:0px 0px;text-align:center;}'); document.writeln( 'select.scwHead {margin:2px 1px;}'); document.writeln( 'input.scwHead {height:22px;width:22px;' + 'vertical-align:middle;' + 'text-align:center;margin:1px 1px;' + 'font-size:10pt;font-family:fixedSys;' + 'font-weight:bold;}'); document.writeln( 'tr.scwWeek {text-align:center;font-weight:bold;' + 'color:' + scwHeadText + ';}'); document.writeln( 'td.scwWeek {padding:0px;}'); document.writeln( 'table.scwCells {text-align:right;font-size:7pt;' + 'width:90%;font-family:' + 'Arial,Helvetica,Sans-Serif;}'); document.writeln( 'td.scwCells {padding:2px;vertical-align:middle;' + 'width:16px;height:12px;font-weight:bold;' + 'color:' + scwCellText + ';background-color:' + scwCellBackground + '}'); document.writeln( 'td.scwFoot {padding:0px;text-align:center;' + 'font-weight:normal;color:' + scwTodayText + ';}'); document.writeln(""); // You can modify the input, display and output date formats in the // following three functions; function scwInputFormat(scwArrInput,scwEleValue) {var scwArrSeed = new Array(); scwBlnFullInputDate = false; switch (scwArrInput.length) {case 1: {// Year only entry scwArrSeed[0] = parseInt(scwArrInput[0],10); // Year scwArrSeed[1] = '6'; // Month scwArrSeed[2] = 1; // Day break; } case 2: {// Year and Month entry scwArrSeed[0] = parseInt(scwArrInput[1],10); // Year scwArrSeed[1] = scwArrInput[0]; // Month scwArrSeed[2] = 1; // Day break; } case 3: {// Day Month and Year entry scwArrSeed[0] = parseInt(scwArrInput[2],10); // Year scwArrSeed[1] = scwArrInput[1]; // Month scwArrSeed[2] = parseInt(scwArrInput[0],10); // Day // for Month, Day and Year entry use... // scwArrSeed[0] = parseInt(scwArrInput[2],10); // Year // scwArrSeed[1] = scwArrInput[0]; // Month // scwArrSeed[2] = parseInt(scwArrInput[1],10); // Day scwBlnFullInputDate = true; break; } default: {// A stuff-up has led to more than three elements in the date. scwArrSeed[0] = 0; // Year scwArrSeed[1] = 0; // Month scwArrSeed[2] = 0; // Day } } // Apply validation and report failures if (scwExpValYear.exec(scwArrSeed[0]) == null || scwExpValMonth.exec(scwArrSeed[1]) == null || scwExpValDay.exec(scwArrSeed[2]) == null) {alert(scwInvalidDateMsg + scwInvalidAlert[0] + scwEleValue + scwInvalidAlert[1]); scwBlnFullInputDate = false; scwArrSeed[0] = scwBaseYear + Math.floor(scwDropDownYears/2); // Year scwArrSeed[1] = '6'; // Month scwArrSeed[2] = 1; // Day } // Return the Year in scwArrSeed[0] // Month in scwArrSeed[1] // Day in scwArrSeed[2] return scwArrSeed; } function scwDisplayFormat(scwDisplayDate) {// The format of the display of today's date at the foot of the // calendar... // Day Month and Year display document.write(scwDisplayDate.getDate() + "-" + scwArrMonthNames[scwDisplayDate.getMonth()] + "-" + scwDisplayDate.getFullYear()); // for Month, Day and Year output use... //document.write(scwArrMonthNames[scwDisplayDate.getMonth()] + "-" + // scwDisplayDate.getDate() + "-" + // scwDisplayDate.getFullYear()); } function scwSetOutput(scwOutputDate) {// Numeric months are held internally as 0 to 11 in this script so // the correct numeric month output should be in the form // (scwOutputDate.getMonth()+1) // e.g. // scwTargetEle.value = ((scwOutputDate.getDate()<10)?'0':'') + // scwOutputDate.getDate() + '-' + // ((scwOutputDate.getMonth()<9)?'0':'') + // (scwOutputDate.getMonth()+1) + '-' + // scwOutputDate.getFullYear(); // Day Month and Year output scwTargetEle.value = ((scwOutputDate.getDate()<10)?'0':'') + scwOutputDate.getDate() + '-' + scwArrMonthNames[scwOutputDate.getMonth()] + '-' + scwOutputDate.getFullYear(); // for Month, Day and Year output use... //scwTargetEle.value = scwArrMonthNames[scwOutputDate.getMonth()] + '-' + // ((scwOutputDate.getDate()<10)?'0':'') + // scwOutputDate.getDate() + '-' + // scwOutputDate.getFullYear(); scwHide(); } //------------------------------------------------------------------------------ // End of customisation section //------------------------------------------------------------------------------ // I try to avoid browser sniffing but the IE SELECT/z-index "feature" means // that I have had to place an IFRAME behind the pop-up. This currently // renders incorrectly in Opera (the IFRAME renders in front of the // calendar) but as I write (2005-Nov-01) the rendering is fixed in Opera 9 // which is in Beta. var scwIsOpera = (navigator.userAgent.toLowerCase().indexOf("opera")!=-1); // Browsers handle positioning differently Mozilla (Firefox & Flock) needs // to exclude DIVs while IE/Opera must include them so unfortunately I have // to sniff this too. var scwIsFirefox= (navigator.userAgent.toLowerCase().indexOf("firefox")!=-1); var scwTargetEle, scwSaveText, scwSaveBackground, scwMonthSum = 0, scwBlnFullInputDate = false, scwStartDate = new Date(), scwSeedDate = new Date(), scwWeekStart = scwWeekStart%7; // "Escape" all the user defined date delimiters - // several delimiters will need it and it does no harm for the others. var scwExpDelimiters = new RegExp('[\\'+scwArrDelimiters.join('\\')+']','g'); // These regular expression validate the input date format to the // following rules; // // Format: Day 1-31 (optional zero on single digits) // Month 1-12 (optional zero on single digits) // or case insensitive name // Year Two or four digits // Months names and Delimiters are as defined above var scwExpValDay = /^(0?[1-9]|[1-2]\d|3[0-1])$/, scwExpValMonth = new RegExp("^(0?[1-9]|1[0-2]|" + scwArrMonthNames.join("|") + ")$","i"), scwExpValYear = /^(\d{2}|\d{4})$/; function showCal(scwEle,scwSourceEle) {scwShow(scwEle,scwSourceEle);} function scwShow(scwEle,scwSourceEle) { //********************************************************************* // If no value is preset then the seed date is // Today (when today is in range) OR // The middle of the date range. scwSeedDate = scwDateNow; // Strip space characters from start and end of date input scwEle.value = scwEle.value.replace(/^\s+/,'').replace(/\s+$/,''); if (scwEle.value.length==0) {// If no value is entered and today is within the range, // use today's date, otherwise use the middle of the valid range. scwBlnFullInputDate=false; if ((new Date(scwBaseYear+scwDropDownYears-1,11,31))scwSeedDate ) {scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears / 2), 5, 1); } } else {// Parse the string into an array using the allowed delimiters scwArrSeedDate = scwInputFormat(scwEle.value.split(scwExpDelimiters), scwEle.value); // So now we have the Year, Month and Day in an array. // If the year is two digits then the routine assumes a year // belongs in the 21st Century unless it is less than 50 in which // case it assumes the 20th Century is intended. if (scwArrSeedDate[0]<100) {scwArrSeedDate[0]= scwArrSeedDate[0] + parseInt((scwArrSeedDate[0]>50)?1900:2000, 10); } // Check whether the month is in digits or an abbreviation if (scwArrSeedDate[1].search(/\d+/)!=0) {month = scwArrMonthNames.join('|').toUpperCase(). search(scwArrSeedDate[1].substr(0,3).toUpperCase()); scwArrSeedDate[1] = Math.floor(month/4)+1; } scwSeedDate = new Date(scwArrSeedDate[0], scwArrSeedDate[1]-1, scwArrSeedDate[2]); } // Test that we have arrived at a valid date if (isNaN(scwSeedDate)) {alert( scwInvalidDateMsg + scwInvalidAlert[0] + scwEle.value + scwInvalidAlert[1]); scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears/2),5,1); scwBlnFullInputDate=false; } else {// Test that the date is within range, // if not then set date to a sensible date in range. if ((new Date(scwBaseYear,0,1)) > scwSeedDate) {if (scwBlnStrict) alert(scwOutOfRangeMsg); scwSeedDate = new Date(scwBaseYear,0,1); scwBlnFullInputDate=false; } else {if ((new Date(scwBaseYear+scwDropDownYears-1,11,31))< scwSeedDate) {if (scwBlnStrict) alert(scwOutOfRangeMsg); scwSeedDate = new Date(scwBaseYear + Math.floor(scwDropDownYears)-1, 11,1); scwBlnFullInputDate=false; } else {if (scwBlnStrict && scwBlnFullInputDate && (scwSeedDate.getDate() != scwArrSeedDate[2] || (scwSeedDate.getMonth()+1) != scwArrSeedDate[1] || scwSeedDate.getFullYear() != scwArrSeedDate[0] ) ) {alert(scwDoesNotExistMsg); scwSeedDate = new Date(scwSeedDate.getFullYear(), scwSeedDate.getMonth()-1,1); scwBlnFullInputDate=false; } } } } // Test the disabled dates for validity // Give error message if not valid. for (var i=0;i scwDisabledDates[i][1])) {scwDisabledDates[i].reverse();} } else {alert(scwDateDisablingError[0] + scwDisabledDates[i] + scwDateDisablingError[1]);} } } // Calculate the number of months that the entered (or // defaulted) month is after the start of the allowed // date range. scwMonthSum = 12*(scwSeedDate.getFullYear()-scwBaseYear)+ scwSeedDate.getMonth(); // Set the drop down boxes. document.getElementById('scwYears').options.selectedIndex = Math.floor(scwMonthSum/12); document.getElementById('scwMonths').options.selectedIndex= (scwMonthSum%12); // Position the calendar box if(scwIsFirefox) { var brws_top = 0, brws_left = 0; if(parseInt(window.innerWidth,10)>1000) brws_left += parseInt((window.innerWidth/2),10)-837; } else { var brws_top = -755, brws_left = 0; if(parseInt(document.body.clientWidth,10)>900) brws_left += parseInt((900-document.body.clientWidth),10); } var offsetTop =parseInt(scwEle.offsetTop,10)+ parseInt(scwEle.offsetHeight,10)+brws_top, offsetLeft=parseInt(scwEle.offsetLeft,10)+brws_left; scwTargetEle=scwEle; do {scwEle=scwEle.parentNode; if (scwEle.tagName!='FORM' && scwEle.tagName!='TBODY' && scwEle.tagName!='TR' && ((scwIsFirefox && scwEle.tagName!='DIV') || !scwIsFirefox) && scwEle.nodeType==1) {offsetTop +=parseInt(scwEle.offsetTop,10); offsetLeft+=parseInt(scwEle.offsetLeft,10); } } while (scwEle.tagName!='BODY'); document.getElementById('scw').style.top =offsetTop +'px'; document.getElementById('scw').style.left=offsetLeft+'px'; if (!scwIsOpera) {document.getElementById('scwIframe').style.top =offsetTop +'px'; document.getElementById('scwIframe').style.left=offsetLeft+'px'; document.getElementById('scwIframe').style.width = (document.getElementById('scw').offsetWidth-2)+'px'; document.getElementById('scwIframe').style.height = (document.getElementById('scw').offsetHeight-2)+'px'; document.getElementById('scwIframe').style.visibility='visible'; } // Display the month scwShowMonth(0); // Show it on the page document.getElementById('scw').style.visibility='visible'; scwCancelPropagation(scwSourceEle); } function scwCellOutput(scwEvt) {var scwEle = eventTrigger(scwEvt), scwOutputDate = new Date(scwStartDate); scwOutputDate.setDate(scwStartDate.getDate() + parseInt(scwEle.id.substr(8),10)); scwSetOutput(scwOutputDate); } function scwFootOutput() {scwSetOutput(scwDateNow);} function scwCancelPropagation(scwSourceEle) {if (typeof event=='undefined') //Firefox {scwSourceEle.parentNode. addEventListener("click",scwStopPropagation,false); } else {event.cancelBubble = true;} //IE, Opera } function scwStopPropagation(scwEvt) {if (typeof event=='undefined') scwEvt.stopPropagation(); //Firefox else scwEvt.cancelBubble = true; //IE, Opera } function scwHighlight(e) {var scwEle = eventTrigger(e); scwSaveText =scwEle.style.color; scwSaveBackground =scwEle.style.backgroundColor; scwEle.style.color =scwHighlightText; scwEle.style.backgroundColor =scwHighlightBackground; return true; } function scwUnhighlight(e) {var scwEle = eventTrigger(e); scwEle.style.backgroundColor =scwSaveBackground; scwEle.style.color =scwSaveText; return true; } function eventTrigger(e) {if (!e) e = event; return e.target||e.srcElement; } function scwCancel(e) {if (scwClickToHide) scwHide(); scwStopPropagation(e);} function scwHide() {document.getElementById('scw').style.visibility='hidden'; if (!scwIsOpera) {document.getElementById('scwIframe').style.visibility='hidden';} } function scwFootOver() {document.getElementById('scwFoot').style.color=scwTodayHighlight; document.getElementById('scwFoot').style.fontWeight='bold'; } function scwFootOut() {document.getElementById('scwFoot').style.color=scwTodayText; document.getElementById('scwFoot').style.fontWeight='normal'; } function scwShowMonth(scwBias) {// Set the selectable Month and Year // May be called: from the left and right arrows // (shift month -1 and +1 respectively) // from the month selection list // from the year selection list // from the showCal routine // (which initiates the display). var scwShowDate = new Date(Date.parse(new Date().toDateString())); scwSelYears = document.getElementById('scwYears'); scwSelMonths = document.getElementById('scwMonths'); if (scwSelYears.options.selectedIndex>-1) {scwMonthSum=12*(scwSelYears.options.selectedIndex)+scwBias; if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;} } else {if (scwSelMonths.options.selectedIndex>-1) {scwMonthSum+=scwSelMonths.options.selectedIndex;} } scwShowDate.setFullYear(scwBaseYear + Math.floor(scwMonthSum/12), (scwMonthSum%12), 1); if ((12*parseInt((scwShowDate.getFullYear()-scwBaseYear),10)) + parseInt(scwShowDate.getMonth(),10) < (12*scwDropDownYears) && (12*parseInt((scwShowDate.getFullYear()-scwBaseYear),10)) + parseInt(scwShowDate.getMonth(),10) > -1) {scwSelYears.options.selectedIndex=Math.floor(scwMonthSum/12); scwSelMonths.options.selectedIndex=(scwMonthSum%12); scwCurMonth = scwShowDate.getMonth(); scwShowDate.setDate(-(scwShowDate.getDay()-scwWeekStart)%7+1); scwStartDate = new Date(scwShowDate); var scwFoot = document.getElementById('scwFoot'); if (scwDisabledDates.length==0) {if (scwActiveToday) {scwFoot.onclick=scwFootOutput; scwFoot.onmouseover=scwFootOver; scwFoot.onmouseout =scwFootOut; } else {if (document.addEventListener) {scwFoot.addEventListener('click',scwStopPropagation, false);} else {scwFoot.attachEvent('onclick',scwStopPropagation);} scwFoot.onmouseover=null; scwFoot.onmouseout=null; } } else {for (var k=0;k= scwDisabledDates[k][0].valueOf() && scwDateNow.valueOf() <= scwDisabledDates[k][1].valueOf() ) ) ) ) {if (document.addEventListener) {scwFoot.addEventListener('click',scwStopPropagation, false);} else {scwFoot.attachEvent('onclick',scwStopPropagation);} scwFoot.onmouseover=null; scwFoot.onmouseout=null; break; } else {scwFoot.onclick=scwFootOutput; scwFoot.onmouseover=scwFootOver; scwFoot.onmouseout =scwFootOut; } } } // Treewalk to display the dates. // I tried to use getElementsByName but IE refused to cooperate // so I resorted to this method which works for all tested // browsers. var scwCells = document.getElementById('scwCells'); for (i=0;i= scwDisabledDates[k][0].valueOf() && scwShowDate.valueOf() <= scwDisabledDates[k][1].valueOf()) {scwDisabled = true;} } } if (scwDisabled || !scwEnabledDay[j+(7*((i*scwCells.childNodes.length)/6))]) {scwRows.childNodes[j].onclick=null; scwRows.childNodes[j].onmouseover=null; scwRows.childNodes[j].onmouseout=null; scwCellStyle.color=scwDisabledDayText; scwCellStyle.backgroundColor= scwDisabledDayBackground; } else {scwRows.childNodes[j].onclick =scwCellOutput; scwRows.childNodes[j].onmouseover =scwHighlight; scwRows.childNodes[j].onmouseout =scwUnhighlight; if (scwShowDate.getMonth()!=scwCurMonth) {scwCellStyle.color=scwExMonthText; scwCellStyle.backgroundColor= scwExMonthBackground; } else if (scwBlnFullInputDate && scwShowDate.toDateString()== scwSeedDate.toDateString()) {scwCellStyle.color=scwInDateText; scwCellStyle.backgroundColor= scwInDateBackground; } else if (scwShowDate.getDay()%6==0) {scwCellStyle.color=scwWeekendText; scwCellStyle.backgroundColor= scwWeekendBackground; } else {scwCellStyle.color=scwCellText; scwCellStyle.backgroundColor= scwCellBackground; } } scwShowDate.setDate(scwShowDate.getDate()+1); } } } } } } if (!scwIsOpera) {document.write(""); } document.write( "" + "" + "" + "" + "" + "" + "" + "
" + "" + "" + "" + "" + "" + "" + "" + "
" + "" + "" + "" + "" + "" + "
" + "
" + "" + "" + ""); for (i=0;i" + scwArrWeekInits[(i+scwWeekStart)%scwArrWeekInits.length] + ""); document.write("" + "" + ""); for (i=0;i<6;i++) {document.write( ""); for (j=0;j<7;j++) {document.write( ""); } document.write( ""); } document.write( ""); if ((new Date(scwBaseYear + scwDropDownYears, 11, 32)) > scwDateNow && (new Date(scwBaseYear, 0, 0)) < scwDateNow) {document.write( "" + "" + "" + "" + ""); } document.write( "
" + scwToday + " "); scwDisplayFormat(scwDateNow); document.write( "
" + "
"); if (document.addEventListener) {document.addEventListener('click',scwHide, false); document.getElementById('scw').addEventListener('click',scwCancel,false); document.getElementById('scwHead').addEventListener('click',scwStopPropagation,false); document.getElementById('scwCells').addEventListener('click',scwStopPropagation,false); } else {document.attachEvent('onclick',scwHide); document.getElementById('scw').attachEvent('onclick',scwCancel); document.getElementById('scwHead').attachEvent('onclick',scwStopPropagation); document.getElementById('scwCells').attachEvent('onclick',scwStopPropagation); } // End of Calendar