Full version: jsB@nk » Time » Calendar » DynaCalendar
URL: https://www.javascriptbank.com/dynacalendar.html
A date selection widget for use with forms. Clean and simple. Uses style sheets for layout.
Full version: jsB@nk » Time » Calendar » DynaCalendar
URL: https://www.javascriptbank.com/dynacalendar.html
<style type=text/css>.dynaCalendarDiv { position: absolute; display: none; border: 2px solid black; background-color: white;}.dynaCalendarTable { border-collapse: collapse;}.dynaCalendarTable th { background-color: #CCCCFF; cursor: default; width: 2em; text-align: center; text-transform: capitalize; border: 1px solid white;}.dynaCalendarTable th.BF { cursor: pointer;}.dynaCalendarTable td { border: 1px solid white;}.dynaCalendarTable td.day { background-color: #DDDDFF; color: black; cursor: pointer;}.dynaCalendarTable td.daySelected { background-color: #333399; font-weight: bold; color: white; cursor: pointer;}.myText { font-family: sans-serif; font-size: 12px; color: black; padding-left: 5px;}</style><!-- This script downloaded from www.JavaScriptBank.com Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->
<script type=text/javascript>// Created by: Michael O'Connell :: http://wunder-ful.com/*** Invocation represents a function call in a specific object context with a list of parameters* This is a very powerful object that allows code to be executed in it's intended context* from any other context (context = the 'this' for that function).* There is a perfomance hit to use this (takes about 5x more time) * WARNING in IE if you try to use invoke on an object that is in a window that is no longer loaded it will throw "can't execute code in freed script"* @constructor* @param targetObj object to invoke a method on (functions not on an object are attached to the window object)* @param functionName string containing the name of the function to invoke on targetObj* @param arguments an Array of arguments to invoke the function with (optional)* @author Mike O'Connell*/function Invocation(targetObj, functionName, arguments) { this.targetObj = targetObj; this.functionName = functionName; this.arguments = arguments;}/*** Actually invoke the function call defined by this instance of Invocation.* If the object doesn't exist, or the function does not exist it will not try to execute* @param arguments an Array of arguments to invoke the function with (will be appended to the end of the predefined argument Array)* @return The return value of the function invoked.*/Invocation.prototype.invoke = function(arguments) { if(this.targetObj && typeof this.targetObj[this.functionName] == "function") { var args = this.arguments; if(!args) args = new Array(); if(arguments) args = args.concat(arguments); return this.targetObj[this.functionName].apply(this.targetObj, args); }}/*** @return the sum of all the offsetTop values from this element to the body*/function getTotalOffsetTop(element) { var offset = 0; for(var i = element; i && i.tagName != "BODY"; i = i.offsetParent) offset+=i.offsetTop; return offset;}/*** @return the sum of all the offsetLeft values from this element to the body*/function getTotalOffsetLeft(element) { var offset = 0; for(var i = element; i && i.tagName != "BODY"; i = i.offsetParent) offset+=i.offsetLeft; return offset;}/*** Positions a absolutely positioned element over the anchor. It will detect body clipping* and move the right side of the element to the right of the anchor. The element cannot* have * @param element the element to position* @param anchor the anchor to position element over* @param positionVertical position on "top" or "bottom" edge of the anchor* @param positionHorizontal position on "left" or "right" edge of the anchor*/function positionAtAnchor(element, anchor, positionVertical, positionHorizontal) { var left = getTotalOffsetLeft(anchor); if(positionHorizontal == "right") left = left + anchor.offsetWidth + 1; //horizontal clip if(left + element.offsetWidth > document.body.scrollWidth && left - element.offsetWidth > 0) { left = left - element.offsetWidth; if(positionHorizontal == "right") left = left - anchor.offsetWidth; else left = left + anchor.offsetWidth + 1; } var top = getTotalOffsetTop(anchor); if(positionVertical == "bottom") top = top + anchor.offsetHeight + 1; //vertical clip if(top + element.offsetHeight > document.body.scrollHeight && top - element.offsetHeight > 0) { top = top - element.offsetHeight; if(positionVertical == "bottom") top = top - anchor.offsetHeight; else top = top + anchor.offsetHeight + 1; } element.style.top = top+"px"; element.style.left = left+"px";}// ===========================//map of dynaCalendars by namevar dynaCalendars = {};/*** Opens / closes the dynacalendar at the specified anchor* @param name The unique name for the calendar to open.* @param anchor A element to open the calendar under**/function openDynaCalendar(name, anchor) { var calendar = dynaCalendars[name]; if(!calendar.isOpen) calendar.open(anchor); else calendar.close();}/*** Constructor for the DynaCalendar* @param name A unique name for this calendar* @param invocation The function to pass the date when a date is selected. * @param year Year to start calendar.* @param month Month to start calendar.* @param day Day to start calendar.* @see Invocation**/function DynaCalendar(name, invocation, year, month, day) { //populate day of week and month name constants if not previously created... if(!DynaCalendar.MONTHS) { var MONTHS = []; var DOW = []; DynaCalendar.MONTHS = MONTHS; DynaCalendar.DOW = DOW; var tmpDate = new Date(2000, 0, 1); for(var i = 0; i < 12; i++) { tmpDate.setMonth(i); var dateStr = tmpDate.toLocaleString(); var monthname = dateStr.match(/\s[a-zA-Z]+\s/)[0]; monthname = monthname.substring(1,monthname.length-1); MONTHS[i] = monthname; } for(var i = 1; i < 8; i++) { tmpDate.setDate(i); var dateStr = tmpDate.toLocaleString(); var dow = dateStr.substring(0,3); DOW[tmpDate.getDay()] = dow; } } if(year && month && day) this.date = new Date(year, month, day); else this.date = new Date(); this.invocation = invocation; this.name = name; this.isOpen = false; this.rendered = false; this.bodyRendern = false; dynaCalendars[name] = this;}/*** Displays the dynacalendar at the specified anchor.* @param anchor A element to open the calendar under*/DynaCalendar.prototype.open = function(anchor) { if(!this.rendered) this.render(); if(!this.bodyRendern) this.renderBody(); this.calendarDiv.style.display = "block"; positionAtAnchor(this.calendarDiv, anchor, "bottom", "left"); this.isOpen = true;}/*** Closes the dynaCalendar*/DynaCalendar.prototype.close = function() { this.calendarDiv.style.display = "none"; this.isOpen = false;}/*** Fills the calendarDiv with actual date spans**/DynaCalendar.prototype.render = function() { var calendarDiv = document.createElement("DIV"); var calendarTable = document.createElement("TABLE"); var calendarHead = document.createElement("THEAD"); var calendarHeadTR = document.createElement("TR"); var calendarHeadWeekTR = document.createElement("TR"); var calendarBY = document.createElement("TH"); var calendarBM = document.createElement("TH"); var calendarTitle = document.createElement("TH"); var calendarFM = document.createElement("TH"); var calendarFY = document.createElement("TH"); var calendarBody = document.createElement("TBODY"); calendarDiv.className = "dynaCalendarDiv"; calendarTable.className = "dynaCalendarTable"; calendarTitle.colSpan = 3; calendarBY.className = "BF"; calendarBM.className = "BF"; calendarFM.className = "BF"; calendarFY.className = "BF"; calendarBY.innerHTML = "<<"; calendarBM.innerHTML = "<"; calendarFM.innerHTML = ">"; calendarFY.innerHTML = ">>"; calendarBY.onclick = dynaCalendarBackYearOnClick; calendarBM.onclick = dynaCalendarBackMonthOnClick; calendarFM.onclick = dynaCalendarForwardMonthOnClick; calendarFY.onclick = dynaCalendarForwardYearOnClick; calendarDiv.dynaCalendar = this; calendarHead.dynaCalendar = this; calendarBody.dynaCalendar = this; calendarBY.dynaCalendar = this; calendarBM.dynaCalendar = this; calendarTitle.dynaCalendar = this; calendarFM.dynaCalendar = this; calendarFY.dynaCalendar = this; this.calendarTitle = calendarTitle; this.calendarBody = calendarBody; this.calendarDiv = calendarDiv; //populate week header for(var i = 0; i < 7; i++) { var dowTH = document.createElement("TH"); dowTH.innerHTML = DynaCalendar.DOW[i]; calendarHeadWeekTR.appendChild(dowTH); } calendarHeadTR.appendChild(calendarBY); calendarHeadTR.appendChild(calendarBM); calendarHeadTR.appendChild(calendarTitle); calendarHeadTR.appendChild(calendarFM); calendarHeadTR.appendChild(calendarFY); calendarHead.appendChild(calendarHeadTR); calendarHead.appendChild(calendarHeadWeekTR); calendarTable.appendChild(calendarHead); calendarTable.appendChild(calendarBody); calendarDiv.appendChild(calendarTable); document.body.appendChild(calendarDiv); this.rendered = true;}/*** Renders the actual month.**/DynaCalendar.prototype.renderBody = function() { //title var title = DynaCalendar.MONTHS[this.date.getMonth()]+ " " + this.date.getFullYear(); this.calendarTitle.innerHTML = title; //clear table body while(this.calendarBody.hasChildNodes()) this.calendarBody.removeChild(this.calendarBody.lastChild); //generate new table body var tmpDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1); var row = document.createElement("TR"); this.calendarBody.appendChild(row); //blanks for(var i = 0; i < tmpDate.getDay(); i++) { var td = document.createElement("TD"); row.appendChild(td); } while(tmpDate.getMonth() == this.date.getMonth()) { var td = document.createElement("TD"); var date = tmpDate.getDate(); if(date == this.date.getDate()) td.className = "daySelected"; else td.className = "day"; td.innerHTML = date; td.dynaCalendar = this; td.onclick = dynaCalendarSelectDayOnClick; row.appendChild(td); if(tmpDate.getDay() == 6) { row = document.createElement("TR"); this.calendarBody.appendChild(row); } tmpDate.setDate(date + 1); } //blanks for(var i = tmpDate.getDay(); i < 7; i++) { var td = document.createElement("TD"); row.appendChild(td); } this.bodyRendern = true;}/*** Set the day of the month* @param date The date of the month to set the calandar to.**/DynaCalendar.prototype.setDate = function(date) { this.date.setDate(date); this.bodyRendern = false;}/*** Moves back a year**/DynaCalendar.prototype.backYear = function() { this.setDate(1); this.date.setFullYear(this.date.getFullYear() - 1); this.renderBody();}/*** Moves back a month**/DynaCalendar.prototype.backMonth = function() { this.setDate(1); this.date.setMonth(this.date.getMonth() - 1); this.renderBody();}/*** Moves forward a month**/DynaCalendar.prototype.forwardMonth = function() { this.setDate(1); this.date.setMonth(this.date.getMonth() + 1); this.renderBody();}/*** Moves forward a year**/DynaCalendar.prototype.forwardYear = function() { this.setDate(1); this.date.setFullYear(this.date.getFullYear() + 1); this.renderBody();}// Event handlers -------------------------------------------------------------/*** onclick to select a day*/function dynaCalendarSelectDayOnClick(event) { //IE if(window.event) { var srcElement = window.event.srcElement; } //MOZ else { var srcElement = event.currentTarget; } var calendar = srcElement.dynaCalendar; calendar.setDate(srcElement.innerHTML); if(calendar.invocation) calendar.invocation.invoke([calendar.date]); srcElement.dynaCalendar.close(); return false;}/*** onclick to go back one year*/function dynaCalendarBackYearOnClick(event) { //IE if(window.event) { var srcElement = window.event.srcElement; } //MOZ else { var srcElement = event.currentTarget; } srcElement.dynaCalendar.backYear(); return false;}/*** onclick to go back one month*/function dynaCalendarBackMonthOnClick(event) { //IE if(window.event) { var srcElement = window.event.srcElement; } //MOZ else { var srcElement = event.currentTarget; } srcElement.dynaCalendar.backMonth(); return false;}/*** onclick to go forward one month*/function dynaCalendarForwardMonthOnClick(event) { //IE if(window.event) { var srcElement = window.event.srcElement; } //MOZ else { var srcElement = event.currentTarget; } srcElement.dynaCalendar.forwardMonth(); return false;}/*** onclick to go forward one year*/function dynaCalendarForwardYearOnClick(event) { //IE if(window.event) { var srcElement = window.event.srcElement; } //MOZ else { var srcElement = event.currentTarget; } srcElement.dynaCalendar.forwardYear(); return false;}// ===================================function setup_cal() { var cal = new DynaCalendar("test",new Invocation(this,"change_link"));}function change_link(date) { document.getElementById("link1").innerHTML = date.toLocaleString();}// =================================window.onload = setup_cal;</script><!-- This script downloaded from www.JavaScriptBank.com Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->
<a id="link1" class="myText" onclick="openDynaCalendar('test',this);">Click to Open Calendar</a><!-- This script downloaded from www.JavaScriptBank.com Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->