/* Copyright (c) 2006 Spip! Inc. All rights reserved. version 0.9.0 */ SPIP.namespace("SPIP.widget"); /** * @class *

SPIP.widget.DateMath is used for simple date manipulation. The class is a static utility * used for adding, subtracting, and comparing dates.

*/ SPIP.widget.DateMath = new function() { /** * Constant field representing Day * @type String */ this.DAY = "D"; /** * Constant field representing Week * @type String */ this.WEEK = "W"; /** * Constant field representing Year * @type String */ this.YEAR = "Y"; /** * Constant field representing Month * @type String */ this.MONTH = "M"; /** * Constant field representing one day, in milliseconds * @type Integer */ this.ONE_DAY_MS = 1000*60*60*24; /** * Adds the specified amount of time to the this instance. * @param {Date} date The JavaScript Date object to perform addition on * @param {string} field The this field constant to be used for performing addition. * @param {Integer} amount The number of units (measured in the field constant) to add to the date. */ this.add = function(date, field, amount) { var d = new Date(date.getTime()); switch (field) { case this.MONTH: var newMonth = date.getMonth() + amount; var years = 0; if (newMonth < 0) { while (newMonth < 0) { newMonth += 12; years -= 1; } } else if (newMonth > 11) { while (newMonth > 11) { newMonth -= 12; years += 1; } } d.setMonth(newMonth); d.setFullYear(date.getFullYear() + years); break; case this.DAY: d.setDate(date.getDate() + amount); break; case this.YEAR: d.setFullYear(date.getFullYear() + amount); break; case this.WEEK: d.setDate(date.getDate() + 7); break; } return d; }; /** * Subtracts the specified amount of time from the this instance. * @param {Date} date The JavaScript Date object to perform subtraction on * @param {Integer} field The this field constant to be used for performing subtraction. * @param {Integer} amount The number of units (measured in the field constant) to subtract from the date. */ this.subtract = function(date, field, amount) { return this.add(date, field, (amount*-1)); }; /** * Determines whether a given date is before another date on the calendar. * @param {Date} date The Date object to compare with the compare argument * @param {Date} compareTo The Date object to use for the comparison * @return {Boolean} true if the date occurs before the compared date; false if not. */ this.before = function(date, compareTo) { var ms = compareTo.getTime(); if (date.getTime() < ms) { return true; } else { return false; } }; /** * Determines whether a given date is after another date on the calendar. * @param {Date} date The Date object to compare with the compare argument * @param {Date} compareTo The Date object to use for the comparison * @return {Boolean} true if the date occurs after the compared date; false if not. */ this.after = function(date, compareTo) { var ms = compareTo.getTime(); if (date.getTime() > ms) { return true; } else { return false; } }; /** * Retrieves a JavaScript Date object representing January 1 of any given year. * @param {Integer} calendarYear The calendar year for which to retrieve January 1 * @return {Date} January 1 of the calendar year specified. */ this.getJan1 = function(calendarYear) { return new Date(calendarYear,0,1); }; /** * Calculates the number of days the specified date is from January 1 of the specified calendar year. * Passing January 1 to this function would return an offset value of zero. * @param {Date} date The JavaScript date for which to find the offset * @param {Integer} calendarYear The calendar year to use for determining the offset * @return {Integer} The number of days since January 1 of the given year */ this.getDayOffset = function(date, calendarYear) { var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1. // Find the number of days the passed in date is away from the calendar year start var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS); return dayOffset; }; /** * Calculates the week number for the given date. This function assumes that week 1 is the * week in which January 1 appears, regardless of whether the week consists of a full 7 days. * The calendar year can be specified to help find what a the week number would be for a given * date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or * week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction * easily. * @param {Date} date The JavaScript date for which to find the week number * @param {Integer} calendarYear OPTIONAL - The calendar year to use for determining the week number. Default is * the calendar year of parameter "date". * @param {Integer} weekStartsOn OPTIONAL - The integer (0-6) representing which day a week begins on. Default is 0 (for Sunday). * @return {Integer} The week number of the given date. */ this.getWeekNumber = function(date, calendarYear, weekStartsOn) { if (! weekStartsOn) { weekStartsOn = 0; } if (! calendarYear) { calendarYear = date.getFullYear(); } var weekNum = -1; var jan1 = this.getJan1(calendarYear); var jan1DayOfWeek = jan1.getDay(); var month = date.getMonth(); var day = date.getDate(); var year = date.getFullYear(); var dayOffset = this.getDayOffset(date, calendarYear); // Days since Jan 1, Calendar Year if (dayOffset < 0 && dayOffset >= (-1 * jan1DayOfWeek)) { weekNum = 1; } else { weekNum = 1; var testDate = this.getJan1(calendarYear); while (testDate.getTime() < date.getTime() && testDate.getFullYear() == calendarYear) { weekNum += 1; testDate = this.add(testDate, this.WEEK, 1); } } return weekNum; }; /** * Determines if a given week overlaps two different years. * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week. * @return {Boolean} true if the date overlaps two different years. */ this.isYearOverlapWeek = function(weekBeginDate) { var overlaps = false; var nextWeek = this.add(weekBeginDate, this.DAY, 6); if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) { overlaps = true; } return overlaps; }; /** * Determines if a given week overlaps two different months. * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week. * @return {Boolean} true if the date overlaps two different months. */ this.isMonthOverlapWeek = function(weekBeginDate) { var overlaps = false; var nextWeek = this.add(weekBeginDate, this.DAY, 6); if (nextWeek.getMonth() != weekBeginDate.getMonth()) { overlaps = true; } return overlaps; }; /** * Gets the first day of a month containing a given date. * @param {Date} date The JavaScript Date used to calculate the month start * @return {Date} The JavaScript Date representing the first day of the month */ this.findMonthStart = function(date) { var start = new Date(date.getFullYear(), date.getMonth(), 1); return start; }; /** * Gets the last day of a month containing a given date. * @param {Date} date The JavaScript Date used to calculate the month end * @return {Date} The JavaScript Date representing the last day of the month */ this.findMonthEnd = function(date) { var start = this.findMonthStart(date); var nextMonth = this.add(start, this.MONTH, 1); var end = this.subtract(nextMonth, this.DAY, 1); return end; }; /** * Clears the time fields from a given date, effectively setting the time to midnight. * @param {Date} date The JavaScript Date for which the time fields will be cleared * @return {Date} The JavaScript Date cleared of all time fields */ this.clearTime = function(date) { date.setHours(0,0,0,0); return date; }; } SPIP.namespace("SPIP.widget"); /** * @class *

Calendar_Core is the base class for the Calendar widget. In its most basic * implementation, it has the ability to render a calendar widget on the page * that can be manipulated to select a single date, move back and forth between * months and years.

*

To construct the placeholder for the calendar widget, the code is as * follows: *

* <div id="cal1Container"></div> * * Note that the table can be replaced with any kind of element. *

* @constructor * @param {String} id The id of the table element that will represent the calendar widget * @param {String} containerId The id of the container element that will contain the calendar table * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.Calendar_Core = function(id, containerId, monthyear, selected) { if (arguments.length > 0) { this.init(id, containerId, monthyear, selected); } } /** * Type constant used for renderers to represent an individual date (M/D/Y) * @final * @type String */ SPIP.widget.Calendar_Core.DATE = "D"; /** * Type constant used for renderers to represent an individual date across any year (M/D) * @final * @type String */ SPIP.widget.Calendar_Core.MONTH_DAY = "MD"; /** * Type constant used for renderers to represent a weekday * @final * @type String */ SPIP.widget.Calendar_Core.WEEKDAY = "WD"; /** * Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y) * @final * @type String */ SPIP.widget.Calendar_Core.RANGE = "R"; /** * Type constant used for renderers to represent a month across any year * @final * @type String */ SPIP.widget.Calendar_Core.MONTH = "M"; /** * Constant that represents the total number of date cells that are displayed in a given month * including * @final * @type Integer */ SPIP.widget.Calendar_Core.DISPLAY_DAYS = 42; /** * Constant used for halting the execution of the remainder of the render stack * @final * @type String */ SPIP.widget.Calendar_Core.STOP_RENDER = "S"; SPIP.widget.Calendar_Core.prototype = { /** * The configuration object used to set up the calendars various locale and style options. * @type Object */ Config : null, /** * The parent CalendarGroup, only to be set explicitly by the parent group * @type CalendarGroup */ parent : null, /** * The index of this item in the parent group * @type Integer */ index : -1, /** * The collection of calendar table cells * @type HTMLTableCellElement[] */ cells : null, /** * The collection of calendar week header cells * @type HTMLTableCellElement[] */ weekHeaderCells : null, /** * The collection of calendar week footer cells * @type HTMLTableCellElement[] */ weekFooterCells : null, /** * The collection of calendar cell dates that is parallel to the cells collection. The array contains dates field arrays in the format of [YYYY, M, D]. * @type Array[](Integer[]) */ cellDates : null, /** * The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page. * @type String */ id : null, /** * The DOM element reference that points to this calendar's container element. The calendar will be inserted into this element when the shell is rendered. * @type HTMLElement */ oDomContainer : null, /** * A Date object representing today's date. * @type Date */ today : null, /** * The list of render functions, along with required parameters, used to render cells. * @type Array[] */ renderStack : null, /** * A copy of the initial render functions created before rendering. * @type Array * @private */ _renderStack : null, /** * A Date object representing the month/year that the calendar is currently set to * @type Date */ pageDate : null, /** * A Date object representing the month/year that the calendar is initially set to * @type Date * @private */ _pageDate : null, /** * A Date object representing the minimum selectable date * @type Date */ minDate : null, /** * A Date object representing the maximum selectable date * @type Date */ maxDate : null, /** * The list of currently selected dates. The data format for this local collection is * an array of date field arrays, e.g: * [ * [2004,5,25], * [2004,5,26] * ] * @type Array[](Integer[]) */ selectedDates : null, /** * The private list of initially selected dates. * @type Array * @private */ _selectedDates : null, /** * A boolean indicating whether the shell of the calendar has already been rendered to the page * @type Boolean */ shellRendered : false, /** * The HTML table element that represents this calendar * @type HTMLTableElement */ table : null, /** * The HTML cell element that represents the main header cell TH used in the calendar table * @type HTMLTableCellElement */ headerCell : null }; /** * Initializes the calendar widget. This method must be called by all subclass constructors. * @param {String} id The id of the table element that will represent the calendar widget * @param {String} containerId The id of the container element that will contain the calendar table * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.Calendar_Core.prototype.init = function(id, containerId, monthyear, selected) { this.setupConfig(); this.id = id; this.cellDates = new Array(); this.cells = new Array(); this.renderStack = new Array(); this._renderStack = new Array(); this.oDomContainer = document.getElementById(containerId); this.today = new Date(); SPIP.widget.DateMath.clearTime(this.today); var month; var year; if (monthyear) { var aMonthYear = monthyear.split(this.Locale.DATE_FIELD_DELIMITER); month = parseInt(aMonthYear[this.Locale.MY_MONTH_POSITION-1]); year = parseInt(aMonthYear[this.Locale.MY_YEAR_POSITION-1]); } else { month = this.today.getMonth()+1; year = this.today.getFullYear(); } this.pageDate = new Date(year, month-1, 1); this._pageDate = new Date(this.pageDate.getTime()); if (selected) { this.selectedDates = this._parseDates(selected); this._selectedDates = this.selectedDates.concat(); } else { this.selectedDates = new Array(); this._selectedDates = new Array(); } this.wireDefaultEvents(); this.wireCustomEvents(); }; /** * Wires the local DOM events for the Calendar, including cell selection, hover, and * default navigation that is used for moving back and forth between calendar pages. */ SPIP.widget.Calendar_Core.prototype.wireDefaultEvents = function() { /** * The default event function that is attached to a date link within a calendar cell * when the calendar is rendered. * @param e The event * @param cal A reference to the calendar passed by the Event utility */ this.doSelectCell = function(e, cal) { var cell = this; var index = cell.index; if (cal.Options.MULTI_SELECT) { var link = cell.getElementsByTagName("A")[0]; link.blur(); var cellDate = cal.cellDates[index]; var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate); if (cellDateIndex > -1) { cal.deselectCell(index); } else { cal.selectCell(index); } } else { var link = cell.getElementsByTagName("A")[0]; link.blur() cal.selectCell(index); } } /** * The event that is executed when the user hovers over a cell * @param e The event * @param cal A reference to the calendar passed by the Event utility * @private */ this.doCellMouseOver = function(e, cal) { SPIP.widget.Calendar_Core.prependCssClass(this, cal.Style.CSS_CELL_HOVER); } /** * The event that is executed when the user moves the mouse out of a cell * @param e The event * @param cal A reference to the calendar passed by the Event utility * @private */ this.doCellMouseOut = function(e, cal) { SPIP.widget.Calendar_Core.removeCssClass(this, cal.Style.CSS_CELL_HOVER); } /** * A wrapper event that executes the nextMonth method through a DOM event * @param e The event * @param cal A reference to the calendar passed by the Event utility * @private */ this.doNextMonth = function(e, cal) { cal.nextMonth(); } /** * A wrapper event that executes the previousMonth method through a DOM event * @param e The event * @param cal A reference to the calendar passed by the Event utility * @private */ this.doPreviousMonth = function(e, cal) { cal.previousMonth(); } } /** * This function can be extended by subclasses to attach additional DOM events to * the calendar. By default, this method is unimplemented. */ SPIP.widget.Calendar_Core.prototype.wireCustomEvents = function() { } /** This method is called to initialize the widget configuration variables, including style, localization, and other display and behavioral options.

Config: Container for the CSS style configuration variables.

Config.Style - Defines the CSS classes used for different calendar elements

CSS_CALENDAR : Container table
CSS_HEADER :
CSS_HEADER_TEXT : Calendar header
CSS_FOOTER : Calendar footer
CSS_CELL : Calendar day cell
CSS_CELL_OOM : Calendar OOM (out of month) cell
CSS_CELL_SELECTED : Calendar selected cell
CSS_CELL_RESTRICTED : Calendar restricted cell
CSS_CELL_TODAY : Calendar cell for today's date
CSS_ROW_HEADER : The cell preceding a row (used for week number by default)
CSS_ROW_FOOTER : The cell following a row (not implemented by default)
CSS_WEEKDAY_CELL : The cells used for labeling weekdays
CSS_WEEKDAY_ROW : The row containing the weekday label cells
CSS_BORDER : The border style used for the default UED rendering
CSS_CONTAINER : Special container class used to properly adjust the sizing and float
CSS_NAV_LEFT : Left navigation arrow
CSS_NAV_RIGHT : Right navigation arrow
CSS_CELL_TOP : Outlying cell along the top row
CSS_CELL_LEFT : Outlying cell along the left row
CSS_CELL_RIGHT : Outlying cell along the right row
CSS_CELL_BOTTOM : Outlying cell along the bottom row
CSS_CELL_HOVER : Cell hover style
CSS_CELL_HIGHLIGHT1 : Highlight color 1 for styling cells
CSS_CELL_HIGHLIGHT2 : Highlight color 2 for styling cells
CSS_CELL_HIGHLIGHT3 : Highlight color 3 for styling cells
CSS_CELL_HIGHLIGHT4 : Highlight color 4 for styling cells

Config.Locale - Defines the locale string arrays used for localization

MONTHS_SHORT : Array of 12 months in short format ("Jan", "Feb", etc.)
MONTHS_LONG : Array of 12 months in short format ("Jan", "Feb", etc.)
WEEKDAYS_1CHAR : Array of 7 days in 1-character format ("S", "M", etc.)
WEEKDAYS_SHORT : Array of 7 days in short format ("Su", "Mo", etc.)
WEEKDAYS_MEDIUM : Array of 7 days in medium format ("Sun", "Mon", etc.)
WEEKDAYS_LONG : Array of 7 days in long format ("Sunday", "Monday", etc.)
DATE_DELIMITER : The value used to delimit series of multiple dates (Default: ",")
DATE_FIELD_DELIMITER : The value used to delimit date fields (Default: "/")
DATE_RANGE_DELIMITER : The value used to delimit date fields (Default: "-")
MY_MONTH_POSITION : The value used to determine the position of the month in a month/year combo (e.g. 12/2005) (Default: 1)
MY_YEAR_POSITION : The value used to determine the position of the year in a month/year combo (e.g. 12/2005) (Default: 2)
MD_MONTH_POSITION : The value used to determine the position of the month in a month/day combo (e.g. 12/25) (Default: 1)
MD_DAY_POSITION : The value used to determine the position of the day in a month/day combo (e.g. 12/25) (Default: 2)
MDY_MONTH_POSITION : The value used to determine the position of the month in a month/day/year combo (e.g. 12/25/2005) (Default: 1)
MDY_DAY_POSITION : The value used to determine the position of the day in a month/day/year combo (e.g. 12/25/2005) (Default: 2)
MDY_YEAR_POSITION : The value used to determine the position of the year in a month/day/year combo (e.g. 12/25/2005) (Default: 3)

Config.Options - Defines other configurable calendar widget options

SHOW_WEEKDAYS : Boolean, determines whether to display the weekday headers (defaults to true)
LOCALE_MONTHS : Array, points to the desired Config.Locale array (defaults to Config.Locale.MONTHS_LONG)
LOCALE_WEEKDAYS : Array, points to the desired Config.Locale array (defaults to Config.Locale.WEEKDAYS_SHORT)
START_WEEKDAY : Integer, 0-6, representing the day that a week begins on
SHOW_WEEK_HEADER : Boolean, determines whether to display row headers
SHOW_WEEK_FOOTER : Boolean, determines whether to display row footers
HIDE_BLANK_WEEKS : Boolean, determines whether to hide extra weeks that are completely OOM
NAV_ARROW_LEFT : String, the image path used for the left navigation arrow
NAV_ARROW_RIGHT : String, the image path used for the right navigation arrow
*/ SPIP.widget.Calendar_Core.prototype.setupConfig = function() { /** * Container for the CSS style configuration variables. */ this.Config = new Object(); this.Config.Style = { // Style variables CSS_ROW_HEADER: "calrowhead", CSS_ROW_FOOTER: "calrowfoot", CSS_CELL : "calcell", CSS_CELL_SELECTED : "selected", CSS_CELL_RESTRICTED : "restricted", CSS_CELL_TODAY : "today", CSS_CELL_OOM : "oom", CSS_HEADER : "calheader", CSS_HEADER_TEXT : "calhead", CSS_WEEKDAY_CELL : "calweekdaycell", CSS_WEEKDAY_ROW : "calweekdayrow", CSS_FOOTER : "calfoot", CSS_CALENDAR : "calendar", CSS_BORDER : "calbordered", CSS_CONTAINER : "calcontainer", CSS_NAV_LEFT : "calnavleft", CSS_NAV_RIGHT : "calnavright", CSS_CELL_TOP : "calcelltop", CSS_CELL_LEFT : "calcellleft", CSS_CELL_RIGHT : "calcellright", CSS_CELL_BOTTOM : "calcellbottom", CSS_CELL_HOVER : "calcellhover", CSS_CELL_HIGHLIGHT1 : "highlight1", CSS_CELL_HIGHLIGHT2 : "highlight2", CSS_CELL_HIGHLIGHT3 : "highlight3", CSS_CELL_HIGHLIGHT4 : "highlight4" }; this.Style = this.Config.Style; this.Config.Locale = { // Locale definition MONTHS_SHORT : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], MONTHS_LONG : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], WEEKDAYS_1CHAR : ["S", "M", "T", "W", "T", "F", "S"], WEEKDAYS_SHORT : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], WEEKDAYS_MEDIUM : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], WEEKDAYS_LONG : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], DATE_DELIMITER : ",", DATE_FIELD_DELIMITER : "/", DATE_RANGE_DELIMITER : "-", MY_MONTH_POSITION : 1, MY_YEAR_POSITION : 2, MD_MONTH_POSITION : 1, MD_DAY_POSITION : 2, MDY_MONTH_POSITION : 1, MDY_DAY_POSITION : 2, MDY_YEAR_POSITION : 3 }; this.Locale = this.Config.Locale; this.Config.Options = { // Configuration variables MULTI_SELECT : false, SHOW_WEEKDAYS : true, START_WEEKDAY : 0, SHOW_WEEK_HEADER : false, SHOW_WEEK_FOOTER : false, HIDE_BLANK_WEEKS : false, NAV_ARROW_LEFT : "img/callt.gif", NAV_ARROW_RIGHT : "img/calrt.gif", IMG_CLOSE : "img/calx.gif", IMG_CLOSE_CLASS : "close-icon" }; this.Options = this.Config.Options; this.customConfig(); if (! this.Options.LOCALE_MONTHS) { this.Options.LOCALE_MONTHS=this.Locale.MONTHS_LONG; } if (! this.Options.LOCALE_WEEKDAYS) { this.Options.LOCALE_WEEKDAYS=this.Locale.WEEKDAYS_SHORT; } // If true, reconfigure weekday arrays to place Mondays first if (this.Options.START_WEEKDAY > 0) { for (var w=0;w * this.Config.Style.CSS_CELL = "newcalcell"; * this.Config.Locale.MONTHS_SHORT = ["Jan", "Fév", "Mars", "Avr", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc"]; * */ SPIP.widget.Calendar_Core.prototype.customConfig = function() { }; /** * Builds the date label that will be displayed in the calendar header or * footer, depending on configuration. * @return The formatted calendar month label * @type String */ SPIP.widget.Calendar_Core.prototype.buildMonthLabel = function() { var text = this.Options.LOCALE_MONTHS[this.pageDate.getMonth()] + " " + this.pageDate.getFullYear(); return text; }; /** * Builds the date digit that will be displayed in calendar cells * @return The formatted day label * @type String */ SPIP.widget.Calendar_Core.prototype.buildDayLabel = function(workingDate) { var day = workingDate.getDate(); return day; }; /** * Builds the calendar table shell that will be filled in with dates and formatting. * This method calls buildShellHeader, buildShellBody, and buildShellFooter (in that order) * to construct the pieces of the calendar table. The construction of the shell should * only happen one time when the calendar is initialized. */ SPIP.widget.Calendar_Core.prototype.buildShell = function() { this.table = document.createElement("TABLE"); this.table.cellSpacing = 0; SPIP.widget.Calendar_Core.setCssClasses(this.table, [this.Style.CSS_CALENDAR]); this.table.id = this.id; this.buildShellHeader(); this.buildShellBody(); this.buildShellFooter(); SPIP.util.Event.addListener(window, "unload", this._unload, this); }; /** * Builds the calendar shell header by inserting a THEAD into the local calendar table. */ SPIP.widget.Calendar_Core.prototype.buildShellHeader = function() { var head = document.createElement("THEAD"); var headRow = document.createElement("TR"); var headerCell = document.createElement("TH"); var colSpan = 7; if (this.Config.Options.SHOW_WEEK_HEADER) { this.weekHeaderCells = new Array(); colSpan += 1; } if (this.Config.Options.SHOW_WEEK_FOOTER) { this.weekFooterCells = new Array(); colSpan += 1; } headerCell.colSpan = colSpan; SPIP.widget.Calendar_Core.setCssClasses(headerCell,[this.Style.CSS_HEADER_TEXT]); this.headerCell = headerCell; headRow.appendChild(headerCell); head.appendChild(headRow); // Append day labels, if needed if (this.Options.SHOW_WEEKDAYS) { var row = document.createElement("TR"); var fillerCell; SPIP.widget.Calendar_Core.setCssClasses(row,[this.Style.CSS_WEEKDAY_ROW]); if (this.Config.Options.SHOW_WEEK_HEADER) { fillerCell = document.createElement("TH"); SPIP.widget.Calendar_Core.setCssClasses(fillerCell,[this.Style.CSS_WEEKDAY_CELL]); row.appendChild(fillerCell); } for(var i=0;i 0) { this.preMonthDays -= this.Options.START_WEEKDAY; } if (this.preMonthDays < 0) { this.preMonthDays += 7; } this.monthDays = SPIP.widget.DateMath.findMonthEnd(workingDate).getDate(); this.postMonthDays = SPIP.widget.Calendar_Core.DISPLAY_DAYS-this.preMonthDays-this.monthDays; workingDate = SPIP.widget.DateMath.subtract(workingDate, SPIP.widget.DateMath.DAY, this.preMonthDays); this.table.style.visibility = "hidden"; // Hide while we render var weekRowIndex = 0; for (var c=0;c= d1.getTime() && workingDate.getTime() <= d2.getTime()) { renderer = rArray[2]; if (workingDate.getTime()==d2.getTime()) { this.renderStack.splice(r,1); } } break; case SPIP.widget.Calendar_Core.WEEKDAY: var weekday = rArray[1][0]; if (workingDate.getDay()+1 == weekday) { renderer = rArray[2]; } break; case SPIP.widget.Calendar_Core.MONTH: month = rArray[1][0]; if (workingDate.getMonth()+1 == month) { renderer = rArray[2]; } break; } if (renderer) { cellRenderers[cellRenderers.length]=renderer; } } } if (this._indexOfSelectedFieldArray([workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]) > -1) { cellRenderers[cellRenderers.length]=this.renderCellStyleSelected; } if (this.minDate) { this.minDate = SPIP.widget.DateMath.clearTime(this.minDate); } if (this.maxDate) { this.maxDate = SPIP.widget.DateMath.clearTime(this.maxDate); } if ( (this.minDate && (workingDate.getTime() < this.minDate.getTime())) || (this.maxDate && (workingDate.getTime() > this.maxDate.getTime())) ) { cellRenderers[cellRenderers.length]=this.renderOutOfBoundsDate; } else { cellRenderers[cellRenderers.length]=this.renderCellDefault; } for (var x=0;x= 0 && c <= 6) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_TOP); } if ((c % 7) == 0) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_LEFT); } if (((c+1) % 7) == 0) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_RIGHT); } var postDays = this.postMonthDays; if (postDays >= 7 && this.Options.HIDE_BLANK_WEEKS) { var blankWeeks = Math.floor(postDays/7); for (var p=0;p= ((this.preMonthDays+postDays+this.monthDays)-7)) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_BOTTOM); } } this.table.style.visibility = "visible"; // Show table, now that it's rendered }; /** * Appends the contents of the calendar widget footer into the shell. By default, * the calendar does not contain a footer, and this method must be implemented by * subclassing the widget. */ SPIP.widget.Calendar_Core.prototype.renderFooter = function() { }; /** * @private */ SPIP.widget.Calendar_Core.prototype._unload = function(e, cal) { for (var c in cal.cells) { c = null; } cal.cells = null; cal.tbody = null; cal.oDomContainer = null; cal.table = null; cal.headerCell = null; cal = null; }; /****************** BEGIN BUILT-IN TABLE CELL RENDERERS ************************************/ SPIP.widget.Calendar_Core.prototype.renderOutOfBoundsDate = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, "previous"); cell.innerHTML = workingDate.getDate(); return SPIP.widget.Calendar_Core.STOP_RENDER; } /** * Renders the row header for a week. The date passed in should be * the first date of the given week. * @param {Date} workingDate The current working Date object (beginning of the week) being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar */ SPIP.widget.Calendar_Core.prototype.renderRowHeader = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_ROW_HEADER); var useYear = this.pageDate.getFullYear(); if (! SPIP.widget.DateMath.isYearOverlapWeek(workingDate)) { useYear = workingDate.getFullYear(); } var weekNum = SPIP.widget.DateMath.getWeekNumber(workingDate, useYear, this.Options.START_WEEKDAY); cell.innerHTML = weekNum; if (this.isDateOOM(workingDate) && ! SPIP.widget.DateMath.isMonthOverlapWeek(workingDate)) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_OOM); } }; /** * Renders the row footer for a week. The date passed in should be * the first date of the given week. * @param {Date} workingDate The current working Date object (beginning of the week) being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar */ SPIP.widget.Calendar_Core.prototype.renderRowFooter = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_ROW_FOOTER); if (this.isDateOOM(workingDate) && ! SPIP.widget.DateMath.isMonthOverlapWeek(workingDate)) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_OOM); } }; /** * Renders a single standard calendar cell in the calendar widget table. * All logic for determining how a standard default cell will be rendered is * encapsulated in this method, and must be accounted for when extending the * widget class. * @param {Date} workingDate The current working Date object being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar * @return SPIP.widget.Calendar_Core.STOP_RENDER if rendering should stop with this style, null or nothing if rendering * should not be terminated * @type String */ SPIP.widget.Calendar_Core.prototype.renderCellDefault = function(workingDate, cell) { cell.innerHTML = ""; var link = document.createElement("a"); link.href="javascript:void(null);"; link.name=this.id+"__"+workingDate.getFullYear()+"_"+(workingDate.getMonth()+1)+"_"+workingDate.getDate(); //link.onclick = this._selectEventLink; //cell.onclick = this.doSelectCell; SPIP.util.Event.addListener(cell, "click", this.doSelectCell, this); if (SPIP.widget.Calendar_Core._getBrowser() == "ie") { SPIP.util.Event.addListener(cell, "mouseover", this.doCellMouseOver, this); SPIP.util.Event.addListener(cell, "mouseout", this.doCellMouseOut, this); } link.appendChild(document.createTextNode(this.buildDayLabel(workingDate))); cell.appendChild(link); //cell.onmouseover = this.doCellMouseOver; //cell.onmouseout = this.doCellMouseOut; }; SPIP.widget.Calendar_Core.prototype.renderCellStyleHighlight1 = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_HIGHLIGHT1); }; SPIP.widget.Calendar_Core.prototype.renderCellStyleHighlight2 = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_HIGHLIGHT2); }; SPIP.widget.Calendar_Core.prototype.renderCellStyleHighlight3 = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_HIGHLIGHT3); }; SPIP.widget.Calendar_Core.prototype.renderCellStyleHighlight4 = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_HIGHLIGHT4); }; /** * Applies the default style used for rendering today's date to the current calendar cell * @param {Date} workingDate The current working Date object being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar * @return SPIP.widget.Calendar_Core.STOP_RENDER if rendering should stop with this style, null or nothing if rendering * should not be terminated * @type String */ SPIP.widget.Calendar_Core.prototype.renderCellStyleToday = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_TODAY); }; /** * Applies the default style used for rendering selected dates to the current calendar cell * @param {Date} workingDate The current working Date object being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar * @return SPIP.widget.Calendar_Core.STOP_RENDER if rendering should stop with this style, null or nothing if rendering * should not be terminated * @type String */ SPIP.widget.Calendar_Core.prototype.renderCellStyleSelected = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_SELECTED); }; /** * Applies the default style used for rendering dates that are not a part of the current * month (preceding or trailing the cells for the current month) * @param {Date} workingDate The current working Date object being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar * @return SPIP.widget.Calendar_Core.STOP_RENDER if rendering should stop with this style, null or nothing if rendering * should not be terminated * @type String */ SPIP.widget.Calendar_Core.prototype.renderCellNotThisMonth = function(workingDate, cell) { SPIP.widget.Calendar_Core.addCssClass(cell, this.Style.CSS_CELL_OOM); cell.innerHTML=workingDate.getDate(); return SPIP.widget.Calendar_Core.STOP_RENDER; }; /** * Renders the current calendar cell as a non-selectable "black-out" date using the default * restricted style. * @param {Date} workingDate The current working Date object being used to generate the calendar * @param {HTMLTableCellElement} cell The current working cell in the calendar * @return SPIP.widget.Calendar_Core.STOP_RENDER if rendering should stop with this style, null or nothing if rendering * should not be terminated * @type String */ SPIP.widget.Calendar_Core.prototype.renderBodyCellRestricted = function(workingDate, cell) { SPIP.widget.Calendar_Core.setCssClasses(cell, [this.Style.CSS_CELL,this.Style.CSS_CELL_RESTRICTED]); cell.innerHTML=workingDate.getDate(); return SPIP.widget.Calendar_Core.STOP_RENDER; }; /******************** END BUILT-IN TABLE CELL RENDERERS ************************************/ /******************** BEGIN MONTH NAVIGATION METHODS ************************************/ /** * Adds the designated number of months to the current calendar month, and sets the current * calendar page date to the new month. * @param {Integer} count The number of months to add to the current calendar */ SPIP.widget.Calendar_Core.prototype.addMonths = function(count) { this.pageDate = SPIP.widget.DateMath.add(this.pageDate, SPIP.widget.DateMath.MONTH, count); this.resetRenderers(); this.onChangePage(); }; /** * Subtracts the designated number of months from the current calendar month, and sets the current * calendar page date to the new month. * @param {Integer} count The number of months to subtract from the current calendar */ SPIP.widget.Calendar_Core.prototype.subtractMonths = function(count) { this.pageDate = SPIP.widget.DateMath.subtract(this.pageDate, SPIP.widget.DateMath.MONTH, count); this.resetRenderers(); this.onChangePage(); }; /** * Adds the designated number of years to the current calendar, and sets the current * calendar page date to the new month. * @param {Integer} count The number of years to add to the current calendar */ SPIP.widget.Calendar_Core.prototype.addYears = function(count) { this.pageDate = SPIP.widget.DateMath.add(this.pageDate, SPIP.widget.DateMath.YEAR, count); this.resetRenderers(); this.onChangePage(); }; /** * Subtcats the designated number of years from the current calendar, and sets the current * calendar page date to the new month. * @param {Integer} count The number of years to subtract from the current calendar */ SPIP.widget.Calendar_Core.prototype.subtractYears = function(count) { this.pageDate = SPIP.widget.DateMath.subtract(this.pageDate, SPIP.widget.DateMath.YEAR, count); this.resetRenderers(); this.onChangePage(); }; /** * Navigates to the next month page in the calendar widget. */ SPIP.widget.Calendar_Core.prototype.nextMonth = function() { this.addMonths(1); }; /** * Navigates to the previous month page in the calendar widget. */ SPIP.widget.Calendar_Core.prototype.previousMonth = function() { this.subtractMonths(1); }; /** * Navigates to the next year in the currently selected month in the calendar widget. */ SPIP.widget.Calendar_Core.prototype.nextYear = function() { this.addYears(1); }; /** * Navigates to the previous year in the currently selected month in the calendar widget. */ SPIP.widget.Calendar_Core.prototype.previousYear = function() { this.subtractYears(1); }; /****************** END MONTH NAVIGATION METHODS ************************************/ /************* BEGIN SELECTION METHODS *************************************************************/ /** * Resets the calendar widget to the originally selected month and year, and * sets the calendar to the initial selection(s). */ SPIP.widget.Calendar_Core.prototype.reset = function() { this.selectedDates.length = 0; this.selectedDates = this._selectedDates.concat(); this.deselectAll(); /*this.pageDate = new Date(this._pageDate.getTime());*/ this.onReset(); }; /** * Clears the selected dates in the current calendar widget and sets the calendar * to the current month and year. */ SPIP.widget.Calendar_Core.prototype.clear = function() { this.selectedDates.length = 0; /*this.pageDate = new Date(this.today.getTime());*/ this.onClear(); }; /** * Selects a date or a collection of dates on the current calendar. This method, by default, * does not call the render method explicitly. Once selection has completed, render must be * called for the changes to be reflected visually. * @param {String/Date/Date[]} date The date string of dates to select in the current calendar. Valid formats are * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006). * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005). * This method can also take a JavaScript Date object or an array of Date objects. * @return Array of JavaScript Date objects representing all individual dates that are currently selected. * @type Date[] */ SPIP.widget.Calendar_Core.prototype.select = function(date) { this.onBeforeSelect(); var aToBeSelected = this._toFieldArray(date); for (var a=0;a -1) { if (this.pageDate.getMonth() == dCellDate.getMonth() && this.pageDate.getFullYear() == dCellDate.getFullYear()) { SPIP.widget.Calendar_Core.removeCssClass(cell, this.Style.CSS_CELL_SELECTED); } this.selectedDates.splice(cellDateIndex, 1); } if (this.parent) { this.parent.sync(this); } this.onDeselect(); return this.getSelectedDates(); }; /** * Deselects all dates on the current calendar. * @return Array of JavaScript Date objects representing all individual dates that are currently selected. * Assuming that this function executes properly, the return value should be an empty array. * However, the empty array is returned for the sake of being able to check the selection status * of the calendar. * @type Date[] */ SPIP.widget.Calendar_Core.prototype.deselectAll = function() { this.onBeforeDeselect(); var count = this.selectedDates.length; this.selectedDates.length = 0; if (this.parent) { this.parent.sync(this); } if (count > 0) { this.onDeselect(); } return this.getSelectedDates(); }; /************* END SELECTION METHODS *************************************************************/ /************* BEGIN TYPE CONVERSION METHODS ****************************************************/ /** * Converts a date (either a JavaScript Date object, or a date string) to the internal data structure * used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]]. * @private * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006). * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005). * This method can also take a JavaScript Date object or an array of Date objects. * @return Array of date field arrays * @type Array[](Integer[]) */ SPIP.widget.Calendar_Core.prototype._toFieldArray = function(date) { var returnDate = new Array(); if (date instanceof Date) { returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]]; } else if (typeof date == 'string') { returnDate = this._parseDates(date); } else if (date instanceof Array) { for (var i=0;iSPIP.widget.CalendarGroup is a special container class for SPIP.widget.Calendar_Core. This class facilitates * the ability to have multi-page calendar views that share a single dataset and are * dependent on each other.

* *

The calendar group instance will refer to each of its elements using a 0-based index. * For example, to construct the placeholder for a calendar group widget with id "cal1" and * containerId of "cal1Container", the markup would be as follows: *

* <div id="cal1Container_0"></div> * <div id="cal1Container_1"></div> * * The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers. *

* @constructor * @param {Integer} pageCount The number of pages that this calendar should display. * @param {String} id The id of the element that will be inserted into the DOM. * @param {String} containerId The id of the container element that the calendar will be inserted into. * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.CalendarGroup = function(pageCount, id, containerId, monthyear, selected) { if (arguments.length > 0) { this.init(pageCount, id, containerId, monthyear, selected); } } /** * Initializes the calendar group. All subclasses must call this method in order for the * group to be initialized properly. * @param {Integer} pageCount The number of pages that this calendar should display. * @param {String} id The id of the element that will be inserted into the DOM. * @param {String} containerId The id of the container element that the calendar will be inserted into. * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.CalendarGroup.prototype.init = function(pageCount, id, containerId, monthyear, selected) { //var self=this; this.id = id; this.selectedDates = new Array(); this.containerId = containerId; this.pageCount = pageCount; this.pages = new Array(); for (var p=0;p0) { year+=1; } cal.setYear(year); } }; /** * Calls the render function of all child calendars within the group. */ SPIP.widget.CalendarGroup.prototype.render = function() { for (var p=0;p=0;--p) { var cal = this.pages[p]; cal.previousMonth(); } }; /** * Calls the nextYear function of all child calendars within the group. */ SPIP.widget.CalendarGroup.prototype.nextYear = function() { for (var p=0;p * calGroup.wireEvent("onSelect", fnSelect); * * @param {String} eventName The name of the event to handler to set within all child calendars. * @param {Function} fn The function to set into the specified event handler. */ SPIP.widget.CalendarGroup.prototype.wireEvent = function(eventName, fn) { for (var p=0;p 0) { this.init(id, containerId, monthyear, selected); } } SPIP.widget.Calendar.prototype = new SPIP.widget.Calendar_Core(); SPIP.widget.Calendar.prototype.buildShell = function() { this.border = document.createElement("DIV"); this.border.className = this.Style.CSS_BORDER; this.table = document.createElement("TABLE"); this.table.cellSpacing = 0; SPIP.widget.Calendar_Core.setCssClasses(this.table, [this.Style.CSS_CALENDAR]); this.border.id = this.id; this.buildShellHeader(); this.buildShellBody(); this.buildShellFooter(); }; SPIP.widget.Calendar.prototype.renderShell = function() { this.border.appendChild(this.table); this.oDomContainer.appendChild(this.border); this.shellRendered = true; }; SPIP.widget.Calendar.prototype.renderHeader = function() { this.headerCell.innerHTML = ""; var headerContainer = document.createElement("DIV"); headerContainer.className = this.Style.CSS_HEADER; var linkLeft = document.createElement("A"); linkLeft.href = "javascript:" + this.id + ".previousMonth()"; var imgLeft = document.createElement("IMG"); imgLeft.src = this.Options.NAV_ARROW_LEFT; imgLeft.className = this.Style.CSS_NAV_LEFT; linkLeft.appendChild(imgLeft); var linkRight = document.createElement("A"); linkRight.href = "javascript:" + this.id + ".nextMonth()"; var imgRight = document.createElement("IMG"); imgRight.src = this.Options.NAV_ARROW_RIGHT; imgRight.className = this.Style.CSS_NAV_RIGHT; linkRight.appendChild(imgRight); headerContainer.appendChild(linkLeft); var labelMonth = document.createElement("span"); labelMonth.innerHTML = this.buildMonthLabel(); headerContainer.appendChild(labelMonth); headerContainer.appendChild(linkRight); this.headerCell.appendChild(headerContainer); }; SPIP.widget.Cal = SPIP.widget.Calendar; SPIP.namespace("SPIP.widget"); /** * @class * Calendar2up_Cal is the default implementation of the Calendar_Core base class, when used * in a 2-up view. This class is the UED-approved version of the calendar selector widget. For all documentation * on the implemented methods listed here, see the documentation for Calendar_Core. This class * has some special attributes that only apply to calendars rendered within the calendar group implementation. * There should be no reason to instantiate this class directly. * @constructor * @param {String} id The id of the table element that will represent the calendar widget * @param {String} containerId The id of the container element that will contain the calendar table * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.Calendar2up_Cal = function(id, containerId, monthyear, selected) { if (arguments.length > 0) { this.init(id, containerId, monthyear, selected); } } SPIP.widget.Calendar2up_Cal.prototype = new SPIP.widget.Calendar_Core(); /** * Renders the header for each individual calendar in the 2-up view. More * specifically, this method handles the placement of left and right arrows for * navigating between calendar pages. */ SPIP.widget.Calendar2up_Cal.prototype.renderHeader = function() { this.headerCell.innerHTML = ""; var headerContainer = document.createElement("DIV"); headerContainer.className = this.Style.CSS_HEADER; if (this.index == 0) { var linkLeft = document.createElement("A"); linkLeft.href = "javascript:void(null)"; SPIP.util.Event.addListener(linkLeft, "click", this.parent.doPreviousMonth, this.parent); var imgLeft = document.createElement("IMG"); imgLeft.src = this.Options.NAV_ARROW_LEFT; imgLeft.className = this.Style.CSS_NAV_LEFT; linkLeft.appendChild(imgLeft); headerContainer.appendChild(linkLeft); } var labelMonth = document.createElement("span"); labelMonth.innerHTML = this.buildMonthLabel(); /*headerContainer.appendChild(document.createTextNode(this.buildMonthLabel()));*/ headerContainer.appendChild(labelMonth); if (this.index == 1) { var linkRight = document.createElement("A"); linkRight.href = "javascript:void(null)"; SPIP.util.Event.addListener(linkRight, "click", this.parent.doNextMonth, this.parent); var imgRight = document.createElement("IMG"); imgRight.src = this.Options.NAV_ARROW_RIGHT; imgRight.className = this.Style.CSS_NAV_RIGHT; linkRight.appendChild(imgRight); headerContainer.appendChild(linkRight); } this.headerCell.appendChild(headerContainer); }; /** * @class * Calendar2up is the default implementation of the Calendar2up_Core base class, when used * in a 2-up view. This class is the UED-approved version of the 2-up calendar selector widget. For all documentation * on the implemented methods listed here, see the documentation for Calendar2up_Core. * @constructor * @param {String} id The id of the table element that will represent the calendar widget * @param {String} containerId The id of the container element that will contain the calendar table * @param {String} monthyear The month/year string used to set the current calendar page * @param {String} selected A string of date values formatted using the date parser. The built-in default date format is MM/DD/YYYY. Ranges are defined using MM/DD/YYYY-MM/DD/YYYY. Month/day combinations are defined using MM/DD. Any combination of these can be combined by delimiting the string with commas. Example: "12/24/2005,12/25,1/18/2006-1/21/2006" */ SPIP.widget.Calendar2up = function(id, containerId, monthyear, selected) { if (arguments.length > 0) { this.buildWrapper(containerId); this.init(2, id, containerId, monthyear, selected); } } SPIP.widget.Calendar2up.prototype = new SPIP.widget.CalendarGroup(); /** * Implementation of CalendarGroup.constructChild that ensures that child calendars of * Calendar2up will be of type Calendar2up_Cal. */ SPIP.widget.Calendar2up.prototype.constructChild = function(id,containerId,monthyear,selected) { var cal = new SPIP.widget.Calendar2up_Cal(id,containerId,monthyear,selected); return cal; }; /** * Builds the wrapper container for the 2-up calendar. * @param {String} containerId The id of the outer container element. */ SPIP.widget.Calendar2up.prototype.buildWrapper = function(containerId) { var outerContainer = document.getElementById(containerId); outerContainer.className = "calcontainer"; /*outerContainer.innerHTML=""; if (SPIP.widget.Calendar_Core._getBrowser() == "ie") { outerContainer.innerHTML=""; }*/ var innerContainer = document.createElement("DIV"); innerContainer.className = "calbordered"; innerContainer.id = containerId + "_inner"; var cal1Container = document.createElement("DIV"); cal1Container.id = containerId + "_0"; cal1Container.className = "cal2up"; cal1Container.style.marginRight = "10px"; cal1Container.style.zIndex="99"; //cal1Container.style.cssFloat="left"; var cal2Container = document.createElement("DIV"); cal2Container.id = containerId + "_1"; cal2Container.className = "cal2up2"; cal1Container.style.zIndex="99"; //cal2Container.style.cssFloat="left"; outerContainer.appendChild(innerContainer); innerContainer.appendChild(cal1Container); innerContainer.appendChild(cal2Container); this.innerContainer = innerContainer; this.outerContainer = outerContainer; } /** * Renders the 2-up calendar. */ SPIP.widget.Calendar2up.prototype.render = function() { this.renderHeader(); SPIP.widget.CalendarGroup.prototype.render.call(this); this.renderFooter(); }; /** * Renders the header located at the top of the container for the 2-up calendar. */ SPIP.widget.Calendar2up.prototype.renderHeader = function() { if (! this.title) { this.title = ""; } if (! this.titleDiv) { this.titleDiv = document.createElement("DIV"); if (this.title == "") { this.titleDiv.style.display="none"; } } this.titleDiv.className = "title"; this.titleDiv.innerHTML = this.title; if (this.outerContainer.style.position == "absolute") { var linkClose = document.createElement("A"); linkClose.href = "javascript:void(null)"; SPIP.util.Event.addListener(linkClose, "click", this.hide, this); var imgClose = document.createElement("IMG"); imgClose.src = this.pages[0].Options.IMG_CLOSE; imgClose.className = this.pages[0].Options.IMG_CLOSE_CLASS; linkClose.appendChild(imgClose); this.linkClose = linkClose; this.titleDiv.appendChild(linkClose); } this.innerContainer.insertBefore(this.titleDiv, this.innerContainer.firstChild); } /** * Hides the 2-up calendar's outer container from view. */ SPIP.widget.Calendar2up.prototype.hide = function(e, cal) { if (! cal) { cal = this; } cal.outerContainer.style.display = "none"; } /** * Renders a footer for the 2-up calendar container. By default, this method is * unimplemented. */ SPIP.widget.Calendar2up.prototype.renderFooter = function() {} SPIP.widget.Cal2up = SPIP.widget.Calendar2up;