// Namespace JACS // -------------- // This namespace encapsulates all the calendar script code eliminating // naming conflicts between the JavaScript in this script and your calling // page(s) [as long as you don't use JACS as a variable of course]. It is // still possible for CSS inheritance to cause problems but that is unavoidable. var JACS = new function() {// This date is used throughout to determine today's date. var dateNow = new Date(Date.parse(new Date().toDateString())); // This array keeps track of the defined calendars for the page. var cals = new Array(); // This function shortens the code replacing // document.getElementById('myID') with getEl('myId') // everywhere in the script. It also tries to handle a common // error when calling the script: when the developer has only // set a NAME attribute value, so no ID attribute is set. function getEl(id) {if (document.getElementById(id) || (!document.getElementById(id) && document.getElementsByName(id).length==0)) // IF An ID attribute is assigned // OR No ID attribute is assigned but using IE and Opera // (which will find the NAME attribute value using getElementById) // OR No element has this ID or NAME attribute value // (used internally by the script) // THEN Return the required element. {return document.getElementById(id);} else {if (document.getElementsByName(id).length==1) // IF No ID attribute is assigned // AND Using a standards-based browser // AND Only one element has the NAME attribute set to the value // THEN Return the required element (using the NAME attribute value). {return document.getElementsByName(id)[0];} else {if (document.getElementsByName(id).length>1) { // IF No ID attribute is assigned // AND using a standards-based browser // AND more than one element has the NAME attribute set to the value // THEN alert developer to fix the fault. alert( 'JACS' + ' \nCannot uniquely identify element named: ' + id + '.\nMore than one identical NAME attribute defined' + '.\nSolution: Assign the required element a unique ID attribute value.'); } } } }; // This DIV inside an IE-only conditional comments is a // reliable way of setting up object testing for IE. document.writeln(""); document.writeln(""); //****************************************************************************** //------------------------------------------------------------------------------ // Customisation section //------------------------------------------------------------------------------ //****************************************************************************** // I have made every effort to isolate the pop-up script from any // CSS defined on the main page but if you have anything set that // affects the pop-up (or you may want to change the way it looks) // then you can address it in the following style sheets. document.writeln( '' ); // This style sheet can be extracted from the script and edited into regular // CSS (by removing all occurrences of + and '). That can be used as the // basis for themes. Classes are described in comments within the style // sheet. document.writeln( ''); function calAttributes(cal) {switch (cal.id) {case 'EnterYourIDHere': // If you want to vary the attributes for a specific instance // of the calendar, replace 'EnterYourIDHere' (above) with the // ID that you have defined for that calendar then amend and // uncomment the block-commented section below (which is just // a copy of the default section below with all the // documentation comments removed). /* cal.zIndex = 1; cal.baseYear = dateNow.getFullYear()-10; cal.dropDownYears = 20; cal.weekStart = 1; cal.weekNumberBaseDay = 4; cal.weekNumberDisplay = false; try {jacsSetLanguage(cal);} catch (exception) {cal.today = 'Vandaag:'; cal.clear = 'Leeg'; cal.drag = 'klik hier om te slepen'; cal.monthNames = ['Jan','Feb','Mrt','Apr','Mei','Jun', 'Jul','Aug','Sep','Okt','Nov','Dec']; cal.weekInits = ['Z','M','D','W','D','V','Z']; cal.invalidDateMsg = 'De ingevoerde datum is ongeldig.\n'; cal.outOfRangeMsg = 'De ingevoerde datum is ongeldig.'; cal.doesNotExistMsg = 'De ingevoerde datum is ongeldig.'; cal.invalidAlert = ['Ongeldige datum (',') genegeerd.']; cal.dateSettingError = ['Fout ',' is geen datumobject.']; cal.rangeSettingError = ['Fout ',' dient uit 2 elementen te bestaan.']; } cal.showInvalidDateMsg = true; cal.showOutOfRangeMsg = true; cal.showDoesNotExistMsg = true; cal.showInvalidAlert = true; cal.showDateSettingError = true; cal.showRangeSettingError = true; cal.delimiters = ['/','-','.',':',',',' ']; cal.dateDisplayFormat = 'dd-mm-yy'; cal.dateFormat = 'DD MMM YYYY'; cal.strict = false; cal.dates = new Array(); cal.higlightDates = new Array(); cal.dayCells = [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]; cal.outOfRangeDisable = true; cal.outOfMonthDisable = false; cal.outOfMonthHide = false; cal.formatTodayCell = true; cal.todayCellBorderColour = 'red'; cal.allowDrag = false; cal.onBlurMoveNext = false; cal.clickToHide = false; cal.xBase = 'L'; // L Left, M Middle, R Right or integer pixel offset from left cal.yBase = 'B'; // T Top, M Middle, B Bottom or integer pixel offset from top cal.xPosition = 'L'; // L Left, M Middle, R Right or integer pixel offset from left cal.yPosition = 'T'; // T Top, M Middle, B Bottom or integer pixel offset from top cal.autoPosition = true; */ break; default: // cal.zIndex 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. cal.zIndex = 1; // Set the bounds for the calendar here... // If you want the year to roll forward you can use something // like this... // var baseYear = dateNow.getFullYear()-5; // alternatively, hard code a date like this... // var baseYear = 1990; // cal.baseYear = dateNow.getFullYear()-10; // How many years do want to be valid and to show in the // drop-down list? if (cal.id=="kalender4") { cal.dropDownYears = 61; cal.baseYear = 1964; } else if (cal.id=="kalender3") { cal.dropDownYears = 100; cal.baseYear = 1924; } else if (cal.id=="kalender2") { cal.dropDownYears = 3; cal.baseYear = 2023; } else if (cal.id=="kalender1") { cal.dropDownYears = 2; cal.baseYear = 2024; } // weekStart determines the start of the week in the display // Set it to: 0 (Zero) for Sunday, 1 (One) for Monday etc.. // Note: Always start the weekInits array with your // string for Sunday whatever weekStart (below) // is set to. cal.weekStart = 1; // Week numbering rules are generally based on a day in the week // that determines the first week of the year. ISO 8601 uses // Thursday (day four when Sunday is day zero). You can alter // the base day here. // See http://www.cl.cam.ac.uk/~mgk25/iso-time.html // for more information cal.weekNumberBaseDay = 4; // The week start day for the display is taken as the week start // for week numbering. This ensures that only one week number // applies to one line of the calendar table. // [ISO 8601 begins the week with Day 1 = Monday.] // If you want to see week numbering on the calendar, set // this to true. If not, false. cal.weekNumberDisplay = false; // If the calendar is given a date that it can't parse a month // from, it will use a default month. If the following attribute // is FALSE then the default month is month 6 (June), if set to // TRUE then the default will be the current month. cal.defaultToCurrentMonth = false; // All language-dependent settings can be made here... // If you wish to work in a single language (other than English) // then just replace the English below with your own text. // Using multiple languages: // In order to keep this script to a resonable size I have not // included multiple languages here. However, you can set the language // fields in a function that you should name jacsSetLanguage. The script // will then use your languages. I have included all the translations // that have been sent to me in such a function on my demonstration // site at http://www.tarrget.info/calendar/jacsLanguages.js. try {jacsSetLanguage(cal);} catch (exception) {// English cal.language = 'nl'; cal.today = 'Vandaag:'; cal.clear = 'Leeg'; cal.drag = 'klik hier om te slepen'; cal.monthNames = ['Jan','Feb','Mrt','Apr','Mei','Jun', 'Jul','Aug','Sep','Okt','Nov','Dec']; cal.weekInits = ['Z','M','D','W','D','V','Z']; cal.invalidDateMsg = 'De ingevoerde datum is ongeldig.\n'; cal.outOfRangeMsg = 'De ingevoerde datum is ongeldig.'; cal.doesNotExistMsg = 'De ingevoerde datum is ongeldig.'; cal.invalidAlert = ['Ongeldige datum (',') genegeerd.']; cal.dateSettingError = ['Fout ',' is geen datum-object.']; cal.rangeSettingError = ['Fout ',' dient uit 2 elementen te bestaan.']; } // Each of the calendar's alert message types can be disabled // independently here. cal.showInvalidDateMsg = true; cal.showOutOfRangeMsg = true; cal.showDoesNotExistMsg = true; cal.showInvalidAlert = true; cal.showDateSettingError = true; cal.showRangeSettingError = true; // Set the whole calendar as active (dates selectable) // or inactive (display only) cal.active = true; // Set the allowed input date delimiters here... // E.g. To set the rising slash, hyphen, full-stop (aka stop or // point), colon, comma and space as delimiters use // var cal.delimiters = ['/','-','.',':',',',' ']; cal.delimiters = ['/','-','.',':',',',' ']; // Set the format for the displayed 'Today' date and for the // output date here. // // The format is described using delimiters of your choice (as // set in cal.delimiters above) and case insensitive letters // D, M and Y. // // NOTE: If no delimiters are input then the date output format is used // to parse the value. This allows less flexiblility in the input // value than using delimiters but an accurately entered date // remains parsable. // Displayed "Today" date format cal.dateDisplayFormat = 'dd/mm/yyyy'; // e.g. 'MMM-DD-YYYY' for the US // Output date format cal.dateFormat = 'DD-MM-YYYY'; // e.g. 'MMM-DD-YYYY' for the US // Note: The delimiters used should be in cal.delimiters. // Personally I like the fact that entering 31-Sep-2005 (a date // that doesn't exist) displays 1-Oct-2005, however you may want // that to be an error. If so, set cal.strict = 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. cal.strict = false; // If you are using ReadOnly or diaabled fields to return the date // value into, it can be useful to show a button on the calendar // that allows the value to be cleared. If you want to do that, // set cal.clearButton = true; cal.clearButton = true; // Choose whether the dates and days you specify in cal.dates // and as parameters to the JACS.show call are enabled (with all // other dates disabled) or disabled (with all other dates enabled). cal.valuesEnabled = false; // If you wish to set any displayed day, e.g. Every Monday, // you can do it using the following array. The array elements // match the displayed cells. // // With the valuesEnabled attribute FALSE you could put something // like the following in your calling page to disable all weekend // days; // // for (var i=0;i<<>.dayCells.length;i++) // {if (i%7%6==0) <>.dayCells[i] = false;} // // The above approach will allow you to select days of the week // for the whole of your page easily. If you need to set different // selected days for a number of date input fields on your page // there is an easier way: You can pass optional arguments to // JACS.show. The syntax is described at the top of this script in // the section: // "How to use the Calendar once it is defined for your page:" // // It is possible to use these two approaches in combination. cal.dayCells = [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]; // You can specify any date (e.g. 24-Jan-2006 or Today) by creating // an element of the array cal.dates as a date object with the // value you want to handle. Date ranges can be handled by placing // an array of two values (Start and End) into an element of this array. // // Use cal.valuesEnabled to determine whether any specified dates // are treated as the only enabled ones or the only disabled ones. cal.dates = new Array(); // e.g. To specify 10-Dec-2005: // cal.dates[0] = new Date(2005,11,10); // // Or a range from 2004-Dec-25 to 2005-Jan-01: // // cal.dates[1] = // [new Date(2004,11,25),new Date(2005,0,1)]; // // The following will specify all calendar dates up to // yesterday: // // cal.dates[2] = // [new Date(cal.baseYear,0,1), // new Date(dateNow.getFullYear(), // dateNow.getMonth(), // dateNow.getDate()-1)]; // // Remember that Javascript months are zero-based. // Allow specified dates to be highlighted when they are enabled. // You can set individual dates or date ranges in the same way as // above. cal.highlightDates = new Array(); // Dates that are out of the specified range can be displayed at // the start of the very first month and end of the very last. // Set outOfRangeDisable = true to disable these dates // (or false to allow their selection). cal.outOfRangeDisable = true; // Dates that are out of the displayed month are shown at the start // (unless the month starts on the first day of the week) and end of // each month. Set outOfMonthDisable = true to disable these dates // (or false to allow their selection). Set outOfMonthHide = true // to hide these dates (or false to make them visible). cal.outOfMonthDisable = false; cal.outOfMonthHide = false; // If you want a special format for the cell that contains the current day // set this to true. This sets a thin border around the cell in the colour // set by cal.todayCellBorderColour. cal.formatTodayCell = true; cal.todayCellBorderColour = '#f00'; // red // You can allow the calendar to be dragged around the screen by // using the setting allowDrag = true. // I can't say I recommend it because of the danger of the user // forgetting which date field the calendar will update when // there are multiple date fields on a page. cal.allowDrag = false; // It is not easy to code HTML events to make the focus move // automatically on to the next element in the tab order so // here is a parameter you can set that will tell the script // to do it for you. NOTE: The script may have to build a list // of all the page's elements in tabIndex order to achieve this // so there can be an overhead to using this feature. cal.onBlurMoveNext = false; // You can allow a click on the calendar to close dynamic // calendars by setting clickToHide = true. If set to false // the script will hide a dynamic calendar when a date is // selected or the main page is clicked. cal.clickToHide = false; // Dynamic calendar positioning is relative to the return value // element. The script is supplied with the parameters below // setting the calendar's top left corner to appear at the // return element's bottom left corner. cal.xBase = 'L'; cal.yBase = 'B'; cal.xPosition = 'L'; cal.yPosition = 'T'; // For the horizontal (X) parameters, xBase and xPosition, // the accepted values are; L - Left // M - Middle // R - Right // or nn - integer pixel offset from left +/- // // For the vertical (Y) parameters, yBase and yPosition, // the accepted values are; T - Top // M - Middle // B - Bottom // or nn - integer pixel offset from top +/- // The calendar will position itself aligned according to the // choices above. If automatic positioning is turned // on with cal.autoPosition = true then if the chosen position // would cause the calendar to display off the visible screen, // it is shifted to a position that is visible. cal.autoPosition = true; } // Do not set the value of this calendar attribute. It is used // to tell you whether a date has been selected or not when // using the JACS.next feature to trigger a function after the // calendar is used. // dateReturned is False unless the user has clicked on an // active date cell or the value for "Today", in which case // it is True. cal.dateReturned = false; // The most recent date output to the target element is stored // as an attribute of the calendar. Initialised to Midnight // on 1st January 1970 (UTC), a selected date can never // equal this because returned dates are always 12 Midday. cal.outputDate = new Date(0); // Finally: The following attributes are used in calendar // functions. You need do nothing with them here. cal.seedDate = new Date(); cal.fullInputDate = false; cal.activeToday = true; cal.monthSum = 0; cal.days = new Array(); cal.arrOnNext = new Array(); cal.triggerEle; cal.targetEle; }; //****************************************************************************** //------------------------------------------------------------------------------ // End of customisation section //------------------------------------------------------------------------------ //****************************************************************************** // ******************************************************* // Custom methods for Date, String and Function prototypes // ******************************************************* // Format a date into the required pattern Date.prototype.jacsFormat = function(format,monthNames) {var charCount = 0, codeChar = '', result = ''; for (var i=0;i<=format.length;i++) {if (i0) {result += codeChar;} } if (i-1) {cal.monthSum =12*(selYears.options.selectedIndex)+bias;} if (selMonths.options.selectedIndex>-1) {cal.monthSum+=selMonths.options.selectedIndex;} showDate.setFullYear(cal.baseYear+Math.floor(cal.monthSum/12),(cal.monthSum%12),1); // If the Week numbers are displayed, shift the week day names to the right. getEl(calId+'Week_').style.display = (cal.weekNumberDisplay)?'':'none'; // Opera has a bug with setting the selected index. // It requires the following work-around to force SELECTs to display correctly. if (window.opera) {selMonths.style.display = 'inherit'; selYears.style.display = 'inherit'; } tmp = (12*parseInt((showDate.getFullYear()-cal.baseYear),10)) + parseInt(showDate.getMonth(),10); if (tmp > -1 && tmp < (12*cal.dropDownYears)) {selYears.options.selectedIndex = Math.floor(cal.monthSum/12); selMonths.options.selectedIndex = (cal.monthSum%12); curMonth = showDate.getMonth(); showDate.setDate((((showDate.getDay()-cal.weekStart)<0)?-6:1)+cal.weekStart-showDate.getDay()); var compareDateValue = new Date(showDate.getFullYear(),showDate.getMonth(),showDate.getDate()).valueOf(); startDate = new Date(showDate); var now = getEl(calId+'Now'); function nowOutput() {setOutput(dateNow,calId);}; if (cal.dates.length==0) {if (cal.active && cal.activeToday) {now.onclick = nowOutput; now.className = 'jacsNow'; if (getEl('jacsIE')) {now.onmouseover = changeClass; now.onmouseout = changeClass; } if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);} else {now.detachEvent( 'onclick',stopPropagation);} } else {now.onclick = null; now.className = 'jacsNowDisabled'; if (getEl('jacsIE')) {now.onmouseover = null; now.onmouseout = null; } if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);} else {now.attachEvent( 'onclick',stopPropagation);} } } else {for (var k=0;k= cal.dates[k][0].valueOf() && dateNow.valueOf() <= cal.dates[k][1].valueOf() ) ) ) ) {now.onclick = (cal.active && cal.valuesEnabled)?nowOutput:null; now.className = (cal.active && cal.valuesEnabled)?'jacsNow':'jacsNowDisabled'; if (getEl('jacsIE')) {now.onmouseover = (cal.active && cal.valuesEnabled)?changeClass:null; now.onmouseout = (cal.active && cal.valuesEnabled)?changeClass:null; } if (cal.active && cal.valuesEnabled) {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);} else {now.detachEvent( 'onclick',stopPropagation);} } else {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);} else {now.attachEvent( 'onclick',stopPropagation);} } break; } else {now.onclick = (cal.active && cal.valuesEnabled)?null:nowOutput; now.className = (cal.active && cal.valuesEnabled)?'jacsNowDisabled':'jacsNow'; if (getEl('jacsIE')) {now.onmouseover = (cal.active && cal.valuesEnabled)?null:changeClass; now.onmouseout = (cal.active && cal.valuesEnabled)?null:changeClass; } if (cal.active && cal.valuesEnabled) {if (document.addEventListener) {now.addEventListener('click',stopPropagation,false);} else {now.attachEvent( 'onclick',stopPropagation);} } else {if (document.removeEventListener) {now.removeEventListener('click',stopPropagation,false);} else {now.detachEvent( 'onclick',stopPropagation);} } } } } function setOutput(outputDate,calId) {var cal = getEl(calId); if (typeof cal.targetEle.value == 'undefined') {cal.triggerEle.textNode.replaceData(0,cal.triggerEle.len,outputDate.jacsFormat(cal.dateFormat,cal.monthNames));} else {cal.ele.value = outputDate.jacsFormat(cal.dateFormat,cal.monthNames);} cal.dateReturned = true; cal.outputDate = outputDate; if (cal.dynamic) {hide(calId);} else {if (typeof cal.onNext!='undefined' && cal.onNext!=null) {cal.onNext();} JACS.show(cal.ele,cal.id,cal.days); } if (cal.onBlurMoveNext) {// if the target element has a tabIndex look for tabIndex+1 // if that exists then set the focus to it var tagsToFind = 'INPUT;A;SELECT;TEXTAREA;BUTTON;AREA;OBJECT', found = false; if (cal.ele.tabIndex>0) {var tags = tagsToFind.split(';'); tagsOuterLoop: for (var i=0;tags.length;i++) {elementsByTag = document.getElementsByTagName(tags[i]); for (var j=0;j-1) {if (tempEle.tabIndex>0) {tabOrder[tempEle.tabIndex] = tempEle} else {unordered[unordered.length] = tempEle} } elementArrays(tempEle); } } }; elementArrays(document.body); while (tabOrder.length>0 && tabOrder[0]==null) {tabOrder.shift();} return tabOrder.concat(unordered); }; var tabSequenced = orderElements(); // find the current element in tabIndex ordered array // and set focus to the next element (or the first if // the current is the last) for (var i=0;i cal.weekNumberBaseDay)?7:0)); // The first Base Day in the year var firstBaseDay = new Date(inDateWeekBase.getFullYear(),0,1); firstBaseDay.setDate(firstBaseDay.getDate() - firstBaseDay.getDay() + cal.weekNumberBaseDay); if (firstBaseDayfirstBaseDay) {startWeekOne.setDate(startWeekOne.getDate()-7);} // Subtract the date of the current week from the date of the first week of the year to // get the number of weeks in milliseconds. Divide by the number of milliseconds in a // week then round to no decimals in order to remove the effect of daylight saving. Add // one to make the first week, week 1. Place a string zero on the front so that week // numbers are zero filled. var weekNo = '0'+(Math.round((inDateWeekBase - firstBaseDay)/604800000,0)+1); // Return the last two characters in the week number string return weekNo.substring(weekNo.length-2,weekNo.length); }; // walk the DOM to display the dates. var cells = getEl(calId+'Cells').childNodes; for (var i=0;i (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours())) ) )?'hidden':'inherit'; // Disable if the outOfRangeDisable option has been set and the current date // is out of range or the cal.valuesEnabled option is true. var disabled = cal.valuesEnabled; if ((cal.outOfRangeDisable && (showDate < (new Date(cal.baseYear,0,1,12)) || showDate > (new Date(cal.baseYear+cal.dropDownYears,0,0,12)) ) ) || (cal.outOfMonthDisable && (showDate < (new Date(showDate.getFullYear(),curMonth,1,showDate.getHours())) || showDate > (new Date(showDate.getFullYear(),curMonth+1,0,showDate.getHours())) ) ) ) {disabled = true;} else {if ((cal.days.join().search(((j-1+(7*(i*cells.length/6))+cal.weekStart)%7))>-1) || !cal.dayCells[j-1+(7*((i*cells.length)/6))] ) {disabled = !cal.valuesEnabled;} // Set (Disable or Enable) if the day is passed as a parameter of JACS.show else {for (var k=0;k= cal.dates[k][0].valueOf() && compareDateValue <= cal.dates[k][1].valueOf() ) ) ) {disabled = !cal.valuesEnabled; break; } } } } if (disabled) {rows.childNodes[j].onclick = null; if (getEl('jacsIE')) {rows.childNodes[j].onmouseover = null; rows.childNodes[j].onmouseout = null; } cell.className= (showDate.getMonth()!=curMonth) ?'jacsCellsExMonthDisabled' :(cal.fullInputDate && compareDateValue== cal.seedDate.valueOf()) ?'jacsInputDateDisabled' :(showDate.getDay()%6==0) ?'jacsCellsWeekendDisabled' :'jacsCellsDisabled'; cell.style.borderColor = (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString()) ?cal.todayCellBorderColour :(cell.currentStyle) ?cell.currentStyle['backgroundColor'] :(document.defaultView.getComputedStyle) ?document.defaultView.getComputedStyle(cell,null).backgroundColor :''; } else {function cellOutput(evt) {var ele = eventTrigger(evt), outputDate = new Date(startDate); if (ele.nodeType==3) ele=ele.parentNode; outputDate.setDate(startDate.getDate() + parseInt(ele.id.substr(calId.length+5),10)); setOutput(outputDate,calId); }; if (cal.active) {rows.childNodes[j].onclick=cellOutput;} if (getEl('jacsIE')) {rows.childNodes[j].onmouseover = changeClass; rows.childNodes[j].onmouseout = changeClass; } var highlighted = false; for (var k=0;k= cal.highlightDates[k][0].valueOf() && compareDateValue <= cal.highlightDates[k][1].valueOf() ) ) ) {highlighted = true; break; } } cell.className= (showDate.getMonth()!=curMonth) ?'jacsCellsExMonth' :(cal.fullInputDate && compareDateValue== cal.seedDate.valueOf()) ?'jacsInputDate' :(showDate.getDay()%6==0) ?(highlighted)?'jacsCellsHighlightedWeekend':'jacsCellsWeekend' :(highlighted)?'jacsCellsHighlighted':'jacsCells'; cell.style.borderColor = (cal.formatTodayCell && showDate.toDateString()==dateNow.toDateString()) ?cal.todayCellBorderColour :(cell.currentStyle) ?cell.currentStyle['backgroundColor'] :(document.defaultView.getComputedStyle) ?document.defaultView.getComputedStyle(cell,null).backgroundColor :''; } showDate.setDate(showDate.getDate()+1); compareDateValue = new Date(showDate.getFullYear(), showDate.getMonth(), showDate.getDate()).valueOf(); } } } } } // Opera has a bug with setting the selected index. // It requires the following work-around to force SELECTs to display correctly. // Also Opera's poor dynamic rendering prior to 9.5 requires // the visibility to be reset to prevent garbage in the calendar // when the displayed month is changed. if (window.opera) {selMonths.style.display = 'inline'; selYears.style.display = 'inline'; cal.style.visibility = 'hidden'; cal.style.visibility = 'inherit'; } }; function hide(instanceID) {if (typeof instanceID=='object') {for (var i=0;i 0) {cal.onNext = cal.arrOnNext.shift(); cal.onNext(); // Explicit null set to prevent closure causing memory leak cal.onNext = null; } } }; function stopPropagation(evt) {if (evt.stopPropagation) {if (evt.target!=evt.currentTarget) {evt.stopPropagation(); evt.preventDefault();}} else {evt.cancelBubble = true;} }; // ********************************* // End of Private Function Library // ********************************* // Start of Public Function Library // ********************************* return {show: function(ele) {// Check the type of any additional parameters. // The optional string parameter is a calendar ID, // Take any remaining parameters as day numbers to be handled // (enabled/disabled) according to the setting of the // calendar's valuesEnabled attribute. // 0 = Sunday through to 6 = Saturday. if (typeof arguments[1]=='object') {var dynamic = true; if (typeof arguments[2]=='string') {var calId = arguments[2], min = 3;} else {var calId = 'jacs', min = 2;} // Stop the click event that opens the calendar // from bubbling up to the document-level event // handler that hides it! var source = arguments[1]; if (!source) {source = window.event;} if (source.tagName) // Second parameter isn't an event it's an element {var sourceEle = source; if (getEl('jacsIE')) {window.event.cancelBubble = true;} else {sourceEle.parentNode.addEventListener('click',stopPropagation,false);} } else // Second parameter is an event {var event = source; // Stop the click event that opens the calendar from bubbling up to // the document-level event handler that hides it! var sourceEle = (event.target)?event.target:event.srcElement; if (event.stopPropagation) {event.stopPropagation();} else {event.cancelBubble = true;} } } else {var sourceEle = ele, dynamic = false; if (typeof arguments[1]=='string') {var calId = arguments[1], min = 2;} else {var calId = 'jacs', min = 1;} } // Add event handlers to the return element and its parent. // This helps the script to support tab sequences and focus events. if (document.addEventListener) {ele.addEventListener('keydown',hideOnTab,false); ele.parentNode.addEventListener('click',stopPropagation,false);} else {ele.attachEvent('onkeydown',hideOnTab); if (ele.parentNode!=document.body) {ele.parentNode.attachEvent('onclick',stopPropagation);} } function hideOnTab(evt) {if (!evt) {var evt = window.event;} if ((evt.keyCode||evt.which)==9) {hide(calId);} }; // Create the calendar structure. One is enough unless you want more // than one calendar visible on the page at one time. If you DO need // more, you can create as many as you like but each must have a unique // ID. // The first parameter of JACS.make is the ID of the calendar. The // second is a boolean that determines whether the calendar is to be // static on the page (assigned to a single input field and always // visible) or dynamic (shown and hidden on events and can be assigned // to any number of input fields). if (!getEl(calId)) {JACS.make(calId,dynamic);} cal = getEl(calId); // If the calendar has been triggered using an onfocus event, // and the script actively returns the focus to the target // element (i.e. when cal.onBlurMoveNext = false). We need // to kill the event. if (event) {if (event.type == 'focus' && cal.dateReturned && !cal.onBlurMoveNext && cal.prevEventType == 'focus') {stopPropagation(event); cal.prevEventType = ''; cal.dateReturned = false; return false;} cal.prevEventType = event.type; } if (cal.style.visibility != 'hidden' && cal.style.visibility != 'inherit' && typeof doNext == 'function') {doNext(cal);} cal.triggerEle = sourceEle; cal.dateReturned = false; cal.activeToday = true; // Set enabled/disabled days if (arguments.length==min) {cal.days.length=0;} else {selectedDays = (typeof arguments[min]=='object')?arguments[min]:arguments; for (var i=(min|0);i 0) {cal.triggerEle.textNode = childNodes[i]; cal.triggerEle.len = childNodes[i].nodeValue.length; break; } } } } } // Set the year range var yearOptions = getEl(calId+'Years').options; if (yearOptions.length==0 || yearOptions[0].value!=cal.baseYear) {yearOptions.length = 0; for (var i=0;ical.seedDate ) {cal.seedDate = new Date(cal.baseYear+Math.floor(cal.dropDownYears / 2), 5, 1);} } else {function inputFormat() {var seed = new Array(), input = dateValue.split(new RegExp('[\\'+cal.delimiters.join('\\')+']+','g')); // "Escape" all the user defined date delimiters above - // several delimiters will need it and it does no harm for // the others. // Strip any empty array elements (caused by delimiters) // from the beginning or end of the array. They will // still appear in the output string if in the output // format. if (input[0]!=null) {if (input[0].length==0) {input.splice(0,1);} if (input[input.length-1].length==0) {input.splice(input.length-1,1);} } cal.fullInputDate = false; cal.dateFormat = cal.dateFormat.toUpperCase(); // List all the allowed letters in the date format var template = ['D','M','Y']; // Prepare the sequence of date input elements var result = new Array(); for (var i=0;i-1) {result[cal.dateFormat.search(template[i])] = template[i];} } cal.dateSequence = result.join(''); // Separate the elements of the date input switch (input.length) {case 1: {// Year only entry or undelimited date format if (cal.dateFormat.indexOf('Y')>-1 && input[0].length>cal.dateFormat.lastIndexOf('Y')) {seed[0] = parseInt(input[0].substring(cal.dateFormat.indexOf('Y'), cal.dateFormat.lastIndexOf('Y')+1),10); } else {seed[0] = parseInt(input[0],10);} if (cal.dateFormat.indexOf('M')>-1 && input[0].length>cal.dateFormat.lastIndexOf('M')) {seed[1] = input[0].substring(cal.dateFormat.indexOf('M'), cal.dateFormat.lastIndexOf('M')+1); } else {seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6';} if (cal.dateFormat.indexOf('D')>-1 && input[0].length>cal.dateFormat.lastIndexOf('D')) {seed[2] = parseInt(input[0].substring(cal.dateFormat.indexOf('D'), cal.dateFormat.lastIndexOf('D')+1),10); } else {seed[2] = 1;} if (input[0].length==cal.dateFormat.length) {cal.fullInputDate = true;} break; } case 2: {// Year and Month entry seed[0] = parseInt(input[cal.dateSequence.replace(/D/i,'').search(/Y/i)],10); // Year seed[1] = input[cal.dateSequence.replace(/D/i,'').search(/M/i)]; // Month seed[2] = 1; // Day break; } case 3: {// Day Month and Year entry seed[0] = parseInt(input[cal.dateSequence.search(/Y/i)],10); // Year seed[1] = input[cal.dateSequence.search(/M/i)]; // Month seed[2] = parseInt(input[cal.dateSequence.search(/D/i)],10); // Day cal.fullInputDate = true; break; } default: {// A stuff-up has led to more than three elements in the date. seed[0] = 0; // Year seed[1] = 0; // Month seed[2] = 0; // Day } } // These regular expressions validate the input date format // to the following rules; // Day 1-31 (optional zero on single digits) // Month 1-12 (optional zero on single digits) // or case insensitive name // Year One, Two or four digits // Months names are as set in the language-dependent // definitions and delimiters are set just below there var expValDay = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])$'), expValMonth = new RegExp('^(0?[1-9]|1[0-2]|'+cal.monthNames.join('|')+')$','i'), expValYear = new RegExp('^([0-9]{1,2}|[0-9]{4})$'); // Apply validation and report failures if (expValYear.exec(seed[0]) ==null || expValMonth.exec(seed[1])==null || expValDay.exec(seed[2]) ==null ) {if (cal.showInvalidDateMsg) {alert(cal.invalidDateMsg + cal.invalidAlert[0] + dateValue + cal.invalidAlert[1]);} seed[0] = cal.baseYear + Math.floor(cal.dropDownYears/2); // Year seed[1] = cal.defaultToCurrentMonth?(dateNow.getMonth()+1).toString():'6'; // Month seed[2] = 1; // Day cal.fullInputDate = false; } // Return the Year in seed[0] // Month in seed[1] // Day in seed[2] return seed; }; // Parse the string into an array using the allowed delimiters seedDate = inputFormat(); // So now we have the Year, Month and Day in an array. // If the year is one or 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 (seedDate[0]<100) {seedDate[0] += (seedDate[0]>50)?1900:2000;} // Check whether the month is in digits or an abbreviation if (seedDate[1].search(/\d+/)<0) {for (i=0;ical.seedDate) {if (cal.strict && cal.showOutOfRangeMsg) {alert(cal.outOfRangeMsg);} cal.seedDate = new Date(cal.baseYear,0,1); cal.fullInputDate=false; } else {if ((new Date(cal.baseYear+cal.dropDownYears,0,0))cal.dates[i][1])) {cal.dates[i].reverse();} } else {if (cal.showRangeSettingError) {alert(cal.dateSettingError[0] + cal.dates[i] + cal.dateSettingError[1]);} } } } // Set language-dependent values getEl(calId+'DragText').innerHTML = cal.drag; var monthOptions = getEl(calId+'Months').options, months = ''; if (monthOptions.length>0) {for (var i=0;imonthOptions.length-1) {monthOptions[i] = new Option(cal.monthNames[i],cal.monthNames[i]);} else {monthOptions[i].innerHTML = cal.monthNames[i];} } } for (var i=0;i dateNow && (new Date(cal.baseYear, 0, 0)) < dateNow) || (cal.clearButton && (ele.readOnly || ele.disabled)) ) {getEl(calId+'Now').innerHTML = cal.today+' '+dateNow.jacsFormat(cal.dateDisplayFormat,cal.monthNames); getEl(calId+'ClearButton').value = cal.clear; getEl(calId+'Foot').style.display = ''; if ((new Date(cal.baseYear + cal.dropDownYears, 0, 0)) > dateNow && (new Date(cal.baseYear, 0, 0)) < dateNow) {getEl(calId+'Now').style.display = ''; if (cal.clearButton && (ele.readOnly || ele.disabled)) {getEl(calId+'Clear').style.display = ''; getEl(calId+'Clear').style.textAlign = 'left'; getEl(calId+'Now' ).style.textAlign = 'right'; } else {getEl(calId+'Clear').style.display = 'none'; getEl(calId+'Now' ).style.textAlign = 'center'; } } else {getEl(calId+'Clear').style.textAlign = 'center'; getEl(calId+'Clear').style.display = ''; getEl(calId+'Now' ).style.display = 'none'; } } else {getEl(calId+'Foot').style.display = 'none';} // Calculate the number of months that the entered (or // defaulted) month is after the start of the allowed // date range. cal.monthSum = 12*(cal.seedDate.getFullYear() - cal.baseYear) + cal.seedDate.getMonth(); // Set the drop down boxes. getEl(calId+'Years').options.selectedIndex = Math.floor(cal.monthSum/12); getEl(calId+'Months').options.selectedIndex = (cal.monthSum%12); getEl(calId).ele = ele; // Display the month showMonth(0,calId); // Remember the Element cal.targetEle = ele; // Position the calendar box. if (dynamic) {// Check whether or not dragging is allowed and display drag handle if necessary getEl(calId+'Drag').style.display = (cal.allowDrag)?'':'none'; var offsetTop = parseInt(ele.offsetTop ,10), offsetLeft = parseInt(ele.offsetLeft,10); // The object sniffing for Opera allows for the fact that Opera // is the only major browser that correctly reports the position // of an element in a scrollable DIV. This is because IE and // Firefox omit the DIV from the offsetParent tree. if (!window.opera) {while (ele.tagName!='BODY' && ele.tagName!='HTML') {offsetTop -= parseInt(ele.scrollTop, 10); offsetLeft -= parseInt(ele.scrollLeft,10); ele = ele.parentNode; } ele = cal.targetEle; } while (ele.tagName!='BODY' && ele.tagName!='HTML') {ele = ele.offsetParent; offsetTop += parseInt(ele.offsetTop, 10); offsetLeft += parseInt(ele.offsetLeft,10); } ele = cal.targetEle; var eleOffsetTop = offsetTop, eleOffsetLeft = offsetLeft; if (cal.xBase.length>0) {if (isNaN(cal.xBase)) {cal.xBase = cal.xBase.toUpperCase(); offsetLeft += (cal.xBase=='R') ?parseInt(ele.offsetWidth,10) :(cal.xBase=='M')?Math.round(parseInt(ele.offsetWidth,10)/2):0; } else {offsetLeft += parseInt(cal.xBase,10);} } if (cal.yBase.length>0) {if (isNaN(cal.yBase)) {cal.yBase = cal.yBase.toUpperCase(); offsetTop += (cal.yBase=='B') ?parseInt(ele.offsetHeight,10) :(cal.yBase=='M')?Math.round(parseInt(ele.offsetHeight,10)/2):0; } else {offsetTop += parseInt(cal.yBase,10);} } else {offsetTop += parseInt(ele.offsetHeight,10);} if (cal.xPosition.length>0) {if (isNaN(cal.xPosition)) {cal.xPosition = cal.xPosition.toUpperCase(); offsetLeft -= (cal.xPosition=='R') ?parseInt(cal.offsetWidth,10) :(cal.xPosition=='M')?Math.round(parseInt(cal.offsetWidth,10)/2):0; } else {offsetLeft += parseInt(cal.xPosition,10);} } if (cal.yPosition.length>0) {if (isNaN(cal.yPosition)) {cal.yPosition = cal.yPosition.toUpperCase(); offsetTop -= (cal.yPosition=='B') ?parseInt(cal.offsetHeight,10) :(cal.yPosition=='M')?Math.round((parseInt(cal.offsetHeight,10))/2):0; } else {offsetTop += parseInt(cal.yPosition,10);} } if (cal.autoPosition) {var width = parseInt(cal.offsetWidth, 10), height = parseInt(cal.offsetHeight,10), windowLeft = (document.body && document.body.scrollLeft) ?document.body.scrollLeft //DOM compliant :(document.documentElement && document.documentElement.scrollLeft) ?document.documentElement.scrollLeft //IE6+ standards compliant :0, //Failed windowWidth = (typeof(innerWidth) == 'number') ?innerWidth //DOM compliant :(document.documentElement && document.documentElement.clientWidth) ?document.documentElement.clientWidth //IE6+ standards compliant :(document.body && document.body.clientWidth) ?document.body.clientWidth //IE non-compliant :0, //Failed windowTop = (document.body && document.body.scrollTop) ?document.body.scrollTop //DOM compliant :(document.documentElement && document.documentElement.scrollTop) ?document.documentElement.scrollTop //IE6+ standards compliant :0, //Failed windowHeight = (typeof(innerHeight) == 'number') ?innerHeight //DOM compliant :(document.documentElement && document.documentElement.clientHeight) ?document.documentElement.clientHeight //IE6+ standards compliant :(document.body && document.body.clientHeight) ?document.body.clientHeight //IE non-compliant :0; //Failed if (eleOffsetLeft + parseInt(ele.offsetWidth,10) - width >= windowLeft && offsetLeft + width > windowLeft + windowWidth ) {offsetLeft = eleOffsetLeft + parseInt(ele.offsetWidth,10) - width;} else if (eleOffsetLeft >= windowLeft && offsetLeft < windowLeft ) {offsetLeft = eleOffsetLeft;} if (eleOffsetTop - height >= windowTop && offsetTop + height > windowTop + windowHeight ) {offsetTop = eleOffsetTop - height;} else if (offsetTop + height <= windowTop + windowHeight && offsetTop < windowTop) {offsetTop = eleOffsetTop + parseInt(ele.offsetHeight,10);} } cal.style.top = offsetTop+'px'; cal.style.left = offsetLeft+'px'; getEl(calId+'Iframe').style.top = offsetTop +'px'; getEl(calId+'Iframe').style.left = offsetLeft+'px'; getEl(calId+'Iframe').style.width = (cal.offsetWidth -(getEl('jacsIE')?2:4))+'px'; getEl(calId+'Iframe').style.height = (cal.offsetHeight-(getEl('jacsIE')?2:4))+'px'; getEl(calId+'Iframe').style.visibility = 'inherit'; } // Show it on the page cal.style.visibility = 'inherit'; }, make: function (calId) {cals.push(calId); var dynamic = (typeof arguments[1]=='boolean')?arguments[1]:true; TABLEjacs = document.createElement('table'); TABLEjacs.id = calId; TABLEjacs.dynamic = dynamic; TABLEjacs.className = (dynamic)?'jacs':TABLEjacs; calAttributes(TABLEjacs); if (dynamic) {TABLEjacs.style.zIndex = TABLEjacs.zIndex+1;} function cancel(evt) {if (TABLEjacs.clickToHide) {hide(calId);} stopPropagation(evt); }; TBODYjacs = document.createElement('tbody'); TRjacs1 = document.createElement('tr'); TRjacs1.className = 'jacs'; TDjacs1 = document.createElement('td'); TDjacs1.className = 'jacs'; TABLEjacsHead = document.createElement('table'); TABLEjacsHead.id = calId+'Head'; TABLEjacsHead.cellSpacing = '0'; TABLEjacsHead.cellPadding = '0'; TABLEjacsHead.className = 'jacsHead'; TABLEjacsHead.width = '100%'; TBODYjacsHead = document.createElement('tbody'); TRjacsDrag = document.createElement('tr'); TRjacsDrag.id = calId+'Drag'; TRjacsDrag.style.display = 'none'; TDjacsDrag = document.createElement('td'); TDjacsDrag.className = 'jacsDrag'; TDjacsDrag.colSpan = '4'; function beginDrag(evt) {var elToDrag = getEl(calId); var deltaX = evt.clientX, deltaY = evt.clientY, offsetEle = elToDrag; while (offsetEle.tagName!='BODY' && offsetEle.tagName!='HTML') {deltaX -= parseInt(offsetEle.offsetLeft,10); deltaY -= parseInt(offsetEle.offsetTop ,10); offsetEle = offsetEle.offsetParent; } if (document.addEventListener) {elToDrag.addEventListener('mousemove',moveHandler,true); elToDrag.addEventListener('mouseup', upHandler,true); } else {elToDrag.attachEvent('onmousemove', moveHandler); elToDrag.attachEvent('onmouseup', upHandler); elToDrag.setCapture(); } stopPropagation(evt); function moveHandler(evt) {if (!evt) {evt = window.event;} elToDrag.style.left = (evt.clientX-deltaX)+'px'; elToDrag.style.top = (evt.clientY-deltaY)+'px'; getEl(calId+'Iframe').style.left = (evt.clientX-deltaX)+'px'; getEl(calId+'Iframe').style.top = (evt.clientY-deltaY)+'px'; stopPropagation(evt); }; function upHandler(evt) {if (!evt) {evt = window.event;} if (document.removeEventListener) {elToDrag.removeEventListener('mousemove',moveHandler,true); elToDrag.removeEventListener( 'mouseup', upHandler,true); } else {elToDrag.detachEvent('onmouseup', upHandler); elToDrag.detachEvent('onmousemove',moveHandler); elToDrag.releaseCapture(); } stopPropagation(evt); }; }; DIVjacsDragText = document.createElement('span'); DIVjacsDragText.id = calId+'DragText'; TRjacsHead = document.createElement('tr'); TRjacsHead.className = 'jacsHead'; TDjacsHead1 = document.createElement('td'); TDjacsHead1.className = 'jacsHead'; INPUTjacsHead1 = document.createElement('input'); INPUTjacsHead1.className = 'jacsHead'; INPUTjacsHead1.id = calId+'HeadLeft'; INPUTjacsHead1.type = 'button'; INPUTjacsHead1.tabIndex = '-1'; INPUTjacsHead1.value = '<'; INPUTjacsHead1.onclick = function() {showMonth(-1,calId);} TDjacsHead2 = document.createElement('td'); TDjacsHead2.className = 'jacsHead'; SELECTjacsHead2 = document.createElement('select'); SELECTjacsHead2.className = 'jacsHead'; SELECTjacsHead2.id = calId+'Months'; SELECTjacsHead2.tabIndex = '-1'; SELECTjacsHead2.onchange = function() {showMonth(0,calId);} TDjacsHead3 = document.createElement('td'); TDjacsHead3.className = 'jacsHead'; SELECTjacsHead3 = document.createElement('select'); SELECTjacsHead3.className = 'jacsHead'; SELECTjacsHead3.id = calId+'Years'; SELECTjacsHead3.tabIndex = '-1'; SELECTjacsHead3.onchange = function() {showMonth(0,calId);} TDjacsHead4 = document.createElement('td'); TDjacsHead4.className = 'jacsHead'; INPUTjacsHead4 = document.createElement('input'); INPUTjacsHead4.className = 'jacsHead'; INPUTjacsHead4.id = calId+'HeadRight'; INPUTjacsHead4.type = 'button'; INPUTjacsHead4.tabIndex = '-1'; INPUTjacsHead4.value = '>'; INPUTjacsHead4.onclick = function() {showMonth(1,calId);} TRjacs2 = document.createElement('tr'); TRjacs2.className = 'jacs'; TDjacs2 = document.createElement('td'); TDjacs2.className = 'jacs'; TABLEjacsCells = document.createElement('table'); TABLEjacsCells.className = 'jacsCells'; TABLEjacsCells.align = 'center'; TABLEjacsCells.width = '100%'; THEADjacsCells = document.createElement('thead'); TRjacsCells = document.createElement('tr'); TDjacsCells = document.createElement('td'); TDjacsCells.className = 'jacsWeekNumberHead'; TDjacsCells.id = calId+'Week_'; TABLEjacs.appendChild(TBODYjacs); TBODYjacs.appendChild(TRjacs1); TRjacs1.appendChild(TDjacs1); TDjacs1.appendChild(TABLEjacsHead); TABLEjacsHead.appendChild(TBODYjacsHead); TBODYjacsHead.appendChild(TRjacsDrag); TRjacsDrag.appendChild(TDjacsDrag); TDjacsDrag.appendChild(DIVjacsDragText); TBODYjacsHead.appendChild(TRjacsHead); TRjacsHead.appendChild(TDjacsHead1); TDjacsHead1.appendChild(INPUTjacsHead1); TRjacsHead.appendChild(TDjacsHead2); TDjacsHead2.appendChild(SELECTjacsHead2); TRjacsHead.appendChild(TDjacsHead3); TDjacsHead3.appendChild(SELECTjacsHead3); TRjacsHead.appendChild(TDjacsHead4); TDjacsHead4.appendChild(INPUTjacsHead4); TBODYjacs.appendChild(TRjacs2); TRjacs2.appendChild(TDjacs2); TDjacs2.appendChild(TABLEjacsCells); TABLEjacsCells.appendChild(THEADjacsCells); THEADjacsCells.appendChild(TRjacsCells); TRjacsCells.appendChild(TDjacsCells); for (var i=0;i<7;i++) {TDjacsCells = document.createElement('td'); TDjacsCells.className = 'jacsWeek'; TDjacsCells.id = calId+'WeekInit'+i; TRjacsCells.appendChild(TDjacsCells); } TBODYjacsCells = document.createElement('tbody'); TBODYjacsCells.id = calId+'Cells'; TABLEjacsCells.appendChild(TBODYjacsCells); for (var i=0;i<6;i++) {TRjacsCells = document.createElement('tr'); TBODYjacsCells.appendChild(TRjacsCells); TDjacsCells = document.createElement('td'); TDjacsCells.className = 'jacsWeekNo'; TDjacsCells.id = calId+'Week_'+i; TRjacsCells.appendChild(TDjacsCells); for (var j=0;j<7;j++) {TDjacsCells = document.createElement('td'); TDjacsCells.className = 'jacsCells'; TDjacsCells.id = calId+'Cell_'+(j+(i*7)); TRjacsCells.appendChild(TDjacsCells); } } TFOOTjacsFoot = document.createElement('tfoot'); TABLEjacsCells.appendChild(TFOOTjacsFoot); TRjacsFoot = document.createElement('tr'); TRjacsFoot.id = calId+'Foot'; TFOOTjacsFoot.appendChild(TRjacsFoot); TDjacsFoot = document.createElement('td'); TDjacsFoot.colSpan = '8'; TDjacsFoot.style.padding = '0px'; TRjacsFoot.appendChild(TDjacsFoot); TABLEjacsFootDetail = document.createElement('table'); TABLEjacsFootDetail.style.width = '100%'; TABLEjacsFootDetail.cellSpacing = '0'; TABLEjacsFootDetail.cellPadding = '0'; TDjacsFoot.appendChild(TABLEjacsFootDetail); TBODYjacsFootDetail = document.createElement('tbody'); TABLEjacsFootDetail.appendChild(TBODYjacsFootDetail); TRjacsFootDetail = document.createElement('tr'); TBODYjacsFootDetail.appendChild(TRjacsFootDetail); TDjacsFootDetail = document.createElement('td'); TDjacsFootDetail.className = 'jacsClear'; TDjacsFootDetail.id = calId+'Clear'; TDjacsFootDetail.style.padding = '0px'; TRjacsFootDetail.appendChild(TDjacsFootDetail); INPUTjacsClearButton = document.createElement('input'); INPUTjacsClearButton.type = 'button'; INPUTjacsClearButton.id = calId+'ClearButton'; INPUTjacsClearButton.className = 'Clear'; INPUTjacsClearButton.style.textAlign = 'center'; INPUTjacsClearButton.onclick = function() {cal.targetEle.value='';hide(calId);}; TDjacsFootDetail.appendChild(INPUTjacsClearButton); TDjacsNow = document.createElement('td'); TDjacsNow.className = 'jacsNow'; TDjacsNow.id = calId+'Now'; TDjacsNow.style.padding = '0px'; TRjacsFootDetail.appendChild(TDjacsNow); if (TABLEjacs.clickToHide) {if (document.addEventListener) { TABLEjacs.addEventListener('click', cancel, false); TABLEjacs.addEventListener('change', cancel, false); TDjacsDrag.addEventListener('mousedown',beginDrag, false); INPUTjacsHead1.addEventListener('click', stopPropagation,false); SELECTjacsHead2.addEventListener('click', stopPropagation,false); SELECTjacsHead2.addEventListener('change', stopPropagation,false); SELECTjacsHead3.addEventListener('click', stopPropagation,false); SELECTjacsHead3.addEventListener('change', stopPropagation,false); INPUTjacsHead4.addEventListener('click', stopPropagation,false); TBODYjacsCells.addEventListener('click', stopPropagation,false); } else { TABLEjacs.attachEvent('onclick', cancel); TABLEjacs.attachEvent('onchange', cancel); TDjacsDrag.attachEvent('onmousedown',beginDrag); INPUTjacsHead1.attachEvent('onclick', stopPropagation); SELECTjacsHead2.attachEvent('onclick', stopPropagation); SELECTjacsHead2.attachEvent('onchange', stopPropagation); SELECTjacsHead3.attachEvent('onclick', stopPropagation); SELECTjacsHead3.attachEvent('onchange', stopPropagation); INPUTjacsHead4.attachEvent('onclick', stopPropagation); TBODYjacsCells.attachEvent('onclick', stopPropagation); } } else {if (document.addEventListener) { TABLEjacs.addEventListener('click', stopPropagation,false); TABLEjacs.addEventListener('change', stopPropagation,false); TDjacsDrag.addEventListener('mousedown',beginDrag, false); } else { TABLEjacs.attachEvent('onclick', stopPropagation); TABLEjacs.attachEvent('onchange', stopPropagation); TDjacsDrag.attachEvent('onmousedown',beginDrag); } } if (dynamic) {iFrame = document.createElement('iframe'); iFrame.className = 'jacs'; iFrame.id = calId+'Iframe'; if (getEl('jacsIElt7')) {iFrame.src = '/jacsblank.html';} iFrame.name = 'jacsIframe'; iFrame.frameborder = '0'; iFrame.style.zIndex = TABLEjacs.zIndex; document.body.insertBefore(iFrame, document.body.firstChild); document.body.insertBefore(TABLEjacs, iFrame); } else {if (!getEl('jacsSpan'+calId)) {document.writeln("");} getEl('jacsSpan'+calId).appendChild(TABLEjacs); } }, cals: function () {return cals;}, next: function () {if (typeof arguments[0]=='string') {calID = arguments[0]; inFunc = arguments[1]; argPosition = 2; } else {calID = 'jacs'; inFunc = arguments[0]; argPosition = 1; } if (getEl(calID)) {// Take the arguments to be passed through to the defined function. var args = new Array(); for (var i=argPosition;i> does not exist.\n' + 'Please check that the calendar object id is correct\n' + 'and that JACS.show is called before JACS.next.'); } } }; }; // ****************************** // End of Public Function Library // ****************************************************** // End of Javascript Advanced Calendar Script (JACS) Code // ******************************************************