'_visable'/** * Filename.......: calendar.js * Project........: Popup Calendar * Last Modified..: $Date: 2002/07/22 18:17:05 $ * CVS Revision...: $Revision: 1.2 $ * Copyright......: 2001, 2002 Richard Heyes */ var dynCalendar_instances = new Array(); var dynCalendar_instance = false; /** * Global variables */ var dynCalendar_mouseoverStatus = false; var dynCalendar_mouseX = 0; var dynCalendar_mouseY = 0; var dynCalendar_cssLoaded = 0; function dynCalendar_onload() { /* write the calendards to the end of the document */ dynCalendar_writeLayers(); /* change the input fields to calendards */ var inputs=document.getElementsByTagName('input'); //alert(inputs.length); for (var t = 0; t < inputs.length; t++) { //alert(inputs[t].attributes['class'].nodeValue); if (!inputs[t].attributes['class'] || inputs[t].attributes['class'].nodeValue != 'dynCalendar') { continue; } //alert("got calendar"); if (!inputs[t].getAttribute('id')) { inputs[t].setAttribute('id', inputs[t].getAttribute('name')); } //alert(inputs[t].getAttribute('id')); dynCalendar_instances[dynCalendar_instances.length] = new dynCalendar( { name: inputs[t].getAttribute('name'), images: inputs[t].getAttribute('calendar:images'), type: inputs[t].getAttribute('calendar:type') ? inputs[t].getAttribute('calendar:type') : 'day' } ); if (!dynCalendar_cssLoaded) { if (!dynCalendar_cssLoaded) { var nextTheme = inputs[t].getAttribute('calendar:images') + '../dynCalendar.css'; try { document.styleSheets[0].addImport(nextTheme); } catch (e) { document.styleSheets[0].insertRule('@import url(' + nextTheme + ');',0); } dynCalendar_cssLoaded = 1; } dynCalendar_cssLoaded = 1; } //alert(inputs[t].getAttribute('calendar:type')); } } /* add a listener for it */ function dynCalendar_addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } } dynCalendar_addLoadEvent(function() { dynCalendar_onload(); }); /** * The calendar constructor * * @access public * @param string key * @param string value * @param string ... repeats for all the possible settings.... * * key : value * 'name' , 'thedate', // name of layer & input field * 'images' , '/templates/javascript/calendar/images/', * 'type' , 'day' // type = day | month | ??year?? */ function dynCalendar(config) { /** * Properties */ // Todays date this.today = new Date(); this.day = this.today.getDate(); this.month = this.today.getMonth(); this.year = this.today.getFullYear(); this.type = 'day'; this.old_onload = false; this.objName = 'unknown'; this.originalName = 'unknown'; this.imagesPath = 'images/'; this.offsetX = 5; this.offsetY = 5; this._x = 0; this._y = 0; this.useMonthCombo = false; this.useYearCombo = false; this.yearComboRange = 5; this.currentMonth = this.month; this.currentYear = this.year; this.currentDay = this.day; this.startMonth = this.month; this.startYear = this.year; this.startDay = this.day; /** * Public Methods */ this.show = dynCalendar_show; this.submit = dynCalendar_submit; this.showStart = dynCalendar_showStart; this.writeHTML = dynCalendar_writeHTML; this.getByName = dynCalendar_getByName; this.setForm = dynCalendar_setForm; // Accessor methods this.setOffset = dynCalendar_setOffset; this.setOffsetX = dynCalendar_setOffsetX; this.setOffsetY = dynCalendar_setOffsetY; this.setImagesPath = dynCalendar_setImagesPath; this.setMonthCombo = dynCalendar_setMonthCombo; this.setYearCombo = dynCalendar_setYearCombo; this.setCurrentMonth = dynCalendar_setCurrentMonth; this.setCurrentYear = dynCalendar_setCurrentYear; this.setYearComboRange = dynCalendar_setYearComboRange; /** * Private methods */ // Layer manipulation this._getLayer = dynCalendar_getLayer; this._hideLayer = dynCalendar_hideLayer; this._showLayer = dynCalendar_showLayer; this._setLayerPosition = dynCalendar_setLayerPosition; this._setHTML = dynCalendar_setHTML; // Miscellaneous this._getDaysInMonth = dynCalendar_getDaysInMonth; this._mouseover = dynCalendar_mouseover; // popups this.showMonthPopup = dynCalendar_showMonthPopup; this.showYearPopup = dynCalendar_showYearPopup; this._setPopupHTML = dynCalendar_setPopupHTML; this._getPopupLayer = dynCalendar_getPopupLayer; this._showPopupLayer = dynCalendar_showPopupLayer; this._hidePopupLayer = dynCalendar_hidePopupLayer; // submit this._submitForm = false; /** * Constructor type code */ this.originalName = config.name; this.imagesPath = config.images; this._submitForm = config.submitForm; dynCalendar_instance = this; this.callbackFunc = 'dynCalendar_instance.setForm'; var start = this.getByName(this.originalName).value; if (start && (start != '')) { var bits = start.split('-'); if (bits.length == 3) { this.currentYear = Number(bits[0]); this.currentMonth = Number(bits[1])-1; this.currentDay = Number(bits[2]); } } //alert(this.currentDay+'/'+this.currentMonth+'/'+this.currentYear); // convert the old input into hidden. //this.getByName(this.objName).type='hidden'; //alert('writeHTML'); this.writeHTML(); this.setForm(this.currentDay,this.currentMonth+1,this.currentYear); } function dynCalendar_showStart(aelement) { var inputs = aelement.getElementsByTagName('input'); var original = inputs[0]; var start = original.value; if (start && (start != '')) { var bits = start.split('-'); dynCalendar_instance.currentYear = dynCalendar_instance.startYear = Number(bits[0]); dynCalendar_instance.currentMonth = dynCalendar_instance.startMonth = Number(bits[1])-1; dynCalendar_instance.currentDay = dynCalendar_instance.startDay = Number(bits[2]); } else { dynCalendar_instance.currentDay = dynCalendar_instance.startDay = dynCalendar_instance.today.getDay(); dynCalendar_instance.currentMonth = dynCalendar_instance.startMonth = dynCalendar_instance.today.getMonth(); dynCalendar_instance.currentYear = dynCalendar_instance.startYear = dynCalendar_instance.today.getFullYear(); } dynCalendar_mouseoverStatus = true; dynCalendar_instance.originalName = original.getAttribute('name'); var images = aelement.getElementsByTagName('img'); dynCalendar_instance.type = original.getAttribute('calendar:type'); dynCalendar_instance._submitForm = original.getAttribute('calendar:submit'); dynCalendar_instance.imgObj = images[0]; //alert(this.originalName ); dynCalendar_instance.show(); } /** * Shows the calendar, or updates the layer if * already visible. * * @access public * @param integer month Optional month number (0-11) * @param integer year Optional year (YYYY format) * @param integer day Optional day (0-31 format) */ function dynCalendar_show() { // Variable declarations to prevent globalisation var day, month, year, monthnames, numdays, thisMonth, firstOfMonth; var ret, row, i, cssClass, linkHTML, previousMonth, previousYear; var nextMonth, nextYear, prevImgHTML, prevLinkHTML, nextImgHTML, nextLinkHTML; var monthComboOptions, monthCombo, yearComboOptions, yearCombo, html; this.currentMonth = month = arguments[0] != null ? arguments[0] : this.currentMonth; this.currentYear = year = arguments[1] != null ? arguments[1] : this.currentYear; this.currentDay = day = arguments[2] != null ? arguments[2] : this.currentDay; monthnames = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); numdays = this._getDaysInMonth(month, year); thisMonth = new Date(year, month, 1); firstOfMonth = thisMonth.getDay(); if (!this._submitForm) { this.setForm(day,month+1,year); } // First few blanks up to first day ret = new Array(new Array()); for(i=0; i numdays) { this.currentDay = day = numdays; } while(i <= numdays){ if(ret[row].length == 7){ ret[++row] = new Array(); } /** * Generate this cells' HTML */ if (this._submitForm) { cssClass = (day == i && month == this.currentMonth && year == this.currentYear) ? 'dynCalendar_today' : 'dynCalendar_day'; linkHTML = '' + (i++) + ''; ret[row][ret[row].length] = '' + linkHTML + ''; } else { cssClass = (i == this.day && month == this.month && year == this.year) ? 'dynCalendar_today' : 'dynCalendar_day'; linkHTML = '' + (i++) + ''; ret[row][ret[row].length] = '' + linkHTML + ''; } } // Format the HTML for(i=0; i 11){ nextMonth = 0; nextYear++; } prevImgHTML = '<<'; prevLinkHTML = '' + prevImgHTML + ''; prevImgHTML = '<<<<'; prevFullLinkHTML = '' + prevImgHTML + ''; nextImgHTML = '>>'; nextLinkHTML = '' + nextImgHTML + ''; nextImgHTML = '>>>>'; nextFullLinkHTML = '' + nextImgHTML + ''; /** * Build month combo */ if (this.useMonthCombo) { monthComboOptions = ''; for (i=0; i<12; i++) { selected = (i == thisMonth.getMonth() ? 'selected="selected"' : ''); monthComboOptions += ''; } monthCombo = ''; } else { monthCombo = '' + monthnames[thisMonth.getMonth()] + ''; } /** * Build year combo */ if (this.useYearCombo) { yearComboOptions = ''; for (i = thisMonth.getFullYear() - this.yearComboRange; i <= (thisMonth.getFullYear() + this.yearComboRange); i++) { selected = (i == thisMonth.getFullYear() ? 'selected="selected"' : ''); yearComboOptions += ''; } yearCombo = ''; } else { yearCombo = // '' + '' + thisMonth.getFullYear() + ''; } html = ''; html += ''; if (this.type == 'day') { html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += '' + ret.join('\n') + ''; } /** * Build OK / Cancel (if get is specified) */ if (this._submitForm) { html += ''; html += ''; html += ''; } html += '
' + prevFullLinkHTML + ' ' + prevLinkHTML + '' + monthCombo + ' ' + yearCombo + '' + nextLinkHTML + ' ' + nextFullLinkHTML + '
SunMonTueWedThuFriSat
'; // OK html += ''; html += ''; html += ''; // Cancel html += ''; html += ''; html += '
 ' + '' + 'OK ' + '' + 'Cancel 
'; this._setHTML(html); this._showLayer(); this._hidePopupLayer(); if (!arguments[0] && !arguments[1]) { this._setLayerPosition(); } } function dynCalendar_showMonthPopup() { html = ''; monthnames = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); for (var i=0;i<12;i++) { // TODO - highlight current... cssClass = (this.currentMonth == i) ? 'dynCalendar_popupSelected' : 'dynCalendar_popup'; html += ''; } html += '
' + '' + monthnames[i] + '
'; this._setPopupHTML(html); this._showPopupLayer(50); this._showLayer(); } function dynCalendar_showYearPopup(year,hideit) { var cssClass; if (this.currentYear == year) { this._hidePopupLayer(); this._showLayer(); return; } if (year != -1) { this.currentYear = year; } this.show(this.currentMonth,this.currentYear) html = ''; var yy0 = this.currentYear.toString().substring(0,2); var yy1 = this.currentYear.toString().substring(2,3); var yy2 = this.currentYear.toString().substring(3,4); html += ''; for (var i=0;i<10;i++) { cssClass = (yy0 == (i+19)) ?'dynCalendar_popupSelected' : 'dynCalendar_popup'; html += ''+ ''; cssClass = (yy1 == i) ? 'dynCalendar_popupSelected' : 'dynCalendar_popup'; html += ''; cssClass = (yy2 == i) ? 'dynCalendar_popupSelected' : 'dynCalendar_popup'; html += '' + ''; } html += '
'+ '' + this.currentYear+ '
' + ((i < 2) ? '' + (i+19) + '' : ' ' ) + '' + '' + i + '' + '' + i + '
'; this._setPopupHTML(html); if (!hideit) { this._showPopupLayer(100); } this._showLayer(); } function dynCalendar_getPopupLayer() { var layerID = '_dynCalendarPopupMonth'; if (document.getElementById(layerID)) { return document.getElementById(layerID); } alert('can not find:' + layerID); } function dynCalendar_setPopupHTML(html) { this._getPopupLayer().innerHTML = html; } function dynCalendar_showPopupLayer(offset) { this._getPopupLayer().style.top = this._y + 'px'; this._getPopupLayer().style.left = (this._x + offset) + 'px'; this._getPopupLayer().style.visibility = 'visible'; } function dynCalendar_hidePopupLayer() { dynCalendar_getPopupLayer().style.visibility = 'hidden'; } function dynCalendar_getByName(name) { if (document.getElementById(name)) { return document.getElementById(name); } alert("can not find " + name); } function dynCalendar_setForm(day,month,year) { // assigns in ISO standard to the named object.. // then assigns in Human readable to the displayed version... if (this.type == 'day') { this.getByName(this.originalName).value = year + '-' + month + '-' + day; monthnames = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'); this.getByName('dyncalendar_visable_' + this.originalName).value = day + ' ' + monthnames[month-1] + ' ' + year; } else { this.getByName(this.originalName).value = year + '-' + month; monthnames = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'); this.getByName('dyncalendar_visable_' + this.originalName).value = monthnames[month-1] + ' ' + year; } } function dynCalendar_submit() { if (!this._submitForm) { // oops. } this.setForm(this.currentDay,this.currentMonth + 1,this.currentYear); this.getByName(this.originalName).form.submit(); } /** * Modifies input entries for calendar buttons * * @access public */ function dynCalendar_writeHTML() { var add_span = document.createElement("SPAN"); var add_link = document.createElement("A"); add_link.setAttribute('href','javascript: var _tmp="";'); var add_input = document.createElement("INPUT"); add_input.size = 12; add_input.name = 'dyncalendar_visable_' + this.originalName ; add_input.id = 'dyncalendar_visable_' + this.originalName ; var add_img = document.createElement("IMG"); this.imgObj = add_img; add_img.src = this.imagesPath + 'dynCalendar.gif'; add_img.border = 0; add_img.height = 16; add_img.width = 16; var org_input = this.getByName(this.originalName); var add_input_org = org_input.cloneNode(1); add_input_org.type = 'hidden'; add_link.appendChild(add_input_org); add_link.appendChild(add_input); add_link.appendChild(add_img); add_span.appendChild(add_link); org_input.parentNode.replaceChild(add_span,org_input); add_input.readOnly = true; //var target = is_ie5up ? 'event.srcElement' : 'arguments[0].target'; add_img.onclick = add_input.onclick = new Function('try { '+ 'dynCalendar_instance.showStart( event.srcElement.parentNode); ' + ' } catch (e) { ' + 'dynCalendar_instance.showStart( arguments[0].target.parentNode); ' + '}'); } /** * Writes HTML to document for layer * * @access public */ function dynCalendar_writeLayers() { var add_div1 = document.createElement("DIV"); add_div1.className = "dynCalendar"; add_div1.id = "_dynCalendarPopupFull" add_div1.onmouseover = new Function ('dynCalendar_mouseover(true)'); add_div1.onmouseout= new Function ('dynCalendar_mouseover(false)'); var add_div2 = document.createElement("DIV"); add_div2.className = "dynCalendarPopup" add_div2.id = "_dynCalendarPopupMonth" add_div2.onmouseover = new Function ('dynCalendar_mouseover(true)'); add_div2.onmouseout= new Function ('dynCalendar_mouseover(false)'); document.body.appendChild(add_div1); document.body.appendChild(add_div2); } /** * Sets the offset to the mouse position * that the calendar appears at. * * @access public * @param integer Xoffset Number of pixels for vertical * offset from mouse position * @param integer Yoffset Number of pixels for horizontal * offset from mouse position */ function dynCalendar_setOffset(Xoffset, Yoffset) { this.setOffsetX(Xoffset); this.setOffsetY(Yoffset); } /** * Sets the X offset to the mouse position * that the calendar appears at. * * @access public * @param integer Xoffset Number of pixels for horizontal * offset from mouse position */ function dynCalendar_setOffsetX(Xoffset) { this.offsetX = Xoffset; } /** * Sets the Y offset to the mouse position * that the calendar appears at. * * @access public * @param integer Yoffset Number of pixels for vertical * offset from mouse position */ function dynCalendar_setOffsetY(Yoffset) { this.offsetY = Yoffset; } /** * Sets the images path * * @access public * @param string path Path to use for images */ function dynCalendar_setImagesPath(path) { this.imagesPath = path; } /** * Turns on/off the month dropdown * * @access public * @param boolean useMonthCombo Whether to use month dropdown or not */ function dynCalendar_setMonthCombo(useMonthCombo) { this.useMonthCombo = useMonthCombo; } /** * Turns on/off the year dropdown * * @access public * @param boolean useYearCombo Whether to use year dropdown or not */ function dynCalendar_setYearCombo(useYearCombo) { this.useYearCombo = useYearCombo; } /** * Sets the current month being displayed * * @access public * @param boolean month The month to set the current month to */ function dynCalendar_setCurrentMonth(month) { this.currentMonth = month; } /** * Sets the current month being displayed * * @access public * @param boolean year The year to set the current year to */ function dynCalendar_setCurrentYear(year) { this.currentYear = year; } /** * Sets the range of the year combo. Displays this number of * years either side of the year being displayed. * * @access public * @param integer range The range to set */ function dynCalendar_setYearComboRange(range) { this.yearComboRange = range; } /** * Returns the layer object * * @access private */ function dynCalendar_getLayer() { var layerID = "_dynCalendarPopupFull"; if (document.getElementById(layerID)) { return document.getElementById(layerID); } return false; } /** * Hides the calendar layer * * @access private */ function dynCalendar_hideLayer() { if (!dynCalendar_getLayer()) { return; } dynCalendar_getLayer().style.visibility = 'hidden'; dynCalendar_hidePopupLayer(); } /** * Shows the calendar layer * * @access private */ function dynCalendar_showLayer() { this._getLayer().style.visibility = 'visible'; } /** * Sets the layers position * * @access private */ function dynCalendar_setLayerPosition() { var ox=0,oy=0; oy = this.imgObj.offsetTop; ox = this.imgObj.offsetLeft; var n = this.imgObj; //alert(n.nodeName + ",x:"+n.offsetLeft +",y:"+ n.offsetTop); while (n.offsetParent) { n = n.offsetParent; //alert(n.nodeName + ",x:"+n.offsetLeft +",y:"+ n.offsetTop); if (n.nodeName && (n.offsetTop || n.offsetLeft)) { oy = oy + n.offsetTop; ox = ox + n.offsetLeft; } } //alert("x:"+ox +",y:"+oy) this._getLayer().style.top = this.offsetY + oy + 'px';//(dynCalendar_mouseY + this.offsetY) + 'px'; this._getLayer().style.left = this.offsetX + ox + 'px';//(dynCalendar_mouseX + this.offsetX) + 'px'; this._x = this.offsetX+ ox;//(dynCalendar_mouseX + this.offsetX); this._y = this.offsetY+ oy;//(dynCalendar_mouseY + this.offsetY); } /** * Sets the innerHTML attribute of the layer * * @access private */ function dynCalendar_setHTML(html) { this._getLayer().innerHTML = html; } /** * Returns number of days in the supplied month * * @access private * @param integer month The month to get number of days in * @param integer year The year of the month in question */ function dynCalendar_getDaysInMonth(month, year) { monthdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (month != 1) { return monthdays[month]; } else { return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? 29 : 28); } } /** * onMouse(Over|Out) event handler * * @access private * @param boolean status Whether the mouse is over the * calendar or not */ function dynCalendar_mouseover(status) { dynCalendar_mouseoverStatus = status; return true; } /** * onMouseMove event handler */ dynCalendar_oldOnmousemove = document.onmousemove ? document.onmousemove : new Function; document.onmousemove = function () { if (arguments[0]) { // dynCalendar_mouseX = arguments[0].pageX; // dynCalendar_mouseY = arguments[0].pageY; } else { // dynCalendar_mouseX = event.clientX + document.body.scrollLeft; // dynCalendar_mouseY = event.clientY + document.body.scrollTop; arguments[0] = null; } dynCalendar_oldOnmousemove(); } /** * Callbacks for document.onclick */ dynCalendar_oldOnclick = document.onclick ? document.onclick : new Function; document.onclick = function () { if (arguments[0]) { dynCalendar_mouseX = arguments[0].pageX; dynCalendar_mouseY = arguments[0].pageY; //alert(arguments[0].pageY); } if(!dynCalendar_mouseoverStatus){ dynCalendar_hideLayer(); } dynCalendar_oldOnclick(arguments[0] ? arguments[0] : null); }