Index: openacs-4/packages/ajaxhelper/www/resources/yui/calendar/calendar.js
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/ajaxhelper/www/resources/yui/calendar/calendar.js,v
diff -u -r1.3 -r1.4
--- openacs-4/packages/ajaxhelper/www/resources/yui/calendar/calendar.js 8 Sep 2007 14:22:00 -0000 1.3
+++ openacs-4/packages/ajaxhelper/www/resources/yui/calendar/calendar.js 9 Apr 2009 17:03:49 -0000 1.4
@@ -1,8 +1,8 @@
/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
-version: 2.3.0
+version: 2.7.0
*/
(function () {
@@ -18,26 +18,20 @@
* @param {Object} owner The owner Object to which this Config Object belongs
*/
YAHOO.util.Config = function (owner) {
-
+
if (owner) {
-
this.init(owner);
-
}
-
- if (!owner) {
-
-
- }
-
+
+
};
var Lang = YAHOO.lang,
- CustomEvent = YAHOO.util.CustomEvent,
+ CustomEvent = YAHOO.util.CustomEvent,
Config = YAHOO.util.Config;
-
+
/**
* Constant representing the CustomEvent type for the config changed event.
* @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
@@ -203,16 +197,19 @@
getConfig: function () {
var cfg = {},
+ currCfg = this.config,
prop,
property;
- for (prop in this.config) {
- property = this.config[prop];
- if (property && property.event) {
- cfg[prop] = property.value;
+ for (prop in currCfg) {
+ if (Lang.hasOwnProperty(currCfg, prop)) {
+ property = currCfg[prop];
+ if (property && property.event) {
+ cfg[prop] = property.value;
+ }
}
}
-
+
return cfg;
},
@@ -249,11 +246,11 @@
!Lang.isUndefined(this.initialConfig[key])) {
this.setProperty(key, this.initialConfig[key]);
+
+ return true;
}
- return true;
-
} else {
return false;
@@ -353,7 +350,7 @@
if (queueItem) {
queueItemKey = queueItem[0];
queueItemValue = queueItem[1];
-
+
if (queueItemKey == key) {
/*
@@ -381,37 +378,37 @@
}
if (property.supercedes) {
-
+
sLen = property.supercedes.length;
-
+
for (s = 0; s < sLen; s++) {
-
+
supercedesCheck = property.supercedes[s];
qLen = this.eventQueue.length;
-
+
for (q = 0; q < qLen; q++) {
queueItemCheck = this.eventQueue[q];
-
+
if (queueItemCheck) {
queueItemCheckKey = queueItemCheck[0];
queueItemCheckValue = queueItemCheck[1];
-
+
if (queueItemCheckKey ==
supercedesCheck.toLowerCase() ) {
-
+
this.eventQueue.push([queueItemCheckKey,
queueItemCheckValue]);
-
+
this.eventQueue[q] = null;
break;
-
+
}
}
}
}
}
-
+
return true;
} else {
return false;
@@ -459,13 +456,23 @@
*/
applyConfig: function (userConfig, init) {
- var prop;
-
+ var sKey,
+ oConfig;
+
if (init) {
- this.initialConfig = userConfig;
+ oConfig = {};
+ for (sKey in userConfig) {
+ if (Lang.hasOwnProperty(userConfig, sKey)) {
+ oConfig[sKey.toLowerCase()] = userConfig[sKey];
+ }
+ }
+ this.initialConfig = oConfig;
}
- for (prop in userConfig) {
- this.queueProperty(prop, userConfig[prop]);
+
+ for (sKey in userConfig) {
+ if (Lang.hasOwnProperty(userConfig, sKey)) {
+ this.queueProperty(sKey, userConfig[sKey]);
+ }
}
},
@@ -475,11 +482,13 @@
* @method refresh
*/
refresh: function () {
-
+
var prop;
-
+
for (prop in this.config) {
- this.refireEvent(prop);
+ if (Lang.hasOwnProperty(this.config, prop)) {
+ this.refireEvent(prop);
+ }
}
},
@@ -503,9 +512,14 @@
key = queueItem[0];
value = queueItem[1];
property = this.config[key];
-
+
property.value = value;
-
+
+ // Clear out queue entry, to avoid it being
+ // re-added to the queue by any queueProperty/supercedes
+ // calls which are invoked during fireEvent
+ this.eventQueue[i] = null;
+
this.fireEvent(key,value);
}
}
@@ -533,19 +547,12 @@
var property = this.config[key.toLowerCase()];
if (property && property.event) {
-
if (!Config.alreadySubscribed(property.event, handler, obj)) {
-
property.event.subscribe(handler, obj, override);
-
}
-
return true;
-
} else {
-
return false;
-
}
},
@@ -665,32 +672,23 @@
i;
if (nSubscribers > 0) {
-
i = nSubscribers - 1;
-
do {
-
subsc = evt.subscribers[i];
-
if (subsc && subsc.obj == obj && subsc.fn == fn) {
-
return true;
-
- }
-
+ }
}
while (i--);
-
}
-
+
return false;
-
+
};
-
+
YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
}());
-
/**
* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
* used for adding, subtracting, and comparing dates.
@@ -742,6 +740,19 @@
* @type Number
*/
ONE_DAY_MS : 1000*60*60*24,
+
+ /**
+ * Constant field representing the date in first week of January
+ * which identifies the first week of the year.
+ *
+ * In the U.S, Jan 1st is normally used based on a Sunday start of week.
+ * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
+ *
+ * @property WEEK_ONE_JAN_DATE
+ * @static
+ * @type Number
+ */
+ WEEK_ONE_JAN_DATE : 1,
/**
* Adds the specified amount of time to the this instance.
@@ -758,7 +769,6 @@
var newMonth = date.getMonth() + amount;
var years = 0;
-
if (newMonth < 0) {
while (newMonth < 0) {
newMonth += 12;
@@ -770,24 +780,56 @@
years += 1;
}
}
-
+
d.setMonth(newMonth);
d.setFullYear(date.getFullYear() + years);
break;
case this.DAY:
- d.setDate(date.getDate() + amount);
+ this._addDays(d, amount);
+ // d.setDate(date.getDate() + amount);
break;
case this.YEAR:
d.setFullYear(date.getFullYear() + amount);
break;
case this.WEEK:
- d.setDate(date.getDate() + (amount * 7));
+ this._addDays(d, (amount * 7));
+ // d.setDate(date.getDate() + (amount * 7));
break;
}
return d;
},
/**
+ * Private helper method to account for bug in Safari 2 (webkit < 420)
+ * when Date.setDate(n) is called with n less than -128 or greater than 127.
+ *
+ * Fix approach and original findings are available here:
+ * http://brianary.blogspot.com/2006/03/safari-date-bug.html
+ *
+ * @method _addDays
+ * @param {Date} d JavaScript date object
+ * @param {Number} nDays The number of days to add to the date object (can be negative)
+ * @private
+ */
+ _addDays : function(d, nDays) {
+ if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
+ if (nDays < 0) {
+ // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
+ for(var min = -128; nDays < min; nDays -= min) {
+ d.setDate(d.getDate() + min);
+ }
+ } else {
+ // Ensure we don't go above 96 + 31 = 127
+ for(var max = 96; nDays > max; nDays -= max) {
+ d.setDate(d.getDate() + max);
+ }
+ }
+ // nDays should be remainder between -128 and 96
+ }
+ d.setDate(d.getDate() + nDays);
+ },
+
+ /**
* Subtracts the specified amount of time from the this instance.
* @method subtract
* @param {Date} date The JavaScript Date object to perform subtraction on
@@ -854,7 +896,7 @@
* @return {Date} January 1 of the calendar year specified.
*/
getJan1 : function(calendarYear) {
- return new Date(calendarYear,0,1);
+ return this.getDate(calendarYear,0,1);
},
/**
@@ -874,30 +916,79 @@
},
/**
- * 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.
+ * Calculates the week number for the given date. Can currently support standard
+ * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
+ * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
+ *
* @method getWeekNumber
- * @param {Date} date The JavaScript date for which to find the week number
- * @param {Number} calendarYear OPTIONAL - The calendar year to use for determining the week number. Default is
- * the calendar year of parameter "date".
- * @return {Number} The week number of the given date.
+ * @param {Date} date The JavaScript date for which to find the week number
+ * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
+ * Defaults to 0
+ * @param {Number} janDate The date in the first week of January which defines week one for the year
+ * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
+ * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
+ *
+ * @return {Number} The number of the week containing the given date.
*/
- getWeekNumber : function(date, calendarYear) {
- date = this.clearTime(date);
- var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
+ getWeekNumber : function(date, firstDayOfWeek, janDate) {
- var jan1 = new Date(nearestThurs.getFullYear(),0,1);
- var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
+ // Setup Defaults
+ firstDayOfWeek = firstDayOfWeek || 0;
+ janDate = janDate || this.WEEK_ONE_JAN_DATE;
- var weekNum = Math.ceil((dayOfYear)/ 7);
+ var targetDate = this.clearTime(date),
+ startOfWeek,
+ endOfWeek;
+
+ if (targetDate.getDay() === firstDayOfWeek) {
+ startOfWeek = targetDate;
+ } else {
+ startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
+ }
+
+ var startYear = startOfWeek.getFullYear(),
+ startTime = startOfWeek.getTime();
+
+ // DST shouldn't be a problem here, math is quicker than setDate();
+ endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
+
+ var weekNum;
+ if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
+ // If years don't match, endOfWeek is in Jan. and if the
+ // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
+ weekNum = 1;
+ } else {
+ // Get the 1st day of the 1st week, and
+ // find how many days away we are from it.
+ var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
+ weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
+
+ // Round days to smoothen out 1 hr DST diff
+ var daysDiff = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
+
+ // Calc. Full Weeks
+ var rem = daysDiff % 7;
+ var weeksDiff = (daysDiff - rem)/7;
+ weekNum = weeksDiff + 1;
+ }
return weekNum;
},
/**
+ * Get the first day of the week, for the give date.
+ * @param {Date} dt The date in the week for which the first day is required.
+ * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
+ * @return {Date} The first day of the week
+ */
+ getFirstDayOfWeek : function (dt, startOfWeek) {
+ startOfWeek = startOfWeek || 0;
+ var dayOfWeekIndex = dt.getDay(),
+ dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
+
+ return this.subtract(dt, this.DAY, dayOfWeek);
+ },
+
+ /**
* Determines if a given week overlaps two different years.
* @method isYearOverlapWeek
* @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
@@ -934,7 +1025,7 @@
* @return {Date} The JavaScript Date representing the first day of the month
*/
findMonthStart : function(date) {
- var start = new Date(date.getFullYear(), date.getMonth(), 1);
+ var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
return start;
},
@@ -960,17 +1051,55 @@
clearTime : function(date) {
date.setHours(12,0,0,0);
return date;
+ },
+
+ /**
+ * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
+ * are set to 0. The method allows Date instances to be created with the a year less than 100. "new Date(year, month, date)" implementations
+ * set the year to 19xx if a year (xx) which is less than 100 is provided.
+ *
+ * NOTE:Validation on argument values is not performed. It is the caller's responsibility to ensure
+ * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
+ *
+ * @method getDate
+ * @param {Number} y Year.
+ * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
+ * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
+ * @return {Date} The JavaScript date object with year, month, date set as provided.
+ */
+ getDate : function(y, m, d) {
+ var dt = null;
+ if (YAHOO.lang.isUndefined(d)) {
+ d = 1;
+ }
+ if (y >= 100) {
+ dt = new Date(y, m, d);
+ } else {
+ dt = new Date();
+ dt.setFullYear(y);
+ dt.setMonth(m);
+ dt.setDate(d);
+ dt.setHours(0,0,0,0);
+ }
+ return dt;
}
};
/**
-* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month or multi-month interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
+* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month or
+* multi-month interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
* @module calendar
-* @title Calendar
-* @namespace YAHOO.widget
+* @title Calendar
+* @namespace YAHOO.widget
* @requires yahoo,dom,event
*/
+(function(){
+ var Dom = YAHOO.util.Dom,
+ Event = YAHOO.util.Event,
+ Lang = YAHOO.lang,
+ DateMath = YAHOO.widget.DateMath;
+
/**
* Calendar 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
@@ -979,19 +1108,40 @@
*
To construct the placeholder for the calendar widget, the code is as
* follows:
*
-*
+*
*
*
+*
+* NOTE: As of 2.4.0, the constructor's ID argument is optional.
+* The Calendar can be constructed by simply providing a container ID string,
+* or a reference to a container DIV HTMLElement (the element needs to exist
+* in the document).
+*
+* E.g.:
+*
+* var c = new YAHOO.widget.Calendar("calContainer", configOptions);
+*
+* or:
+*
+* var containerDiv = YAHOO.util.Dom.get("calContainer");
+* var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
+*
+*
+*
+* If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
+* For example if an ID is not provided, and the container's ID is "calContainer", the Calendar's ID will be set to "calContainer_t".
+*
+*
* @namespace YAHOO.widget
* @class Calendar
* @constructor
-* @param {String} id The id of the table element that will represent the calendar widget
-* @param {String} containerId The id of the container div element that will wrap the calendar table
-* @param {Object} config The configuration object containing the Calendar's arguments
+* @param {String} id optional The id of the table element that will represent the Calendar widget. As of 2.4.0, this argument is optional.
+* @param {String | HTMLElement} container The id of the container div element that will wrap the Calendar table, or a reference to a DIV element which exists in the document.
+* @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
*/
-YAHOO.widget.Calendar = function(id, containerId, config) {
- this.init(id, containerId, config);
-};
+function Calendar(id, containerId, config) {
+ this.init.apply(this, arguments);
+}
/**
* The path to be used for images loaded for the Calendar
@@ -1000,7 +1150,7 @@
* @deprecated You can now customize images by overriding the calclose, calnavleft and calnavright default CSS classes for the close icon, left arrow and right arrow respectively
* @type String
*/
-YAHOO.widget.Calendar.IMG_ROOT = null;
+Calendar.IMG_ROOT = null;
/**
* Type constant used for renderers to represent an individual date (M/D/Y)
@@ -1009,7 +1159,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.DATE = "D";
+Calendar.DATE = "D";
/**
* Type constant used for renderers to represent an individual date across any year (M/D)
@@ -1018,7 +1168,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.MONTH_DAY = "MD";
+Calendar.MONTH_DAY = "MD";
/**
* Type constant used for renderers to represent a weekday
@@ -1027,7 +1177,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.WEEKDAY = "WD";
+Calendar.WEEKDAY = "WD";
/**
* Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
@@ -1036,7 +1186,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.RANGE = "R";
+Calendar.RANGE = "R";
/**
* Type constant used for renderers to represent a month across any year
@@ -1045,7 +1195,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.MONTH = "M";
+Calendar.MONTH = "M";
/**
* Constant that represents the total number of date cells that are displayed in a given month
@@ -1054,7 +1204,7 @@
* @final
* @type Number
*/
-YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
+Calendar.DISPLAY_DAYS = 42;
/**
* Constant used for halting the execution of the remainder of the render stack
@@ -1063,7 +1213,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.STOP_RENDER = "S";
+Calendar.STOP_RENDER = "S";
/**
* Constant used to represent short date field string formats (e.g. Tu or Feb)
@@ -1072,7 +1222,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.SHORT = "short";
+Calendar.SHORT = "short";
/**
* Constant used to represent long date field string formats (e.g. Monday or February)
@@ -1081,7 +1231,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.LONG = "long";
+Calendar.LONG = "long";
/**
* Constant used to represent medium date field string formats (e.g. Mon)
@@ -1090,7 +1240,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.MEDIUM = "medium";
+Calendar.MEDIUM = "medium";
/**
* Constant used to represent single character date field string formats (e.g. M, T, W)
@@ -1099,7 +1249,7 @@
* @final
* @type String
*/
-YAHOO.widget.Calendar.ONE_CHAR = "1char";
+Calendar.ONE_CHAR = "1char";
/**
* The set of default Config property keys and values for the Calendar
@@ -1109,7 +1259,7 @@
* @private
* @type Object
*/
-YAHOO.widget.Calendar._DEFAULT_CONFIG = {
+Calendar._DEFAULT_CONFIG = {
// Default values for pagedate and selected are not class level constants - they are set during instance creation
PAGEDATE : {key:"pagedate", value:null},
SELECTED : {key:"selected", value:null},
@@ -1147,9 +1297,21 @@
MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
- MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""}
+ MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""},
+ NAV: {key:"navigator", value: null},
+ STRINGS : {
+ key:"strings",
+ value: {
+ previousMonth : "Previous Month",
+ nextMonth : "Next Month",
+ close: "Close"
+ },
+ supercedes : ["close", "title"]
+ }
};
+var DEF_CFG = Calendar._DEFAULT_CONFIG;
+
/**
* The set of Custom Event types supported by the Calendar
* @property YAHOO.widget.Calendar._EVENT_TYPES
@@ -1158,16 +1320,28 @@
* @private
* @type Object
*/
-YAHOO.widget.Calendar._EVENT_TYPES = {
+Calendar._EVENT_TYPES = {
BEFORE_SELECT : "beforeSelect",
SELECT : "select",
BEFORE_DESELECT : "beforeDeselect",
DESELECT : "deselect",
CHANGE_PAGE : "changePage",
BEFORE_RENDER : "beforeRender",
RENDER : "render",
+ BEFORE_DESTROY : "beforeDestroy",
+ DESTROY : "destroy",
RESET : "reset",
- CLEAR : "clear"
+ CLEAR : "clear",
+ BEFORE_HIDE : "beforeHide",
+ HIDE : "hide",
+ BEFORE_SHOW : "beforeShow",
+ SHOW : "show",
+ BEFORE_HIDE_NAV : "beforeHideNav",
+ HIDE_NAV : "hideNav",
+ BEFORE_SHOW_NAV : "beforeShowNav",
+ SHOW_NAV : "showNav",
+ BEFORE_RENDER_NAV : "beforeRenderNav",
+ RENDER_NAV : "renderNav"
};
/**
@@ -1178,7 +1352,7 @@
* @private
* @type Object
*/
-YAHOO.widget.Calendar._STYLES = {
+Calendar._STYLES = {
CSS_ROW_HEADER: "calrowhead",
CSS_ROW_FOOTER: "calrowfoot",
CSS_CELL : "calcell",
@@ -1200,6 +1374,7 @@
CSS_CONTAINER : "yui-calcontainer",
CSS_NAV_LEFT : "calnavleft",
CSS_NAV_RIGHT : "calnavright",
+ CSS_NAV : "calnav",
CSS_CLOSE : "calclose",
CSS_CELL_TOP : "calcelltop",
CSS_CELL_LEFT : "calcellleft",
@@ -1212,7 +1387,7 @@
CSS_CELL_HIGHLIGHT4 : "highlight4"
};
-YAHOO.widget.Calendar.prototype = {
+Calendar.prototype = {
/**
* The configuration object used to set up the calendars various locale and style options.
@@ -1243,7 +1418,7 @@
* @type HTMLTableCellElement[]
*/
cells : 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].
* @property cellDates
@@ -1252,13 +1427,20 @@
cellDates : null,
/**
- * The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
+ * The id that uniquely identifies this Calendar.
* @property id
* @type String
*/
id : null,
/**
+ * The unique id associated with the Calendar's container
+ * @property containerId
+ * @type String
+ */
+ containerId: 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.
* @property oDomContainer
* @type HTMLElement
@@ -1288,6 +1470,14 @@
_renderStack : null,
/**
+ * A reference to the CalendarNavigator instance created for this Calendar.
+ * Will be null if the "navigator" configuration property has not been set
+ * @property oNavigator
+ * @type CalendarNavigator
+ */
+ oNavigator : null,
+
+ /**
* The private list of initially selected dates.
* @property _selectedDates
* @private
@@ -1300,3652 +1490,5659 @@
* @property domEventMap
* @type Object
*/
- domEventMap : null
-};
+ domEventMap : null,
-
-
-/**
-* Initializes the Calendar widget.
-* @method init
-* @param {String} id The id of the table element that will represent the calendar widget
-* @param {String} containerId The id of the container div element that will wrap the calendar table
-* @param {Object} config The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
- this.initEvents();
- this.today = new Date();
- YAHOO.widget.DateMath.clearTime(this.today);
-
- this.id = id;
- this.oDomContainer = document.getElementById(containerId);
-
/**
- * The Config object used to hold the configuration variables for the Calendar
- * @property cfg
- * @type YAHOO.util.Config
- */
- this.cfg = new YAHOO.util.Config(this);
-
- /**
- * The local object which contains the Calendar's options
- * @property Options
- * @type Object
- */
- this.Options = {};
+ * Protected helper used to parse Calendar constructor/init arguments.
+ *
+ * As of 2.4.0, Calendar supports a simpler constructor
+ * signature. This method reconciles arguments
+ * received in the pre 2.4.0 and 2.4.0 formats.
+ *
+ * @protected
+ * @method _parseArgs
+ * @param {Array} Function "arguments" array
+ * @return {Object} Object with id, container, config properties containing
+ * the reconciled argument values.
+ **/
+ _parseArgs : function(args) {
+ /*
+ 2.4.0 Constructors signatures
- /**
- * The local object which contains the Calendar's locale settings
- * @property Locale
- * @type Object
- */
- this.Locale = {};
+ new Calendar(String)
+ new Calendar(HTMLElement)
+ new Calendar(String, ConfigObject)
+ new Calendar(HTMLElement, ConfigObject)
- this.initStyles();
+ Pre 2.4.0 Constructor signatures
- YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
- YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
-
- this.cellDates = [];
- this.cells = [];
- this.renderStack = [];
- this._renderStack = [];
+ new Calendar(String, String)
+ new Calendar(String, HTMLElement)
+ new Calendar(String, String, ConfigObject)
+ new Calendar(String, HTMLElement, ConfigObject)
+ */
+ var nArgs = {id:null, container:null, config:null};
- this.setupConfig();
-
- if (config) {
- this.cfg.applyConfig(config, true);
- }
-
- this.cfg.fireQueue();
-};
-
-/**
-* Default Config listener for the iframe property. If the iframe config property is set to true,
-* renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
-*
-* @method configIframe
-*/
-YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
- var useIframe = args[0];
-
- if (!this.parent) {
- if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
- if (useIframe) {
- var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
-
- if (pos == "absolute" || pos == "relative") {
-
- if (!YAHOO.util.Dom.inDocument(this.iframe)) {
- this.iframe = document.createElement("iframe");
- this.iframe.src = "javascript:false;";
-
- YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
-
- if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
- YAHOO.util.Dom.addClass(this.iframe, "fixedsize");
- }
-
- this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
+ if (args && args.length && args.length > 0) {
+ switch (args.length) {
+ case 1:
+ nArgs.id = null;
+ nArgs.container = args[0];
+ nArgs.config = null;
+ break;
+ case 2:
+ if (Lang.isObject(args[1]) && !args[1].tagName && !(args[1] instanceof String)) {
+ nArgs.id = null;
+ nArgs.container = args[0];
+ nArgs.config = args[1];
+ } else {
+ nArgs.id = args[0];
+ nArgs.container = args[1];
+ nArgs.config = null;
}
- }
- } else {
- if (this.iframe) {
- if (this.iframe.parentNode) {
- this.iframe.parentNode.removeChild(this.iframe);
- }
- this.iframe = null;
- }
+ break;
+ default: // 3+
+ nArgs.id = args[0];
+ nArgs.container = args[1];
+ nArgs.config = args[2];
+ break;
}
- }
- }
-};
-
-/**
-* Default handler for the "title" property
-* @method configTitle
-*/
-YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
- var title = args[0];
- var close = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.CLOSE.key);
-
- var titleDiv;
-
- if (title && title !== "") {
- titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
- titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
- titleDiv.innerHTML = title;
- this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
- YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
- } else {
- titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
-
- if (titleDiv) {
- YAHOO.util.Event.purgeElement(titleDiv);
- this.oDomContainer.removeChild(titleDiv);
- }
- if (! close) {
- YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
- }
- }
-};
-
-/**
-* Default handler for the "close" property
-* @method configClose
-*/
-YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
- var close = args[0];
- var title = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.TITLE.key);
-
- var DEPR_CLOSE_PATH = "us/my/bn/x_d.gif";
-
- var linkClose;
-
- if (close === true) {
- linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
- linkClose.href = "#";
- linkClose.className = "link-close";
- YAHOO.util.Event.addListener(linkClose, "click", function(e, cal) {cal.hide(); YAHOO.util.Event.preventDefault(e); }, this);
-
- if (YAHOO.widget.Calendar.IMG_ROOT !== null) {
- var imgClose = document.createElement("img");
- imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
- imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
- linkClose.appendChild(imgClose);
} else {
- linkClose.innerHTML = '';
}
-
- this.oDomContainer.appendChild(linkClose);
- YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
- } else {
- linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
- if (linkClose) {
- YAHOO.util.Event.purgeElement(linkClose);
- this.oDomContainer.removeChild(linkClose);
- }
- if (! title || title === "") {
- YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
- }
- }
-};
+ return nArgs;
+ },
-/**
-* Initializes Calendar's built-in CustomEvents
-* @method initEvents
-*/
-YAHOO.widget.Calendar.prototype.initEvents = function() {
-
- var defEvents = YAHOO.widget.Calendar._EVENT_TYPES;
-
/**
- * Fired before a selection is made
- * @event beforeSelectEvent
+ * Initializes the Calendar widget.
+ * @method init
+ *
+ * @param {String} id optional The id of the table element that will represent the Calendar widget. As of 2.4.0, this argument is optional.
+ * @param {String | HTMLElement} container The id of the container div element that will wrap the Calendar table, or a reference to a DIV element which exists in the document.
+ * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
*/
- this.beforeSelectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_SELECT);
+ init : function(id, container, config) {
+ // Normalize 2.4.0, pre 2.4.0 args
+ var nArgs = this._parseArgs(arguments);
- /**
- * Fired when a selection is made
- * @event selectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- this.selectEvent = new YAHOO.util.CustomEvent(defEvents.SELECT);
+ id = nArgs.id;
+ container = nArgs.container;
+ config = nArgs.config;
- /**
- * Fired before a selection is made
- * @event beforeDeselectEvent
- */
- this.beforeDeselectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_DESELECT);
+ this.oDomContainer = Dom.get(container);
- /**
- * Fired when a selection is made
- * @event deselectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- this.deselectEvent = new YAHOO.util.CustomEvent(defEvents.DESELECT);
-
- /**
- * Fired when the Calendar page is changed
- * @event changePageEvent
- */
- this.changePageEvent = new YAHOO.util.CustomEvent(defEvents.CHANGE_PAGE);
-
- /**
- * Fired before the Calendar is rendered
- * @event beforeRenderEvent
- */
- this.beforeRenderEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_RENDER);
-
- /**
- * Fired when the Calendar is rendered
- * @event renderEvent
- */
- this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
-
- /**
- * Fired when the Calendar is reset
- * @event resetEvent
- */
- this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET);
-
- /**
- * Fired when the Calendar is cleared
- * @event clearEvent
- */
- this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
-
- this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
- this.selectEvent.subscribe(this.onSelect, this, true);
- this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
- this.deselectEvent.subscribe(this.onDeselect, this, true);
- this.changePageEvent.subscribe(this.onChangePage, this, true);
- this.renderEvent.subscribe(this.onRender, this, true);
- this.resetEvent.subscribe(this.onReset, this, true);
- this.clearEvent.subscribe(this.onClear, this, true);
-};
-
-/**
-* The default event function that is attached to a date link within a calendar cell
-* when the calendar is rendered.
-* @method doSelectCell
-* @param {DOMEvent} e The event
-* @param {Calendar} cal A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
- var cell,index,d,date;
-
- var target = YAHOO.util.Event.getTarget(e);
- var tagName = target.tagName.toLowerCase();
- var defSelector = false;
-
- while (tagName != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
-
- if (!defSelector && tagName == "a" && YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
- defSelector = true;
+ if (!this.oDomContainer.id) {
+ this.oDomContainer.id = Dom.generateId();
}
-
- target = target.parentNode;
- tagName = target.tagName.toLowerCase();
- if (tagName == "html") {
- return;
+ if (!id) {
+ id = this.oDomContainer.id + "_t";
}
- }
- if (defSelector) {
- // Stop link href navigation for default renderer
- YAHOO.util.Event.preventDefault(e);
- }
+ this.id = id;
+ this.containerId = this.oDomContainer.id;
- cell = target;
+ this.initEvents();
- if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
- index = cell.id.split("cell")[1];
- d = cal.cellDates[index];
- date = new Date(d[0],d[1]-1,d[2]);
-
- var link;
+ this.today = new Date();
+ DateMath.clearTime(this.today);
- if (cal.Options.MULTI_SELECT) {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
+ /**
+ * The Config object used to hold the configuration variables for the Calendar
+ * @property cfg
+ * @type YAHOO.util.Config
+ */
+ this.cfg = new YAHOO.util.Config(this);
- var cellDate = cal.cellDates[index];
- var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
+ /**
+ * The local object which contains the Calendar's options
+ * @property Options
+ * @type Object
+ */
+ this.Options = {};
- if (cellDateIndex > -1) {
- cal.deselectCell(index);
- } else {
- cal.selectCell(index);
- }
+ /**
+ * The local object which contains the Calendar's locale settings
+ * @property Locale
+ * @type Object
+ */
+ this.Locale = {};
- } else {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
- cal.selectCell(index);
- }
- }
-};
+ this.initStyles();
-/**
-* The event that is executed when the user hovers over a cell
-* @method doCellMouseOver
-* @param {DOMEvent} e The event
-* @param {Calendar} cal A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
- var target;
- if (e) {
- target = YAHOO.util.Event.getTarget(e);
- } else {
- target = this;
- }
+ Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
+ Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
- while (target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (target.tagName.toLowerCase() == "html") {
- return;
- }
- }
+ this.cellDates = [];
+ this.cells = [];
+ this.renderStack = [];
+ this._renderStack = [];
- if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
- }
-};
+ this.setupConfig();
-/**
-* The event that is executed when the user moves the mouse out of a cell
-* @method doCellMouseOut
-* @param {DOMEvent} e The event
-* @param {Calendar} cal A reference to the calendar passed by the Event utility
-*/
-YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
- var target;
- if (e) {
- target = YAHOO.util.Event.getTarget(e);
- } else {
- target = this;
- }
-
- while (target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (target.tagName.toLowerCase() == "html") {
- return;
+ if (config) {
+ this.cfg.applyConfig(config, true);
}
- }
- if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
- }
-};
+ this.cfg.fireQueue();
+ },
-YAHOO.widget.Calendar.prototype.setupConfig = function() {
-
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
-
/**
- * The month/year representing the current visible Calendar date (mm/yyyy)
- * @config pagedate
- * @type String
- * @default today's date
+ * Default Config listener for the iframe property. If the iframe config property is set to true,
+ * renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
+ *
+ * @method configIframe
*/
- this.cfg.addProperty(defCfg.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
+ configIframe : function(type, args, obj) {
+ var useIframe = args[0];
+
+ if (!this.parent) {
+ if (Dom.inDocument(this.oDomContainer)) {
+ if (useIframe) {
+ var pos = Dom.getStyle(this.oDomContainer, "position");
+
+ if (pos == "absolute" || pos == "relative") {
+
+ if (!Dom.inDocument(this.iframe)) {
+ this.iframe = document.createElement("iframe");
+ this.iframe.src = "javascript:false;";
+
+ Dom.setStyle(this.iframe, "opacity", "0");
+
+ if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
+ Dom.addClass(this.iframe, "fixedsize");
+ }
+
+ this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
+ }
+ }
+ } else {
+ if (this.iframe) {
+ if (this.iframe.parentNode) {
+ this.iframe.parentNode.removeChild(this.iframe);
+ }
+ this.iframe = null;
+ }
+ }
+ }
+ }
+ },
/**
- * The date or range of dates representing the current Calendar selection
- * @config selected
- * @type String
- * @default []
+ * Default handler for the "title" property
+ * @method configTitle
*/
- this.cfg.addProperty(defCfg.SELECTED.key, { value:[], handler:this.configSelected } );
+ configTitle : function(type, args, obj) {
+ var title = args[0];
+ // "" disables title bar
+ if (title) {
+ this.createTitleBar(title);
+ } else {
+ var close = this.cfg.getProperty(DEF_CFG.CLOSE.key);
+ if (!close) {
+ this.removeTitleBar();
+ } else {
+ this.createTitleBar(" ");
+ }
+ }
+ },
+
/**
- * The title to display above the Calendar's month header
- * @config title
- * @type String
- * @default ""
+ * Default handler for the "close" property
+ * @method configClose
*/
- this.cfg.addProperty(defCfg.TITLE.key, { value:defCfg.TITLE.value, handler:this.configTitle } );
+ configClose : function(type, args, obj) {
+ var close = args[0],
+ title = this.cfg.getProperty(DEF_CFG.TITLE.key);
+
+ if (close) {
+ if (!title) {
+ this.createTitleBar(" ");
+ }
+ this.createCloseButton();
+ } else {
+ this.removeCloseButton();
+ if (!title) {
+ this.removeTitleBar();
+ }
+ }
+ },
/**
- * Whether or not a close button should be displayed for this Calendar
- * @config close
- * @type Boolean
- * @default false
+ * Initializes Calendar's built-in CustomEvents
+ * @method initEvents
*/
- this.cfg.addProperty(defCfg.CLOSE.key, { value:defCfg.CLOSE.value, handler:this.configClose } );
+ initEvents : function() {
- /**
- * Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
- * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
- * enabled if required.
- *
- * @config iframe
- * @type Boolean
- * @default true for IE6 and below, false for all other browsers
- */
- this.cfg.addProperty(defCfg.IFRAME.key, { value:defCfg.IFRAME.value, handler:this.configIframe, validator:this.cfg.checkBoolean } );
+ var defEvents = Calendar._EVENT_TYPES,
+ CE = YAHOO.util.CustomEvent,
+ cal = this; // To help with minification
- /**
- * The minimum selectable date in the current Calendar (mm/dd/yyyy)
- * @config mindate
- * @type String
- * @default null
- */
- this.cfg.addProperty(defCfg.MINDATE.key, { value:defCfg.MINDATE.value, handler:this.configMinDate } );
+ /**
+ * Fired before a date selection is made
+ * @event beforeSelectEvent
+ */
+ cal.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
- /**
- * The maximum selectable date in the current Calendar (mm/dd/yyyy)
- * @config maxdate
- * @type String
- * @default null
- */
- this.cfg.addProperty(defCfg.MAXDATE.key, { value:defCfg.MAXDATE.value, handler:this.configMaxDate } );
+ /**
+ * Fired when a date selection is made
+ * @event selectEvent
+ * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
+ */
+ cal.selectEvent = new CE(defEvents.SELECT);
+ /**
+ * Fired before a date or set of dates is deselected
+ * @event beforeDeselectEvent
+ */
+ cal.beforeDeselectEvent = new CE(defEvents.BEFORE_DESELECT);
- // Options properties
+ /**
+ * Fired when a date or set of dates is deselected
+ * @event deselectEvent
+ * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
+ */
+ cal.deselectEvent = new CE(defEvents.DESELECT);
+
+ /**
+ * Fired when the Calendar page is changed
+ * @event changePageEvent
+ */
+ cal.changePageEvent = new CE(defEvents.CHANGE_PAGE);
+
+ /**
+ * Fired before the Calendar is rendered
+ * @event beforeRenderEvent
+ */
+ cal.beforeRenderEvent = new CE(defEvents.BEFORE_RENDER);
+
+ /**
+ * Fired when the Calendar is rendered
+ * @event renderEvent
+ */
+ cal.renderEvent = new CE(defEvents.RENDER);
- /**
- * True if the Calendar should allow multiple selections. False by default.
- * @config MULTI_SELECT
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.MULTI_SELECT.key, { value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+ /**
+ * Fired just before the Calendar is to be destroyed
+ * @event beforeDestroyEvent
+ */
+ cal.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
- /**
- * The weekday the week begins on. Default is 0 (Sunday).
- * @config START_WEEKDAY
- * @type number
- * @default 0
- */
- this.cfg.addProperty(defCfg.START_WEEKDAY.key, { value:defCfg.START_WEEKDAY.value, handler:this.configOptions, validator:this.cfg.checkNumber } );
+ /**
+ * Fired after the Calendar is destroyed. This event should be used
+ * for notification only. When this event is fired, important Calendar instance
+ * properties, dom references and event listeners have already been
+ * removed/dereferenced, and hence the Calendar instance is not in a usable
+ * state.
+ *
+ * @event destroyEvent
+ */
+ cal.destroyEvent = new CE(defEvents.DESTROY);
- /**
- * True if the Calendar should show weekday labels. True by default.
- * @config SHOW_WEEKDAYS
- * @type Boolean
- * @default true
- */
- this.cfg.addProperty(defCfg.SHOW_WEEKDAYS.key, { value:defCfg.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+ /**
+ * Fired when the Calendar is reset
+ * @event resetEvent
+ */
+ cal.resetEvent = new CE(defEvents.RESET);
- /**
- * True if the Calendar should show week row headers. False by default.
- * @config SHOW_WEEK_HEADER
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key, { value:defCfg.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+ /**
+ * Fired when the Calendar is cleared
+ * @event clearEvent
+ */
+ cal.clearEvent = new CE(defEvents.CLEAR);
- /**
- * True if the Calendar should show week row footers. False by default.
- * @config SHOW_WEEK_FOOTER
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+ /**
+ * Fired just before the Calendar is to be shown
+ * @event beforeShowEvent
+ */
+ cal.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
- /**
- * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
- * @config HIDE_BLANK_WEEKS
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key, { value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-
- /**
- * The image that should be used for the left navigation arrow.
- * @config NAV_ARROW_LEFT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
- * @default null
- */
- this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key, { value:defCfg.NAV_ARROW_LEFT.value, handler:this.configOptions } );
+ /**
+ * Fired after the Calendar is shown
+ * @event showEvent
+ */
+ cal.showEvent = new CE(defEvents.SHOW);
- /**
- * The image that should be used for the right navigation arrow.
- * @config NAV_ARROW_RIGHT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
- * @default null
- */
- this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key, { value:defCfg.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
+ /**
+ * Fired just before the Calendar is to be hidden
+ * @event beforeHideEvent
+ */
+ cal.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
- // Locale properties
+ /**
+ * Fired after the Calendar is hidden
+ * @event hideEvent
+ */
+ cal.hideEvent = new CE(defEvents.HIDE);
- /**
- * The short month labels for the current locale.
- * @config MONTHS_SHORT
- * @type String[]
- * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
- */
- this.cfg.addProperty(defCfg.MONTHS_SHORT.key, { value:defCfg.MONTHS_SHORT.value, handler:this.configLocale } );
+ /**
+ * Fired just before the CalendarNavigator is to be shown
+ * @event beforeShowNavEvent
+ */
+ cal.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
- /**
- * The long month labels for the current locale.
- * @config MONTHS_LONG
- * @type String[]
- * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- */
- this.cfg.addProperty(defCfg.MONTHS_LONG.key, { value:defCfg.MONTHS_LONG.value, handler:this.configLocale } );
+ /**
+ * Fired after the CalendarNavigator is shown
+ * @event showNavEvent
+ */
+ cal.showNavEvent = new CE(defEvents.SHOW_NAV);
- /**
- * The 1-character weekday labels for the current locale.
- * @config WEEKDAYS_1CHAR
- * @type String[]
- * @default ["S", "M", "T", "W", "T", "F", "S"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key, { value:defCfg.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
+ /**
+ * Fired just before the CalendarNavigator is to be hidden
+ * @event beforeHideNavEvent
+ */
+ cal.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
- /**
- * The short weekday labels for the current locale.
- * @config WEEKDAYS_SHORT
- * @type String[]
- * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key, { value:defCfg.WEEKDAYS_SHORT.value, handler:this.configLocale } );
-
- /**
- * The medium weekday labels for the current locale.
- * @config WEEKDAYS_MEDIUM
- * @type String[]
- * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key, { value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.configLocale } );
-
- /**
- * The long weekday labels for the current locale.
- * @config WEEKDAYS_LONG
- * @type String[]
- * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key, { value:defCfg.WEEKDAYS_LONG.value, handler:this.configLocale } );
+ /**
+ * Fired after the CalendarNavigator is hidden
+ * @event hideNavEvent
+ */
+ cal.hideNavEvent = new CE(defEvents.HIDE_NAV);
- /**
- * Refreshes the locale values used to build the Calendar.
- * @method refreshLocale
- * @private
- */
- var refreshLocale = function() {
- this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
- this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
- };
+ /**
+ * Fired just before the CalendarNavigator is to be rendered
+ * @event beforeRenderNavEvent
+ */
+ cal.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
- this.cfg.subscribeToConfigEvent(defCfg.START_WEEKDAY.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.MONTHS_SHORT.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.MONTHS_LONG.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_SHORT.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
- this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_LONG.key, refreshLocale, this, true);
-
- /**
- * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
- * @config LOCALE_MONTHS
- * @type String
- * @default "long"
- */
- this.cfg.addProperty(defCfg.LOCALE_MONTHS.key, { value:defCfg.LOCALE_MONTHS.value, handler:this.configLocaleValues } );
-
- /**
- * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
- * @config LOCALE_WEEKDAYS
- * @type String
- * @default "short"
- */
- this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key, { value:defCfg.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
+ /**
+ * Fired after the CalendarNavigator is rendered
+ * @event renderNavEvent
+ */
+ cal.renderNavEvent = new CE(defEvents.RENDER_NAV);
- /**
- * The value used to delimit individual dates in a date string passed to various Calendar functions.
- * @config DATE_DELIMITER
- * @type String
- * @default ","
- */
- this.cfg.addProperty(defCfg.DATE_DELIMITER.key, { value:defCfg.DATE_DELIMITER.value, handler:this.configLocale } );
+ cal.beforeSelectEvent.subscribe(cal.onBeforeSelect, this, true);
+ cal.selectEvent.subscribe(cal.onSelect, this, true);
+ cal.beforeDeselectEvent.subscribe(cal.onBeforeDeselect, this, true);
+ cal.deselectEvent.subscribe(cal.onDeselect, this, true);
+ cal.changePageEvent.subscribe(cal.onChangePage, this, true);
+ cal.renderEvent.subscribe(cal.onRender, this, true);
+ cal.resetEvent.subscribe(cal.onReset, this, true);
+ cal.clearEvent.subscribe(cal.onClear, this, true);
+ },
/**
- * The value used to delimit date fields in a date string passed to various Calendar functions.
- * @config DATE_FIELD_DELIMITER
- * @type String
- * @default "/"
- */
- this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key, { value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The value used to delimit date ranges in a date string passed to various Calendar functions.
- * @config DATE_RANGE_DELIMITER
- * @type String
- * @default "-"
+ * The default event handler for clicks on the "Previous Month" navigation UI
+ *
+ * @method doPreviousMonthNav
+ * @param {DOMEvent} e The DOM event
+ * @param {Calendar} cal A reference to the calendar
*/
- this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key, { value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
+ doPreviousMonthNav : function(e, cal) {
+ Event.preventDefault(e);
+ // previousMonth invoked in a timeout, to allow
+ // event to bubble up, with correct target. Calling
+ // previousMonth, will call render which will remove
+ // HTML which generated the event, resulting in an
+ // invalid event target in certain browsers.
+ setTimeout(function() {
+ cal.previousMonth();
+ var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_LEFT, "a", cal.oDomContainer);
+ if (navs && navs[0]) {
+ try {
+ navs[0].focus();
+ } catch (e) {
+ // ignore
+ }
+ }
+ }, 0);
+ },
/**
- * The position of the month in a month/year date string
- * @config MY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key, { value:defCfg.MY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ * The default event handler for clicks on the "Next Month" navigation UI
+ *
+ * @method doNextMonthNav
+ * @param {DOMEvent} e The DOM event
+ * @param {Calendar} cal A reference to the calendar
+ */
+ doNextMonthNav : function(e, cal) {
+ Event.preventDefault(e);
+ setTimeout(function() {
+ cal.nextMonth();
+ var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_RIGHT, "a", cal.oDomContainer);
+ if (navs && navs[0]) {
+ try {
+ navs[0].focus();
+ } catch (e) {
+ // ignore
+ }
+ }
+ }, 0);
+ },
/**
- * The position of the year in a month/year date string
- * @config MY_YEAR_POSITION
- * @type Number
- * @default 2
+ * The default event handler for date cell selection. Currently attached to
+ * the Calendar's bounding box, referenced by it's oDomContainer property.
+ *
+ * @method doSelectCell
+ * @param {DOMEvent} e The DOM event
+ * @param {Calendar} cal A reference to the calendar
*/
- this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key, { value:defCfg.MY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ doSelectCell : function(e, cal) {
+ var cell, d, date, index;
- /**
- * The position of the month in a month/day date string
- * @config MD_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key, { value:defCfg.MD_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ var target = Event.getTarget(e),
+ tagName = target.tagName.toLowerCase(),
+ defSelector = false;
- /**
- * The position of the day in a month/year date string
- * @config MD_DAY_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MD_DAY_POSITION.key, { value:defCfg.MD_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ while (tagName != "td" && !Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- /**
- * The position of the month in a month/day/year date string
- * @config MDY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key, { value:defCfg.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ if (!defSelector && tagName == "a" && Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
+ defSelector = true;
+ }
- /**
- * The position of the day in a month/day/year date string
- * @config MDY_DAY_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key, { value:defCfg.MDY_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ target = target.parentNode;
+ tagName = target.tagName.toLowerCase();
- /**
- * The position of the year in a month/day/year date string
- * @config MDY_YEAR_POSITION
- * @type Number
- * @default 3
- */
- this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key, { value:defCfg.MDY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
-
- /**
- * The position of the month in the month year label string used as the Calendar header
- * @config MY_LABEL_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MY_LABEL_MONTH_POSITION.key, { value:defCfg.MY_LABEL_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ if (target == this.oDomContainer || tagName == "html") {
+ return;
+ }
+ }
- /**
- * The position of the year in the month year label string used as the Calendar header
- * @config MY_LABEL_YEAR_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MY_LABEL_YEAR_POSITION.key, { value:defCfg.MY_LABEL_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
+ if (defSelector) {
+ // Stop link href navigation for default renderer
+ Event.preventDefault(e);
+ }
- /**
- * The suffix used after the month when rendering the Calendar header
- * @config MY_LABEL_MONTH_SUFFIX
- * @type String
- * @default " "
- */
- this.cfg.addProperty(defCfg.MY_LABEL_MONTH_SUFFIX.key, { value:defCfg.MY_LABEL_MONTH_SUFFIX.value, handler:this.configLocale } );
-
- /**
- * The suffix used after the year when rendering the Calendar header
- * @config MY_LABEL_YEAR_SUFFIX
- * @type String
- * @default ""
- */
- this.cfg.addProperty(defCfg.MY_LABEL_YEAR_SUFFIX.key, { value:defCfg.MY_LABEL_YEAR_SUFFIX.value, handler:this.configLocale } );
-};
+ cell = target;
-/**
-* The default handler for the "pagedate" property
-* @method configPageDate
-*/
-YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
- this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key, this._parsePageDate(args[0]), true);
-};
+ if (Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
+ index = cal.getIndexFromId(cell.id);
+ if (index > -1) {
+ d = cal.cellDates[index];
+ if (d) {
+ date = DateMath.getDate(d[0],d[1]-1,d[2]);
+
+ var link;
-/**
-* The default handler for the "mindate" property
-* @method configMinDate
-*/
-YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
- var val = args[0];
- if (YAHOO.lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MINDATE.key, new Date(val[0],(val[1]-1),val[2]));
- }
-};
+ if (cal.Options.MULTI_SELECT) {
+ link = cell.getElementsByTagName("a")[0];
+ if (link) {
+ link.blur();
+ }
-/**
-* The default handler for the "maxdate" property
-* @method configMaxDate
-*/
-YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
- var val = args[0];
- if (YAHOO.lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MAXDATE.key, new Date(val[0],(val[1]-1),val[2]));
- }
-};
+ var cellDate = cal.cellDates[index];
+ var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
-/**
-* The default handler for the "selected" property
-* @method configSelected
-*/
-YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
- var selected = args[0];
- var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
-
- if (selected) {
- if (YAHOO.lang.isString(selected)) {
- this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
- }
- }
- if (! this._selectedDates) {
- this._selectedDates = this.cfg.getProperty(cfgSelected);
- }
-};
+ if (cellDateIndex > -1) {
+ cal.deselectCell(index);
+ } else {
+ cal.selectCell(index);
+ }
-/**
-* The default handler for all configuration options properties
-* @method configOptions
-*/
-YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
- this.Options[type.toUpperCase()] = args[0];
-};
+ } else {
+ link = cell.getElementsByTagName("a")[0];
+ if (link) {
+ link.blur();
+ }
+ cal.selectCell(index);
+ }
+ }
+ }
+ }
+ },
-/**
-* The default handler for all configuration locale properties
-* @method configLocale
-*/
-YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
- this.Locale[type.toUpperCase()] = args[0];
+ /**
+ * The event that is executed when the user hovers over a cell
+ * @method doCellMouseOver
+ * @param {DOMEvent} e The event
+ * @param {Calendar} cal A reference to the calendar passed by the Event utility
+ */
+ doCellMouseOver : function(e, cal) {
+ var target;
+ if (e) {
+ target = Event.getTarget(e);
+ } else {
+ target = this;
+ }
- this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
- this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
-};
+ while (target.tagName && target.tagName.toLowerCase() != "td") {
+ target = target.parentNode;
+ if (!target.tagName || target.tagName.toLowerCase() == "html") {
+ return;
+ }
+ }
-/**
-* The default handler for all configuration locale field length properties
-* @method configLocaleValues
-*/
-YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+ if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
+ Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
+ }
+ },
- type = type.toLowerCase();
- var val = args[0];
+ /**
+ * The event that is executed when the user moves the mouse out of a cell
+ * @method doCellMouseOut
+ * @param {DOMEvent} e The event
+ * @param {Calendar} cal A reference to the calendar passed by the Event utility
+ */
+ doCellMouseOut : function(e, cal) {
+ var target;
+ if (e) {
+ target = Event.getTarget(e);
+ } else {
+ target = this;
+ }
- switch (type) {
- case defCfg.LOCALE_MONTHS.key:
- switch (val) {
- case YAHOO.widget.Calendar.SHORT:
- this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_SHORT.key).concat();
- break;
- case YAHOO.widget.Calendar.LONG:
- this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_LONG.key).concat();
- break;
+ while (target.tagName && target.tagName.toLowerCase() != "td") {
+ target = target.parentNode;
+ if (!target.tagName || target.tagName.toLowerCase() == "html") {
+ return;
}
- break;
- case defCfg.LOCALE_WEEKDAYS.key:
- switch (val) {
- case YAHOO.widget.Calendar.ONE_CHAR:
- this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_1CHAR.key).concat();
- break;
- case YAHOO.widget.Calendar.SHORT:
- this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_SHORT.key).concat();
- break;
- case YAHOO.widget.Calendar.MEDIUM:
- this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_MEDIUM.key).concat();
- break;
- case YAHOO.widget.Calendar.LONG:
- this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_LONG.key).concat();
- break;
- }
-
- var START_WEEKDAY = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
+ }
- if (START_WEEKDAY > 0) {
- for (var w=0;w
+ * Setting this property to null (default value) or false, will disable the CalendarNavigator UI.
+ *
+ *
+ * Setting this property to true will enable the CalendarNavigatior UI with the default CalendarNavigator configuration values.
+ *
+ *
+ * This property can also be set to an object literal containing configuration properties for the CalendarNavigator UI.
+ * The configuration object expects the the following case-sensitive properties, with the "strings" property being a nested object.
+ * Any properties which are not provided will use the default values (defined in the CalendarNavigator class).
+ *
+ *
+ *
strings
+ *
Object : An object with the properties shown below, defining the string labels to use in the Navigator's UI
+ *
+ *
month
String : The string to use for the month label. Defaults to "Month".
+ *
year
String : The string to use for the year label. Defaults to "Year".
+ *
submit
String : The string to use for the submit button label. Defaults to "Okay".
+ *
cancel
String : The string to use for the cancel button label. Defaults to "Cancel".
+ *
invalidYear
String : The string to use for invalid year values. Defaults to "Year needs to be a number".
+ *
+ *
+ *
monthFormat
String : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG
+ *
initialFocus
String : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"
';
- if (this._indexOfSelectedFieldArray(workingArray) > -1) {
- cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
- }
+ return html;
+ },
+
+ /**
+ * Renders the calendar body.
+ * @method renderBody
+ * @param {Date} workingDate The current working Date being used for the render process
+ * @param {Array} html The current working HTML array
+ * @return {Array} The current working HTML array
+ */
+ renderBody : function(workingDate, html) {
- if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
- (maxdate && (workingDate.getTime() > maxdate.getTime()))
- ) {
- cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
- } else {
- cellRenderers[cellRenderers.length]=cal.styleCellDefault;
- cellRenderers[cellRenderers.length]=cal.renderCellDefault;
- }
-
- for (var x=0; x < cellRenderers.length; ++x) {
- if (cellRenderers[x].call(cal, workingDate, cell) == YAHOO.widget.Calendar.STOP_RENDER) {
- break;
- }
- }
+ var startDay = this.cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
- workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
+ this.preMonthDays = workingDate.getDay();
+ if (startDay > 0) {
+ this.preMonthDays -= startDay;
+ }
+ if (this.preMonthDays < 0) {
+ this.preMonthDays += 7;
+ }
- if (i >= 0 && i <= 6) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
- }
- if ((i % 7) === 0) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
- }
- if (((i+1) % 7) === 0) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
- }
-
- var postDays = this.postMonthDays;
- if (hideBlankWeeks && postDays >= 7) {
- var blankWeeks = Math.floor(postDays/7);
- for (var p=0;p= ((this.preMonthDays+postDays+this.monthDays)-7)) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
- }
+ this.monthDays = DateMath.findMonthEnd(workingDate).getDate();
+ this.postMonthDays = Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
- html[html.length] = tempDiv.innerHTML;
- i++;
- }
- if (showWeekFooter) { html = this.renderRowFooter(weekNum, html); }
+ workingDate = DateMath.subtract(workingDate, DateMath.DAY, this.preMonthDays);
+
+ var weekNum,
+ weekClass,
+ weekPrefix = "w",
+ cellPrefix = "_cell",
+ workingDayPrefix = "wd",
+ dayPrefix = "d",
+ cellRenderers,
+ renderer,
+ t = this.today,
+ cfg = this.cfg,
+ todayYear = t.getFullYear(),
+ todayMonth = t.getMonth(),
+ todayDate = t.getDate(),
+ useDate = cfg.getProperty(DEF_CFG.PAGEDATE.key),
+ hideBlankWeeks = cfg.getProperty(DEF_CFG.HIDE_BLANK_WEEKS.key),
+ showWeekFooter = cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key),
+ showWeekHeader = cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key),
+ mindate = cfg.getProperty(DEF_CFG.MINDATE.key),
+ maxdate = cfg.getProperty(DEF_CFG.MAXDATE.key);
- html[html.length] = '';
+ if (mindate) {
+ mindate = DateMath.clearTime(mindate);
}
- }
+ if (maxdate) {
+ maxdate = DateMath.clearTime(maxdate);
+ }
- html[html.length] = '';
+ html[html.length] = '';
- return html;
-};
+ var i = 0,
+ tempDiv = document.createElement("div"),
+ cell = document.createElement("td");
-/**
-* Renders the calendar footer. In the default implementation, there is
-* no footer.
-* @method renderFooter
-* @param {Array} html The current working HTML array
-* @return {Array} The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };
+ tempDiv.appendChild(cell);
-/**
-* Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
-* when the method is called: renderHeader, renderBody, renderFooter.
-* Refer to the documentation for those methods for information on
-* individual render tasks.
-* @method render
-*/
-YAHOO.widget.Calendar.prototype.render = function() {
- this.beforeRenderEvent.fire();
+ var cal = this.parent || this;
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
+ for (var r=0;r<6;r++) {
+ weekNum = DateMath.getWeekNumber(workingDate, startDay);
+ weekClass = weekPrefix + weekNum;
- // Find starting day of the current month
- var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty(defCfg.PAGEDATE.key));
+ // Local OOM check for performance, since we already have pagedate
+ if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
+ break;
+ } else {
+ html[html.length] = '
';
- this.resetRenderers();
- this.cellDates.length = 0;
+ if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
- YAHOO.util.Event.purgeElement(this.oDomContainer, true);
+ for (var d=0; d < 7; d++){ // Render actual days
- var html = [];
+ cellRenderers = [];
- html[html.length] = '
';
- html = this.renderHeader(html);
- html = this.renderBody(workingDate, html);
- html = this.renderFooter(html);
- html[html.length] = '
';
+ this.clearElement(cell);
+ cell.className = this.Style.CSS_CELL;
+ cell.id = this.id + cellPrefix + i;
- this.oDomContainer.innerHTML = html.join("\n");
+ if (workingDate.getDate() == todayDate &&
+ workingDate.getMonth() == todayMonth &&
+ workingDate.getFullYear() == todayYear) {
+ cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
+ }
- this.applyListeners();
- this.cells = this.oDomContainer.getElementsByTagName("td");
+ var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
+ this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
- this.cfg.refireEvent(defCfg.TITLE.key);
- this.cfg.refireEvent(defCfg.CLOSE.key);
- this.cfg.refireEvent(defCfg.IFRAME.key);
+ // Local OOM check for performance, since we already have pagedate
+ if (workingDate.getMonth() != useDate.getMonth()) {
+ cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
+ } else {
+ Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
+ Dom.addClass(cell, dayPrefix + workingDate.getDate());
- this.renderEvent.fire();
-};
+ for (var s=0;s 0) {
- this.linkLeft = linkLeft[0];
- YAHOO.util.Event.addListener(this.linkLeft, mousedown, cal.previousMonth, cal, true);
- }
+ switch (type) {
+ case Calendar.DATE:
+ month = rArray[1][1];
+ day = rArray[1][2];
+ year = rArray[1][0];
- if (linkRight && linkRight.length > 0) {
- this.linkRight = linkRight[0];
- YAHOO.util.Event.addListener(this.linkRight, mousedown, cal.nextMonth, cal, true);
- }
+ if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
+ renderer = rArray[2];
+ this.renderStack.splice(s,1);
+ }
+ break;
+ case Calendar.MONTH_DAY:
+ month = rArray[1][0];
+ day = rArray[1][1];
- if (this.domEventMap) {
- var el,elements;
- for (var cls in this.domEventMap) {
- if (YAHOO.lang.hasOwnProperty(this.domEventMap, cls)) {
- var items = this.domEventMap[cls];
+ if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
+ renderer = rArray[2];
+ this.renderStack.splice(s,1);
+ }
+ break;
+ case Calendar.RANGE:
+ var date1 = rArray[1][0],
+ date2 = rArray[1][1],
+ d1month = date1[1],
+ d1day = date1[2],
+ d1year = date1[0],
+ d1 = DateMath.getDate(d1year, d1month-1, d1day),
+ d2month = date2[1],
+ d2day = date2[2],
+ d2year = date2[0],
+ d2 = DateMath.getDate(d2year, d2month-1, d2day);
- if (! (items instanceof Array)) {
- items = [items];
- }
+ if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
+ renderer = rArray[2];
- for (var i=0;i -1) {
+ cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
+ }
+
+ if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
+ (maxdate && (workingDate.getTime() > maxdate.getTime()))
+ ) {
+ cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
+ } else {
+ cellRenderers[cellRenderers.length]=cal.styleCellDefault;
+ cellRenderers[cellRenderers.length]=cal.renderCellDefault;
+ }
+
+ for (var x=0; x < cellRenderers.length; ++x) {
+ if (cellRenderers[x].call(cal, workingDate, cell) == Calendar.STOP_RENDER) {
+ break;
+ }
+ }
+
+ workingDate.setTime(workingDate.getTime() + DateMath.ONE_DAY_MS);
+ // Just in case we crossed DST/Summertime boundaries
+ workingDate = DateMath.clearTime(workingDate);
+
+ if (i >= 0 && i <= 6) {
+ Dom.addClass(cell, this.Style.CSS_CELL_TOP);
+ }
+ if ((i % 7) === 0) {
+ Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
+ }
+ if (((i+1) % 7) === 0) {
+ Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
+ }
+
+ var postDays = this.postMonthDays;
+ if (hideBlankWeeks && postDays >= 7) {
+ var blankWeeks = Math.floor(postDays/7);
+ for (var p=0;p= ((this.preMonthDays+postDays+this.monthDays)-7)) {
+ Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
+ }
+
+ html[html.length] = tempDiv.innerHTML;
+ i++;
}
+
+ if (showWeekFooter) { html = this.renderRowFooter(weekNum, html); }
+
+ html[html.length] = '
';
}
}
- }
+
+ html[html.length] = '';
+
+ return html;
+ },
+
+ /**
+ * Renders the calendar footer. In the default implementation, there is
+ * no footer.
+ * @method renderFooter
+ * @param {Array} html The current working HTML array
+ * @return {Array} The current working HTML array
+ */
+ renderFooter : function(html) { return html; },
+
+ /**
+ * Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
+ * when the method is called: renderHeader, renderBody, renderFooter.
+ * Refer to the documentation for those methods for information on
+ * individual render tasks.
+ * @method render
+ */
+ render : function() {
+ this.beforeRenderEvent.fire();
- YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
- YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
- YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
-};
+ // Find starting day of the current month
+ var workingDate = DateMath.findMonthStart(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
-/**
-* Retrieves the Date object for the specified Calendar cell
-* @method getDateByCellId
-* @param {String} id The id of the cell
-* @return {Date} The Date object for the specified Calendar cell
-*/
-YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
- var date = this.getDateFieldsByCellId(id);
- return new Date(date[0],date[1]-1,date[2]);
-};
+ this.resetRenderers();
+ this.cellDates.length = 0;
-/**
-* Retrieves the Date object for the specified Calendar cell
-* @method getDateFieldsByCellId
-* @param {String} id The id of the cell
-* @return {Array} The array of Date fields for the specified Calendar cell
-*/
-YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
- id = id.toLowerCase().split("_cell")[1];
- id = parseInt(id, 10);
- return this.cellDates[id];
-};
+ Event.purgeElement(this.oDomContainer, true);
-// BEGIN BUILT-IN TABLE CELL RENDERERS
+ var html = [];
-/**
-* Renders a cell that falls before the minimum date or after the maximum date.
-* widget class.
-* @method renderOutOfBoundsDate
-* @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-* should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
- cell.innerHTML = workingDate.getDate();
- return YAHOO.widget.Calendar.STOP_RENDER;
-};
+ html[html.length] = '
';
+ html = this.renderHeader(html);
+ html = this.renderBody(workingDate, html);
+ html = this.renderFooter(html);
+ html[html.length] = '
';
-/**
-* Renders the row header for a week.
-* @method renderRowHeader
-* @param {Number} weekNum The week number of the current row
-* @param {Array} cell The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
- html[html.length] = '
' + weekNum + '
';
- return html;
-};
+ this.oDomContainer.innerHTML = html.join("\n");
-/**
-* Renders the row footer for a week.
-* @method renderRowFooter
-* @param {Number} weekNum The week number of the current row
-* @param {Array} cell The current working HTML array
-*/
-YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
- html[html.length] = '
' + weekNum + '
';
- return html;
-};
+ this.applyListeners();
+ this.cells = this.oDomContainer.getElementsByTagName("td");
+
+ this.cfg.refireEvent(DEF_CFG.TITLE.key);
+ this.cfg.refireEvent(DEF_CFG.CLOSE.key);
+ this.cfg.refireEvent(DEF_CFG.IFRAME.key);
-/**
-* 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.
-* @method renderCellDefault
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
- cell.innerHTML = '' + this.buildDayLabel(workingDate) + "";
-};
+ this.renderEvent.fire();
+ },
-/**
-* Styles a selectable cell.
-* @method styleCellDefault
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
-};
+ /**
+ * Applies the Calendar's DOM listeners to applicable elements.
+ * @method applyListeners
+ */
+ applyListeners : function() {
+ var root = this.oDomContainer,
+ cal = this.parent || this,
+ anchor = "a",
+ click = "click";
+ var linkLeft = Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, anchor, root),
+ linkRight = Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, anchor, root);
-/**
-* Renders a single standard calendar cell using the CSS hightlight1 style
-* @method renderCellStyleHighlight1
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
-};
+ if (linkLeft && linkLeft.length > 0) {
+ this.linkLeft = linkLeft[0];
+ Event.addListener(this.linkLeft, click, this.doPreviousMonthNav, cal, true);
+ }
-/**
-* Renders a single standard calendar cell using the CSS hightlight2 style
-* @method renderCellStyleHighlight2
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
-};
+ if (linkRight && linkRight.length > 0) {
+ this.linkRight = linkRight[0];
+ Event.addListener(this.linkRight, click, this.doNextMonthNav, cal, true);
+ }
-/**
-* Renders a single standard calendar cell using the CSS hightlight3 style
-* @method renderCellStyleHighlight3
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
-};
+ if (cal.cfg.getProperty("navigator") !== null) {
+ this.applyNavListeners();
+ }
-/**
-* Renders a single standard calendar cell using the CSS hightlight4 style
-* @method renderCellStyleHighlight4
-* @param {Date} workingDate The current working Date object being used to generate the calendar
-* @param {HTMLTableCellElement} cell The current working cell in the calendar
-*/
-YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
-};
+ if (this.domEventMap) {
+ var el,elements;
+ for (var cls in this.domEventMap) {
+ if (Lang.hasOwnProperty(this.domEventMap, cls)) {
+ var items = this.domEventMap[cls];
+
+ if (! (items instanceof Array)) {
+ items = [items];
+ }
+
+ for (var i=0;i 0) {
-/**
-* Renders the current calendar cell as a non-selectable "black-out" date using the default
-* restricted style.
-* @method renderBodyCellRestricted
-* @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
-* should not be terminated
-*/
-YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
- YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
- cell.innerHTML=workingDate.getDate();
- return YAHOO.widget.Calendar.STOP_RENDER;
-};
+ Event.addListener(navBtns, "click", function (e, obj) {
+ var target = Event.getTarget(e);
+ // this == navBtn
+ if (this === target || Dom.isAncestor(this, target)) {
+ Event.preventDefault(e);
+ }
+ var navigator = calParent.oNavigator;
+ if (navigator) {
+ var pgdate = cal.cfg.getProperty("pagedate");
+ navigator.setYear(pgdate.getFullYear());
+ navigator.setMonth(pgdate.getMonth());
+ navigator.show();
+ }
+ });
+ }
+ },
-// END BUILT-IN TABLE CELL RENDERERS
+ /**
+ * Retrieves the Date object for the specified Calendar cell
+ * @method getDateByCellId
+ * @param {String} id The id of the cell
+ * @return {Date} The Date object for the specified Calendar cell
+ */
+ getDateByCellId : function(id) {
+ var date = this.getDateFieldsByCellId(id);
+ return (date) ? DateMath.getDate(date[0],date[1]-1,date[2]) : null;
+ },
+
+ /**
+ * Retrieves the Date object for the specified Calendar cell
+ * @method getDateFieldsByCellId
+ * @param {String} id The id of the cell
+ * @return {Array} The array of Date fields for the specified Calendar cell
+ */
+ getDateFieldsByCellId : function(id) {
+ id = this.getIndexFromId(id);
+ return (id > -1) ? this.cellDates[id] : null;
+ },
-// BEGIN MONTH NAVIGATION METHODS
+ /**
+ * Find the Calendar's cell index for a given date.
+ * If the date is not found, the method returns -1.
+ *
+ * The returned index can be used to lookup the cell HTMLElement
+ * using the Calendar's cells array or passed to selectCell to select
+ * cells by index.
+ *
+ *
+ * See cells, selectCell.
+ *
+ * @method getCellIndex
+ * @param {Date} date JavaScript Date object, for which to find a cell index.
+ * @return {Number} The index of the date in Calendars cellDates/cells arrays, or -1 if the date
+ * is not on the curently rendered Calendar page.
+ */
+ getCellIndex : function(date) {
+ var idx = -1;
+ if (date) {
+ var m = date.getMonth(),
+ y = date.getFullYear(),
+ d = date.getDate(),
+ dates = this.cellDates;
-/**
-* Adds the designated number of months to the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method addMonths
-* @param {Number} count The number of months to add to the current calendar
-*/
-YAHOO.widget.Calendar.prototype.addMonths = function(count) {
- var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
- this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
- this.resetRenderers();
- this.changePageEvent.fire();
-};
+ for (var i = 0; i < dates.length; ++i) {
+ var cellDate = dates[i];
+ if (cellDate[0] === y && cellDate[1] === m+1 && cellDate[2] === d) {
+ idx = i;
+ break;
+ }
+ }
+ }
+ return idx;
+ },
-/**
-* Subtracts the designated number of months from the current calendar month, and sets the current
-* calendar page date to the new month.
-* @method subtractMonths
-* @param {Number} count The number of months to subtract from the current calendar
-*/
-YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
- var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
- this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
- this.resetRenderers();
- this.changePageEvent.fire();
-};
+ /**
+ * Given the id used to mark each Calendar cell, this method
+ * extracts the index number from the id.
+ *
+ * @param {String} strId The cell id
+ * @return {Number} The index of the cell, or -1 if id does not contain an index number
+ */
+ getIndexFromId : function(strId) {
+ var idx = -1,
+ li = strId.lastIndexOf("_cell");
-/**
-* Adds the designated number of years to the current calendar, and sets the current
-* calendar page date to the new month.
-* @method addYears
-* @param {Number} count The number of years to add to the current calendar
-*/
-YAHOO.widget.Calendar.prototype.addYears = function(count) {
- var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
- this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
- this.resetRenderers();
- this.changePageEvent.fire();
-};
+ if (li > -1) {
+ idx = parseInt(strId.substring(li + 5), 10);
+ }
-/**
-* Subtcats the designated number of years from the current calendar, and sets the current
-* calendar page date to the new month.
-* @method subtractYears
-* @param {Number} count The number of years to subtract from the current calendar
-*/
-YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
- var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
- this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
- this.resetRenderers();
- this.changePageEvent.fire();
-};
+ return idx;
+ },
+
+ // BEGIN BUILT-IN TABLE CELL RENDERERS
+
+ /**
+ * Renders a cell that falls before the minimum date or after the maximum date.
+ * widget class.
+ * @method renderOutOfBoundsDate
+ * @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+ * should not be terminated
+ */
+ renderOutOfBoundsDate : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_OOB);
+ cell.innerHTML = workingDate.getDate();
+ return Calendar.STOP_RENDER;
+ },
+
+ /**
+ * Renders the row header for a week.
+ * @method renderRowHeader
+ * @param {Number} weekNum The week number of the current row
+ * @param {Array} cell The current working HTML array
+ */
+ renderRowHeader : function(weekNum, html) {
+ html[html.length] = '
' + weekNum + '
';
+ return html;
+ },
+
+ /**
+ * Renders the row footer for a week.
+ * @method renderRowFooter
+ * @param {Number} weekNum The week number of the current row
+ * @param {Array} cell The current working HTML array
+ */
+ renderRowFooter : function(weekNum, html) {
+ html[html.length] = '
' + weekNum + '
';
+ return html;
+ },
+
+ /**
+ * 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.
+ * @method renderCellDefault
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellDefault : function(workingDate, cell) {
+ cell.innerHTML = '' + this.buildDayLabel(workingDate) + "";
+ },
+
+ /**
+ * Styles a selectable cell.
+ * @method styleCellDefault
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ styleCellDefault : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
+ },
+
+
+ /**
+ * Renders a single standard calendar cell using the CSS hightlight1 style
+ * @method renderCellStyleHighlight1
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellStyleHighlight1 : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
+ },
+
+ /**
+ * Renders a single standard calendar cell using the CSS hightlight2 style
+ * @method renderCellStyleHighlight2
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellStyleHighlight2 : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
+ },
+
+ /**
+ * Renders a single standard calendar cell using the CSS hightlight3 style
+ * @method renderCellStyleHighlight3
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellStyleHighlight3 : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
+ },
+
+ /**
+ * Renders a single standard calendar cell using the CSS hightlight4 style
+ * @method renderCellStyleHighlight4
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellStyleHighlight4 : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
+ },
+
+ /**
+ * Applies the default style used for rendering today's date to the current calendar cell
+ * @method renderCellStyleToday
+ * @param {Date} workingDate The current working Date object being used to generate the calendar
+ * @param {HTMLTableCellElement} cell The current working cell in the calendar
+ */
+ renderCellStyleToday : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
+ },
+
+ /**
+ * Applies the default style used for rendering selected dates to the current calendar cell
+ * @method renderCellStyleSelected
+ * @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+ * should not be terminated
+ */
+ renderCellStyleSelected : function(workingDate, cell) {
+ Dom.addClass(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)
+ * @method renderCellNotThisMonth
+ * @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+ * should not be terminated
+ */
+ renderCellNotThisMonth : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL_OOM);
+ cell.innerHTML=workingDate.getDate();
+ return Calendar.STOP_RENDER;
+ },
+
+ /**
+ * Renders the current calendar cell as a non-selectable "black-out" date using the default
+ * restricted style.
+ * @method renderBodyCellRestricted
+ * @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 {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
+ * should not be terminated
+ */
+ renderBodyCellRestricted : function(workingDate, cell) {
+ Dom.addClass(cell, this.Style.CSS_CELL);
+ Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
+ cell.innerHTML=workingDate.getDate();
+ return Calendar.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.
+ * @method addMonths
+ * @param {Number} count The number of months to add to the current calendar
+ */
+ addMonths : function(count) {
+ var cfgPageDate = DEF_CFG.PAGEDATE.key;
+ this.cfg.setProperty(cfgPageDate, DateMath.add(this.cfg.getProperty(cfgPageDate), DateMath.MONTH, count));
+ this.resetRenderers();
+ this.changePageEvent.fire();
+ },
+
+ /**
+ * Subtracts the designated number of months from the current calendar month, and sets the current
+ * calendar page date to the new month.
+ * @method subtractMonths
+ * @param {Number} count The number of months to subtract from the current calendar
+ */
+ subtractMonths : function(count) {
+ var cfgPageDate = DEF_CFG.PAGEDATE.key;
+ this.cfg.setProperty(cfgPageDate, DateMath.subtract(this.cfg.getProperty(cfgPageDate), DateMath.MONTH, count));
+ this.resetRenderers();
+ this.changePageEvent.fire();
+ },
-/**
-* Navigates to the next month page in the calendar widget.
-* @method nextMonth
-*/
-YAHOO.widget.Calendar.prototype.nextMonth = function() {
- this.addMonths(1);
-};
+ /**
+ * Adds the designated number of years to the current calendar, and sets the current
+ * calendar page date to the new month.
+ * @method addYears
+ * @param {Number} count The number of years to add to the current calendar
+ */
+ addYears : function(count) {
+ var cfgPageDate = DEF_CFG.PAGEDATE.key;
+ this.cfg.setProperty(cfgPageDate, DateMath.add(this.cfg.getProperty(cfgPageDate), DateMath.YEAR, count));
+ this.resetRenderers();
+ this.changePageEvent.fire();
+ },
+
+ /**
+ * Subtcats the designated number of years from the current calendar, and sets the current
+ * calendar page date to the new month.
+ * @method subtractYears
+ * @param {Number} count The number of years to subtract from the current calendar
+ */
+ subtractYears : function(count) {
+ var cfgPageDate = DEF_CFG.PAGEDATE.key;
+ this.cfg.setProperty(cfgPageDate, DateMath.subtract(this.cfg.getProperty(cfgPageDate), DateMath.YEAR, count));
+ this.resetRenderers();
+ this.changePageEvent.fire();
+ },
+
+ /**
+ * Navigates to the next month page in the calendar widget.
+ * @method nextMonth
+ */
+ nextMonth : function() {
+ this.addMonths(1);
+ },
+
+ /**
+ * Navigates to the previous month page in the calendar widget.
+ * @method previousMonth
+ */
+ previousMonth : function() {
+ this.subtractMonths(1);
+ },
+
+ /**
+ * Navigates to the next year in the currently selected month in the calendar widget.
+ * @method nextYear
+ */
+ nextYear : function() {
+ this.addYears(1);
+ },
+
+ /**
+ * Navigates to the previous year in the currently selected month in the calendar widget.
+ * @method previousYear
+ */
+ 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).
+ * @method reset
+ */
+ reset : function() {
+ this.cfg.resetProperty(DEF_CFG.SELECTED.key);
+ this.cfg.resetProperty(DEF_CFG.PAGEDATE.key);
+ this.resetEvent.fire();
+ },
+
+ /**
+ * Clears the selected dates in the current calendar widget and sets the calendar
+ * to the current month and year.
+ * @method clear
+ */
+ clear : function() {
+ this.cfg.setProperty(DEF_CFG.SELECTED.key, []);
+ this.cfg.setProperty(DEF_CFG.PAGEDATE.key, new Date(this.today.getTime()));
+ this.clearEvent.fire();
+ },
+
+ /**
+ * 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.
+ *
+ * Any dates which are OOB (out of bounds, not selectable) will not be selected and the array of
+ * selected dates passed to the selectEvent will not contain OOB dates.
+ *
+ * If all dates are OOB, the no state change will occur; beforeSelect and select events will not be fired.
+ *
+ * @method select
+ * @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 {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
+ */
+ select : function(date) {
-/**
-* Navigates to the previous month page in the calendar widget.
-* @method previousMonth
-*/
-YAHOO.widget.Calendar.prototype.previousMonth = function() {
- this.subtractMonths(1);
-};
+ var aToBeSelected = this._toFieldArray(date),
+ validDates = [],
+ selected = [],
+ cfgSelected = DEF_CFG.SELECTED.key;
-/**
-* Navigates to the next year in the currently selected month in the calendar widget.
-* @method nextYear
-*/
-YAHOO.widget.Calendar.prototype.nextYear = function() {
- this.addYears(1);
-};
+
+ for (var a=0; a < aToBeSelected.length; ++a) {
+ var toSelect = aToBeSelected[a];
-/**
-* Navigates to the previous year in the currently selected month in the calendar widget.
-* @method previousYear
-*/
-YAHOO.widget.Calendar.prototype.previousYear = function() {
- this.subtractYears(1);
-};
+ if (!this.isDateOOB(this._toDate(toSelect))) {
-// END MONTH NAVIGATION METHODS
+ if (validDates.length === 0) {
+ this.beforeSelectEvent.fire();
+ selected = this.cfg.getProperty(cfgSelected);
+ }
+ validDates.push(toSelect);
-// BEGIN SELECTION METHODS
+ if (this._indexOfSelectedFieldArray(toSelect) == -1) {
+ selected[selected.length] = toSelect;
+ }
+ }
+ }
-/**
-* Resets the calendar widget to the originally selected month and year, and
-* sets the calendar to the initial selection(s).
-* @method reset
-*/
-YAHOO.widget.Calendar.prototype.reset = function() {
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
- this.cfg.resetProperty(defCfg.SELECTED.key);
- this.cfg.resetProperty(defCfg.PAGEDATE.key);
- this.resetEvent.fire();
-};
-/**
-* Clears the selected dates in the current calendar widget and sets the calendar
-* to the current month and year.
-* @method clear
-*/
-YAHOO.widget.Calendar.prototype.clear = function() {
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
- this.cfg.setProperty(defCfg.SELECTED.key, []);
- this.cfg.setProperty(defCfg.PAGEDATE.key, new Date(this.today.getTime()));
- this.clearEvent.fire();
-};
+ if (validDates.length > 0) {
+ if (this.parent) {
+ this.parent.cfg.setProperty(cfgSelected, selected);
+ } else {
+ this.cfg.setProperty(cfgSelected, selected);
+ }
+ this.selectEvent.fire(validDates);
+ }
-/**
-* 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.
-*
-* Any dates which are OOB (out of bounds, not selectable) will not be selected and the array of
-* selected dates passed to the selectEvent will not contain OOB dates.
-*
-* If all dates are OOB, the no state change will occur; beforeSelect and select events will not be fired.
-*
-* @method select
-* @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 {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.select = function(date) {
+ return this.getSelectedDates();
+ },
+
+ /**
+ * Selects a date on the current calendar by referencing the index of the cell that should be selected.
+ * This method is used to easily select a single cell (usually with a mouse click) without having to do
+ * a full render. The selected style is applied to the cell directly.
+ *
+ * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
+ * or out of bounds cells), it will not be selected and in such a case beforeSelect and select events will not be fired.
+ *
+ * @method selectCell
+ * @param {Number} cellIndex The index of the cell to select in the current calendar.
+ * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
+ */
+ selectCell : function(cellIndex) {
- var aToBeSelected = this._toFieldArray(date);
+ var cell = this.cells[cellIndex],
+ cellDate = this.cellDates[cellIndex],
+ dCellDate = this._toDate(cellDate),
+ selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
- // Filtered array of valid dates
- var validDates = [];
- var selected = [];
- var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
-
- for (var a=0; a < aToBeSelected.length; ++a) {
- var toSelect = aToBeSelected[a];
- if (!this.isDateOOB(this._toDate(toSelect))) {
-
- if (validDates.length === 0) {
- this.beforeSelectEvent.fire();
- selected = this.cfg.getProperty(cfgSelected);
+ if (selectable) {
+
+ this.beforeSelectEvent.fire();
+
+ var cfgSelected = DEF_CFG.SELECTED.key;
+ var selected = this.cfg.getProperty(cfgSelected);
+
+ var selectDate = cellDate.concat();
+
+ if (this._indexOfSelectedFieldArray(selectDate) == -1) {
+ selected[selected.length] = selectDate;
}
-
- validDates.push(toSelect);
-
- if (this._indexOfSelectedFieldArray(toSelect) == -1) {
- selected[selected.length] = toSelect;
+ if (this.parent) {
+ this.parent.cfg.setProperty(cfgSelected, selected);
+ } else {
+ this.cfg.setProperty(cfgSelected, selected);
}
+ this.renderCellStyleSelected(dCellDate,cell);
+ this.selectEvent.fire([selectDate]);
+
+ this.doCellMouseOut.call(cell, null, this);
}
- }
+ return this.getSelectedDates();
+ },
+
+ /**
+ * Deselects a date or a collection of dates on the current calendar. This method, by default,
+ * does not call the render method explicitly. Once deselection has completed, render must be
+ * called for the changes to be reflected visually.
+ *
+ * The method will not attempt to deselect any dates which are OOB (out of bounds, and hence not selectable)
+ * and the array of deselected dates passed to the deselectEvent will not contain any OOB dates.
+ *
+ * If all dates are OOB, beforeDeselect and deselect events will not be fired.
+ *
+ * @method deselect
+ * @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 {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
+ */
+ deselect : function(date) {
- if (validDates.length > 0) {
- if (this.parent) {
- this.parent.cfg.setProperty(cfgSelected, selected);
- } else {
- this.cfg.setProperty(cfgSelected, selected);
- }
- this.selectEvent.fire(validDates);
- }
+ var aToBeDeselected = this._toFieldArray(date),
+ validDates = [],
+ selected = [],
+ cfgSelected = DEF_CFG.SELECTED.key;
- return this.getSelectedDates();
-};
-/**
-* Selects a date on the current calendar by referencing the index of the cell that should be selected.
-* This method is used to easily select a single cell (usually with a mouse click) without having to do
-* a full render. The selected style is applied to the cell directly.
-*
-* If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
-* or out of bounds cells), it will not be selected and in such a case beforeSelect and select events will not be fired.
-*
-* @method selectCell
-* @param {Number} cellIndex The index of the cell to select in the current calendar.
-* @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
-
- var cell = this.cells[cellIndex];
- var cellDate = this.cellDates[cellIndex];
- var dCellDate = this._toDate(cellDate);
+ for (var a=0; a < aToBeDeselected.length; ++a) {
+ var toDeselect = aToBeDeselected[a];
- var selectable = YAHOO.util.Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
+ if (!this.isDateOOB(this._toDate(toDeselect))) {
+
+ if (validDates.length === 0) {
+ this.beforeDeselectEvent.fire();
+ selected = this.cfg.getProperty(cfgSelected);
+ }
+
+ validDates.push(toDeselect);
+
+ var index = this._indexOfSelectedFieldArray(toDeselect);
+ if (index != -1) {
+ selected.splice(index,1);
+ }
+ }
+ }
+
+
+ if (validDates.length > 0) {
+ if (this.parent) {
+ this.parent.cfg.setProperty(cfgSelected, selected);
+ } else {
+ this.cfg.setProperty(cfgSelected, selected);
+ }
+ this.deselectEvent.fire(validDates);
+ }
+
+ return this.getSelectedDates();
+ },
+
+ /**
+ * Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
+ * This method is used to easily deselect a single cell (usually with a mouse click) without having to do
+ * a full render. The selected style is removed from the cell directly.
+ *
+ * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
+ * or out of bounds cells), the method will not attempt to deselect it and in such a case, beforeDeselect and
+ * deselect events will not be fired.
+ *
+ * @method deselectCell
+ * @param {Number} cellIndex The index of the cell to deselect in the current calendar.
+ * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
+ */
+ deselectCell : function(cellIndex) {
+ var cell = this.cells[cellIndex],
+ cellDate = this.cellDates[cellIndex],
+ cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
- if (selectable) {
+ var selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
- this.beforeSelectEvent.fire();
+ if (selectable) {
- var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
- var selected = this.cfg.getProperty(cfgSelected);
+ this.beforeDeselectEvent.fire();
- var selectDate = cellDate.concat();
+ var selected = this.cfg.getProperty(DEF_CFG.SELECTED.key),
+ dCellDate = this._toDate(cellDate),
+ selectDate = cellDate.concat();
- if (this._indexOfSelectedFieldArray(selectDate) == -1) {
- selected[selected.length] = selectDate;
+ if (cellDateIndex > -1) {
+ if (this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getMonth() == dCellDate.getMonth() &&
+ this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getFullYear() == dCellDate.getFullYear()) {
+ Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
+ }
+ selected.splice(cellDateIndex, 1);
+ }
+
+ if (this.parent) {
+ this.parent.cfg.setProperty(DEF_CFG.SELECTED.key, selected);
+ } else {
+ this.cfg.setProperty(DEF_CFG.SELECTED.key, selected);
+ }
+
+ this.deselectEvent.fire([selectDate]);
}
+
+ return this.getSelectedDates();
+ },
+
+ /**
+ * Deselects all dates on the current calendar.
+ * @method deselectAll
+ * @return {Date[]} 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.
+ */
+ deselectAll : function() {
+ this.beforeDeselectEvent.fire();
+
+ var cfgSelected = DEF_CFG.SELECTED.key,
+ selected = this.cfg.getProperty(cfgSelected),
+ count = selected.length,
+ sel = selected.concat();
+
if (this.parent) {
- this.parent.cfg.setProperty(cfgSelected, selected);
+ this.parent.cfg.setProperty(cfgSelected, []);
} else {
- this.cfg.setProperty(cfgSelected, selected);
+ this.cfg.setProperty(cfgSelected, []);
}
- this.renderCellStyleSelected(dCellDate,cell);
- this.selectEvent.fire([selectDate]);
+
+ if (count > 0) {
+ this.deselectEvent.fire(sel);
+ }
+
+ 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]].
+ * @method _toFieldArray
+ * @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[](Number[])} Array of date field arrays
+ */
+ _toFieldArray : function(date) {
+ var returnDate = [];
+
+ if (date instanceof Date) {
+ returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
+ } else if (Lang.isString(date)) {
+ returnDate = this._parseDates(date);
+ } else if (Lang.isArray(date)) {
+ for (var i=0;i maxDate.getTime()));
+ },
+
+ /**
+ * Parses a pagedate configuration property value. The value can either be specified as a string of form "mm/yyyy" or a Date object
+ * and is parsed into a Date object normalized to the first day of the month. If no value is passed in, the month and year from today's date are used to create the Date object
+ * @method _parsePageDate
+ * @private
+ * @param {Date|String} date Pagedate value which needs to be parsed
+ * @return {Date} The Date object representing the pagedate
+ */
+ _parsePageDate : function(date) {
+ var parsedDate;
- this.doCellMouseOut.call(cell, null, this);
- }
+ if (date) {
+ if (date instanceof Date) {
+ parsedDate = DateMath.findMonthStart(date);
+ } else {
+ var month, year, aMonthYear;
+ aMonthYear = date.split(this.cfg.getProperty(DEF_CFG.DATE_FIELD_DELIMITER.key));
+ month = parseInt(aMonthYear[this.cfg.getProperty(DEF_CFG.MY_MONTH_POSITION.key)-1], 10)-1;
+ year = parseInt(aMonthYear[this.cfg.getProperty(DEF_CFG.MY_YEAR_POSITION.key)-1], 10);
- return this.getSelectedDates();
-};
+ parsedDate = DateMath.getDate(year, month, 1);
+ }
+ } else {
+ parsedDate = DateMath.getDate(this.today.getFullYear(), this.today.getMonth(), 1);
+ }
+ return parsedDate;
+ },
+
+ // END UTILITY METHODS
+
+ // BEGIN EVENT HANDLERS
+
+ /**
+ * Event executed before a date is selected in the calendar widget.
+ * @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
+ */
+ onBeforeSelect : function() {
+ if (this.cfg.getProperty(DEF_CFG.MULTI_SELECT.key) === false) {
+ if (this.parent) {
+ this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
+ this.parent.deselectAll();
+ } else {
+ this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
+ this.deselectAll();
+ }
+ }
+ },
+
+ /**
+ * Event executed when a date is selected in the calendar widget.
+ * @param {Array} selected An array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
+ * @deprecated Event handlers for this event should be susbcribed to selectEvent.
+ */
+ onSelect : function(selected) { },
+
+ /**
+ * Event executed before a date is deselected in the calendar widget.
+ * @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
+ */
+ onBeforeDeselect : function() { },
+
+ /**
+ * Event executed when a date is deselected in the calendar widget.
+ * @param {Array} selected An array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
+ * @deprecated Event handlers for this event should be susbcribed to deselectEvent.
+ */
+ onDeselect : function(deselected) { },
+
+ /**
+ * Event executed when the user navigates to a different calendar page.
+ * @deprecated Event handlers for this event should be susbcribed to changePageEvent.
+ */
+ onChangePage : function() {
+ this.render();
+ },
-/**
-* Deselects a date or a collection of dates on the current calendar. This method, by default,
-* does not call the render method explicitly. Once deselection has completed, render must be
-* called for the changes to be reflected visually.
-*
-* The method will not attempt to deselect any dates which are OOB (out of bounds, and hence not selectable)
-* and the array of deselected dates passed to the deselectEvent will not contain any OOB dates.
-*
-* If all dates are OOB, beforeDeselect and deselect events will not be fired.
-*
-* @method deselect
-* @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 {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.Calendar.prototype.deselect = function(date) {
+ /**
+ * Event executed when the calendar widget is rendered.
+ * @deprecated Event handlers for this event should be susbcribed to renderEvent.
+ */
+ onRender : function() { },
- var aToBeDeselected = this._toFieldArray(date);
+ /**
+ * Event executed when the calendar widget is reset to its original state.
+ * @deprecated Event handlers for this event should be susbcribed to resetEvemt.
+ */
+ onReset : function() { this.render(); },
- var validDates = [];
- var selected = [];
- var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+ /**
+ * Event executed when the calendar widget is completely cleared to the current month with no selections.
+ * @deprecated Event handlers for this event should be susbcribed to clearEvent.
+ */
+ onClear : function() { this.render(); },
+
+ /**
+ * Validates the calendar widget. This method has no default implementation
+ * and must be extended by subclassing the widget.
+ * @return Should return true if the widget validates, and false if
+ * it doesn't.
+ * @type Boolean
+ */
+ validate : function() { return true; },
+
+ // END EVENT HANDLERS
+
+ // BEGIN DATE PARSE METHODS
+
+ /**
+ * Converts a date string to a date field array
+ * @private
+ * @param {String} sDate Date string. Valid formats are mm/dd and mm/dd/yyyy.
+ * @return A date field array representing the string passed to the method
+ * @type Array[](Number[])
+ */
+ _parseDate : function(sDate) {
+ var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER),
+ rArray;
+
+ if (aDate.length == 2) {
+ rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
+ rArray.type = Calendar.MONTH_DAY;
+ } else {
+ rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
+ rArray.type = Calendar.DATE;
+ }
+
+ for (var i=0;i 0) {
- if (this.parent) {
- this.parent.cfg.setProperty(cfgSelected, selected);
- } else {
- this.cfg.setProperty(cfgSelected, selected);
+ /**
+ * Adds a weekday to the render stack. The function reference passed to this method will be executed
+ * when a date cell matches the weekday passed to this method.
+ * @method addWeekdayRenderer
+ * @param {Number} weekday The weekday (Sunday = 1, Monday = 2 ... Saturday = 7) to associate with this renderer
+ * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
+ */
+ addWeekdayRenderer : function(weekday, fnRender) {
+ this._addRenderer(Calendar.WEEKDAY,[weekday],fnRender);
+ },
+
+ // END RENDERER METHODS
+
+ // BEGIN CSS METHODS
+
+ /**
+ * Removes all styles from all body cells in the current calendar table.
+ * @method clearAllBodyCellStyles
+ * @param {style} style The CSS class name to remove from all calendar body cells
+ */
+ clearAllBodyCellStyles : function(style) {
+ for (var c=0;c -1) {
- if (this.cfg.getProperty(defCfg.PAGEDATE.key).getMonth() == dCellDate.getMonth() &&
- this.cfg.getProperty(defCfg.PAGEDATE.key).getFullYear() == dCellDate.getFullYear()) {
- YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
- }
- selected.splice(cellDateIndex, 1);
+ /// END GETTER/SETTER METHODS ///
+
+ /**
+ * Hides the Calendar's outer container from view.
+ * @method hide
+ */
+ hide : function() {
+ if (this.beforeHideEvent.fire()) {
+ this.oDomContainer.style.display = "none";
+ this.hideEvent.fire();
}
+ },
- if (this.parent) {
- this.parent.cfg.setProperty(defCfg.SELECTED.key, selected);
- } else {
- this.cfg.setProperty(defCfg.SELECTED.key, selected);
+ /**
+ * Shows the Calendar's outer container.
+ * @method show
+ */
+ show : function() {
+ if (this.beforeShowEvent.fire()) {
+ this.oDomContainer.style.display = "block";
+ this.showEvent.fire();
}
+ },
- this.deselectEvent.fire(selectDate);
- }
+ /**
+ * Returns a string representing the current browser.
+ * @deprecated As of 2.3.0, environment information is available in YAHOO.env.ua
+ * @see YAHOO.env.ua
+ * @property browser
+ * @type String
+ */
+ browser : (function() {
+ var ua = navigator.userAgent.toLowerCase();
+ if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
+ return 'opera';
+ } else if (ua.indexOf('msie 7')!=-1) { // IE7
+ return 'ie7';
+ } else if (ua.indexOf('msie') !=-1) { // IE
+ return 'ie';
+ } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
+ return 'safari';
+ } else if (ua.indexOf('gecko') != -1) { // Gecko
+ return 'gecko';
+ } else {
+ return false;
+ }
+ })(),
+ /**
+ * Returns a string representation of the object.
+ * @method toString
+ * @return {String} A string representation of the Calendar object.
+ */
+ toString : function() {
+ return "Calendar " + this.id;
+ },
- return this.getSelectedDates();
-};
+ /**
+ * Destroys the Calendar instance. The method will remove references
+ * to HTML elements, remove any event listeners added by the Calendar,
+ * and destroy the Config and CalendarNavigator instances it has created.
+ *
+ * @method destroy
+ */
+ destroy : function() {
-/**
-* Deselects all dates on the current calendar.
-* @method deselectAll
-* @return {Date[]} 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.
-*/
-YAHOO.widget.Calendar.prototype.deselectAll = function() {
- this.beforeDeselectEvent.fire();
-
- var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
+ if (this.beforeDestroyEvent.fire()) {
+ var cal = this;
- var selected = this.cfg.getProperty(cfgSelected);
- var count = selected.length;
- var sel = selected.concat();
+ // Child objects
+ if (cal.navigator) {
+ cal.navigator.destroy();
+ }
- if (this.parent) {
- this.parent.cfg.setProperty(cfgSelected, []);
- } else {
- this.cfg.setProperty(cfgSelected, []);
- }
-
- if (count > 0) {
- this.deselectEvent.fire(sel);
- }
+ if (cal.cfg) {
+ cal.cfg.destroy();
+ }
- return this.getSelectedDates();
-};
+ // DOM event listeners
+ Event.purgeElement(cal.oDomContainer, true);
-// END SELECTION METHODS
+ // Generated markup/DOM - Not removing the container DIV since we didn't create it.
+ Dom.removeClass(cal.oDomContainer, "withtitle");
+ Dom.removeClass(cal.oDomContainer, cal.Style.CSS_CONTAINER);
+ Dom.removeClass(cal.oDomContainer, cal.Style.CSS_SINGLE);
+ cal.oDomContainer.innerHTML = "";
-// BEGIN TYPE CONVERSION METHODS
+ // JS-to-DOM references
+ cal.oDomContainer = null;
+ cal.cells = null;
-/**
-* 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]].
-* @method _toFieldArray
-* @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[](Number[])} Array of date field arrays
-*/
-YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
- var returnDate = [];
-
- if (date instanceof Date) {
- returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
- } else if (YAHOO.lang.isString(date)) {
- returnDate = this._parseDates(date);
- } else if (YAHOO.lang.isArray(date)) {
- for (var i=0;i
+*
+*
+*
+* The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
+*
+*
+* NOTE: As of 2.4.0, the constructor's ID argument is optional.
+* The CalendarGroup can be constructed by simply providing a container ID string,
+* or a reference to a container DIV HTMLElement (the element needs to exist
+* in the document).
+*
+* E.g.:
+*
+* var c = new YAHOO.widget.CalendarGroup("calContainer", configOptions);
+*
+* or:
+*
+* var containerDiv = YAHOO.util.Dom.get("calContainer");
+* var c = new YAHOO.widget.CalendarGroup(containerDiv, configOptions);
+*
+*
+*
+* If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
+* For example if an ID is not provided, and the container's ID is "calContainer", the CalendarGroup's ID will be set to "calContainer_t".
+*
+*
+* @namespace YAHOO.widget
+* @class CalendarGroup
+* @constructor
+* @param {String} id optional The id of the table element that will represent the CalendarGroup widget. As of 2.4.0, this argument is optional.
+* @param {String | HTMLElement} container The id of the container div element that will wrap the CalendarGroup table, or a reference to a DIV element which exists in the document.
+* @param {Object} config optional The configuration object containing the initial configuration values for the CalendarGroup.
*/
-YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
- var match = false;
-
- if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
- match=true;
+function CalendarGroup(id, containerId, config) {
+ if (arguments.length > 0) {
+ this.init.apply(this, arguments);
}
+}
- return match;
-};
-
/**
-* Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
-* @method _indexOfSelectedFieldArray
+* The set of default Config property keys and values for the CalendarGroup
+* @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
+* @final
+* @static
* @private
-* @param {Number[]} find The date field array to search for
-* @return {Number} The index of the date field array within the collection of selected dates.
-* -1 will be returned if the date is not found.
+* @type Object
*/
-YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
- var selected = -1;
- var seldates = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);
+CalendarGroup._DEFAULT_CONFIG = Calendar._DEFAULT_CONFIG;
+CalendarGroup._DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
- for (var s=0;s maxDate.getTime()));
-};
+ this.oDomContainer = Dom.get(container);
-/**
- * Parses a pagedate configuration property value. The value can either be specified as a string of form "mm/yyyy" or a Date object
- * and is parsed into a Date object normalized to the first day of the month. If no value is passed in, the month and year from today's date are used to create the Date object
- * @method _parsePageDate
- * @private
- * @param {Date|String} date Pagedate value which needs to be parsed
- * @return {Date} The Date object representing the pagedate
- */
-YAHOO.widget.Calendar.prototype._parsePageDate = function(date) {
- var parsedDate;
-
- var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
-
- if (date) {
- if (date instanceof Date) {
- parsedDate = YAHOO.widget.DateMath.findMonthStart(date);
- } else {
- var month, year, aMonthYear;
- aMonthYear = date.split(this.cfg.getProperty(defCfg.DATE_FIELD_DELIMITER.key));
- month = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_MONTH_POSITION.key)-1], 10)-1;
- year = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_YEAR_POSITION.key)-1], 10);
-
- parsedDate = new Date(year, month, 1);
+ if (!this.oDomContainer.id) {
+ this.oDomContainer.id = Dom.generateId();
}
- } else {
- parsedDate = new Date(this.today.getFullYear(), this.today.getMonth(), 1);
- }
- return parsedDate;
-};
+ if (!id) {
+ id = this.oDomContainer.id + "_t";
+ }
-// END UTILITY METHODS
+ /**
+ * The unique id associated with the CalendarGroup
+ * @property id
+ * @type String
+ */
+ this.id = id;
-// BEGIN EVENT HANDLERS
+ /**
+ * The unique id associated with the CalendarGroup container
+ * @property containerId
+ * @type String
+ */
+ this.containerId = this.oDomContainer.id;
-/**
-* Event executed before a date is selected in the calendar widget.
-* @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
- if (this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MULTI_SELECT.key) === false) {
- if (this.parent) {
- this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
- this.parent.deselectAll();
- } else {
- this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
- this.deselectAll();
- }
- }
-};
+ this.initEvents();
+ this.initStyles();
-/**
-* Event executed when a date is selected in the calendar widget.
-* @param {Array} selected An array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
-* @deprecated Event handlers for this event should be susbcribed to selectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };
+ /**
+ * The collection of Calendar pages contained within the CalendarGroup
+ * @property pages
+ * @type YAHOO.widget.Calendar[]
+ */
+ this.pages = [];
-/**
-* Event executed before a date is deselected in the calendar widget.
-* @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };
+ Dom.addClass(this.oDomContainer, CalendarGroup.CSS_CONTAINER);
+ Dom.addClass(this.oDomContainer, CalendarGroup.CSS_MULTI_UP);
-/**
-* Event executed when a date is deselected in the calendar widget.
-* @param {Array} selected An array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
-* @deprecated Event handlers for this event should be susbcribed to deselectEvent.
-*/
-YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };
+ /**
+ * The Config object used to hold the configuration variables for the CalendarGroup
+ * @property cfg
+ * @type YAHOO.util.Config
+ */
+ this.cfg = new YAHOO.util.Config(this);
-/**
-* Event executed when the user navigates to a different calendar page.
-* @deprecated Event handlers for this event should be susbcribed to changePageEvent.
-*/
-YAHOO.widget.Calendar.prototype.onChangePage = function() {
- this.render();
-};
+ /**
+ * The local object which contains the CalendarGroup's options
+ * @property Options
+ * @type Object
+ */
+ this.Options = {};
-/**
-* Event executed when the calendar widget is rendered.
-* @deprecated Event handlers for this event should be susbcribed to renderEvent.
-*/
-YAHOO.widget.Calendar.prototype.onRender = function() { };
+ /**
+ * The local object which contains the CalendarGroup's locale settings
+ * @property Locale
+ * @type Object
+ */
+ this.Locale = {};
-/**
-* Event executed when the calendar widget is reset to its original state.
-* @deprecated Event handlers for this event should be susbcribed to resetEvemt.
-*/
-YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };
+ this.setupConfig();
-/**
-* Event executed when the calendar widget is completely cleared to the current month with no selections.
-* @deprecated Event handlers for this event should be susbcribed to clearEvent.
-*/
-YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };
+ if (config) {
+ this.cfg.applyConfig(config, true);
+ }
-/**
-* Validates the calendar widget. This method has no default implementation
-* and must be extended by subclassing the widget.
-* @return Should return true if the widget validates, and false if
-* it doesn't.
-* @type Boolean
-*/
-YAHOO.widget.Calendar.prototype.validate = function() { return true; };
+ this.cfg.fireQueue();
-// END EVENT HANDLERS
+ // OPERA HACK FOR MISWRAPPED FLOATS
+ if (YAHOO.env.ua.opera){
+ this.renderEvent.subscribe(this._fixWidth, this, true);
+ this.showEvent.subscribe(this._fixWidth, this, true);
+ }
-// BEGIN DATE PARSE METHODS
+ },
-/**
-* Converts a date string to a date field array
-* @private
-* @param {String} sDate Date string. Valid formats are mm/dd and mm/dd/yyyy.
-* @return A date field array representing the string passed to the method
-* @type Array[](Number[])
-*/
-YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
- var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
- var rArray;
+ setupConfig : function() {
- if (aDate.length == 2) {
- rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
- rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
- } else {
- rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
- rArray.type = YAHOO.widget.Calendar.DATE;
- }
+ var cfg = this.cfg;
- for (var i=0;i
+ *
previousMonth
String : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".
+ *
nextMonth
String : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".
+ *
close
String : The string to use for the close button label. Defaults to "Close".
+ *
+ */
+ cfg.addProperty(DEF_CFG.STRINGS.key, {
+ value:DEF_CFG.STRINGS.value,
+ handler:this.configStrings,
+ validator: function(val) {
+ return Lang.isObject(val);
+ },
+ supercedes: DEF_CFG.STRINGS.supercedes
+ });
+ },
-/**
-* Resets the render stack of the current calendar to its original pre-render value.
-*/
-YAHOO.widget.Calendar.prototype.resetRenderers = function() {
- this.renderStack = this._renderStack.concat();
-};
+ /**
+ * Initializes CalendarGroup's built-in CustomEvents
+ * @method initEvents
+ */
+ initEvents : function() {
-/**
-* Clears the inner HTML, CSS class and style information from the specified cell.
-* @method clearElement
-* @param {HTMLTableCellElement} The cell to clear
-*/
-YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
- cell.innerHTML = " ";
- cell.className="";
-};
+ var me = this,
+ strEvent = "Event",
+ CE = YAHOO.util.CustomEvent;
-/**
-* Adds a renderer to the render stack. The function reference passed to this method will be executed
-* when a date cell matches the conditions specified in the date string for this renderer.
-* @method addRenderer
-* @param {String} sDates A date string to associate with the specified renderer. Valid formats
-* include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
-* @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
-*/
-YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
- var aDates = this._parseDates(sDates);
- for (var i=0;i 0) {
+ caldate = new Date(firstPageDate);
+ this._setMonthOnDate(caldate, caldate.getMonth() + p);
+ childConfig.pageDate = caldate;
+ }
-/**
-* @namespace YAHOO.widget
-* @class Calendar_Core
-* @extends YAHOO.widget.Calendar
-* @deprecated The old Calendar_Core class is no longer necessary.
-*/
-YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
+ var cal = this.constructChild(calId, calContainerId, childConfig);
-YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
+ Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
+ Dom.addClass(cal.oDomContainer, groupCalClass);
-/**
-* YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. 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:
-*
-*
-*
-*
-* The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
-* @namespace YAHOO.widget
-* @class CalendarGroup
-* @constructor
-* @param {String} id The id of the table element that will represent the calendar widget
-* @param {String} containerId The id of the container div element that will wrap the calendar table
-* @param {Object} config The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.CalendarGroup = function(id, containerId, config) {
- if (arguments.length > 0) {
- this.init(id, containerId, config);
- }
-};
+ if (p===0) {
+ firstPageDate = cal.cfg.getProperty(cfgPageDate);
+ Dom.addClass(cal.oDomContainer, firstClass);
+ }
+
+ if (p==(pageCount-1)) {
+ Dom.addClass(cal.oDomContainer, lastClass);
+ }
+
+ cal.parent = this;
+ cal.index = p;
+
+ this.pages[this.pages.length] = cal;
+ }
+ },
+
+ /**
+ * The default Config handler for the "pagedate" property
+ * @method configPageDate
+ * @param {String} type The CustomEvent type (usually the property name)
+ * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+ * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
+ */
+ configPageDate : function(type, args, obj) {
+ var val = args[0],
+ firstPageDate;
-/**
-* Initializes the calendar group. All subclasses must call this method in order for the
-* group to be initialized properly.
-* @method init
-* @param {String} id The id of the table element that will represent the calendar widget
-* @param {String} containerId The id of the container div element that will wrap the calendar table
-* @param {Object} config The configuration object containing the Calendar's arguments
-*/
-YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
- this.initEvents();
- this.initStyles();
+ var cfgPageDate = DEF_CFG.PAGEDATE.key;
+
+ for (var p=0;p 0) ? this.pages[0].cfg.getProperty(cfgSelected) : [];
+ this.cfg.setProperty(cfgSelected, selected, true);
+ },
+
/**
- * The collection of Calendar pages contained within the CalendarGroup
- * @property pages
- * @type YAHOO.widget.Calendar[]
+ * Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
+ * @method delegateConfig
+ * @param {String} type The CustomEvent type (usually the property name)
+ * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
+ * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
*/
- this.pages = [];
+ delegateConfig : function(type, args, obj) {
+ var val = args[0];
+ var cal;
+ for (var p=0;p0) {
+ year+=1;
+ }
+ cal.setYear(year);
+ }
+ },
/**
- * The local object which contains the CalendarGroup's options
- * @property Options
- * @type Object
+ * Calls the render function of all child calendars within the group.
+ * @method render
*/
- this.Options = {};
+ render : function() {
+ this.renderHeader();
+ for (var p=0;p
+ *
If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.
+ *
If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.
+ *
+ * @method selectCell
+ * @param {Number} cellIndex The index of the cell to be selected.
+ * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
+ */
+ selectCell : function(cellIndex) {
+ for (var p=0;p=0;--p) {
+ var cal = this.pages[p];
+ cal.previousMonth();
+ }
+ },
/**
- * The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
- * @config pages
- * @type Number
- * @default 2
+ * Navigates to the next year in the currently selected month in the calendar widget.
+ * @method nextYear
*/
- this.cfg.addProperty(defCfg.PAGES.key, { value:defCfg.PAGES.value, validator:this.cfg.checkNumber, handler:this.configPages } );
+ nextYear : function() {
+ for (var p=0;p 11)) {
+ var newDate = DateMath.add(date, DateMath.MONTH, iMonth-date.getMonth());
+ date.setTime(newDate.getTime());
+ } else {
+ date.setMonth(iMonth);
+ }
+ },
/**
- * True if the Calendar should show week row headers. False by default.
- * @config SHOW_WEEK_HEADER
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key,{ value:defCfg.SHOW_WEEK_HEADER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+ * Fixes the width of the CalendarGroup container element, to account for miswrapped floats
+ * @method _fixWidth
+ * @private
+ */
+ _fixWidth : function() {
+ var w = 0;
+ for (var p=0;p 0) {
+ this.oDomContainer.style.width = w + "px";
+ }
+ },
/**
- * True if the Calendar should show week row footers. False by default.
- * @config SHOW_WEEK_FOOTER
- * @type Boolean
- * @default false
+ * Returns a string representation of the object.
+ * @method toString
+ * @return {String} A string representation of the CalendarGroup object.
*/
- this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
-
+ toString : function() {
+ return "CalendarGroup " + this.id;
+ },
+
/**
- * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
- * @config HIDE_BLANK_WEEKS
- * @type Boolean
- * @default false
- */
- this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key,{ value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
+ * Destroys the CalendarGroup instance. The method will remove references
+ * to HTML elements, remove any event listeners added by the CalendarGroup.
+ *
+ * It will also destroy the Config and CalendarNavigator instances created by the
+ * CalendarGroup and the individual Calendar instances created for each page.
+ *
+ * @method destroy
+ */
+ destroy : function() {
+
+ if (this.beforeDestroyEvent.fire()) {
+
+ var cal = this;
- /**
- * The image that should be used for the left navigation arrow.
- * @config NAV_ARROW_LEFT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
- * @default null
- */
- this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key, { value:defCfg.NAV_ARROW_LEFT.value, handler:this.delegateConfig } );
+ // Child objects
+ if (cal.navigator) {
+ cal.navigator.destroy();
+ }
+ if (cal.cfg) {
+ cal.cfg.destroy();
+ }
+
+ // DOM event listeners
+ Event.purgeElement(cal.oDomContainer, true);
+
+ // Generated markup/DOM - Not removing the container DIV since we didn't create it.
+ Dom.removeClass(cal.oDomContainer, CalendarGroup.CSS_CONTAINER);
+ Dom.removeClass(cal.oDomContainer, CalendarGroup.CSS_MULTI_UP);
+
+ for (var i = 0, l = cal.pages.length; i < l; i++) {
+ cal.pages[i].destroy();
+ cal.pages[i] = null;
+ }
+
+ cal.oDomContainer.innerHTML = "";
+
+ // JS-to-DOM references
+ cal.oDomContainer = null;
+
+ this.destroyEvent.fire();
+ }
+ }
+};
+
+/**
+* CSS class representing the container for the calendar
+* @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
+* @static
+* @final
+* @type String
+*/
+CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
+
+/**
+* CSS class representing the container for the calendar
+* @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
+* @static
+* @final
+* @type String
+*/
+CalendarGroup.CSS_MULTI_UP = "multi";
+
+/**
+* CSS class representing the title for the 2-up calendar
+* @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
+* @static
+* @final
+* @type String
+*/
+CalendarGroup.CSS_2UPTITLE = "title";
+
+/**
+* CSS class representing the close icon for the 2-up calendar
+* @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
+* @static
+* @final
+* @deprecated Along with Calendar.IMG_ROOT and NAV_ARROW_LEFT, NAV_ARROW_RIGHT configuration properties.
+* Calendar's Style.CSS_CLOSE property now represents the CSS class used to render the close icon
+* @type String
+*/
+CalendarGroup.CSS_2UPCLOSE = "close-icon";
+
+YAHOO.lang.augmentProto(CalendarGroup, Calendar, "buildDayLabel",
+ "buildMonthLabel",
+ "renderOutOfBoundsDate",
+ "renderRowHeader",
+ "renderRowFooter",
+ "renderCellDefault",
+ "styleCellDefault",
+ "renderCellStyleHighlight1",
+ "renderCellStyleHighlight2",
+ "renderCellStyleHighlight3",
+ "renderCellStyleHighlight4",
+ "renderCellStyleToday",
+ "renderCellStyleSelected",
+ "renderCellNotThisMonth",
+ "renderBodyCellRestricted",
+ "initStyles",
+ "configTitle",
+ "configClose",
+ "configIframe",
+ "configStrings",
+ "configNavigator",
+ "createTitleBar",
+ "createCloseButton",
+ "removeTitleBar",
+ "removeCloseButton",
+ "hide",
+ "show",
+ "toDate",
+ "_toDate",
+ "_parseArgs",
+ "browser");
+
+YAHOO.widget.CalGrp = CalendarGroup;
+YAHOO.widget.CalendarGroup = CalendarGroup;
+
+/**
+* @class YAHOO.widget.Calendar2up
+* @extends YAHOO.widget.CalendarGroup
+* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
+*/
+YAHOO.widget.Calendar2up = function(id, containerId, config) {
+ this.init(id, containerId, config);
+};
+
+YAHOO.extend(YAHOO.widget.Calendar2up, CalendarGroup);
+
+/**
+* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
+*/
+YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
+
+})();
+
+/**
+ * The CalendarNavigator is used along with a Calendar/CalendarGroup to
+ * provide a Month/Year popup navigation control, allowing the user to navigate
+ * to a specific month/year in the Calendar/CalendarGroup without having to
+ * scroll through months sequentially
+ *
+ * @namespace YAHOO.widget
+ * @class CalendarNavigator
+ * @constructor
+ * @param {Calendar|CalendarGroup} cal The instance of the Calendar or CalendarGroup to which this CalendarNavigator should be attached.
+ */
+YAHOO.widget.CalendarNavigator = function(cal) {
+ this.init(cal);
+};
+
+(function() {
+ // Setup static properties (inside anon fn, so that we can use shortcuts)
+ var CN = YAHOO.widget.CalendarNavigator;
+
/**
- * The image that should be used for the right navigation arrow.
- * @config NAV_ARROW_RIGHT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
- * @default null
- */
- this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key, { value:defCfg.NAV_ARROW_RIGHT.value, handler:this.delegateConfig } );
+ * YAHOO.widget.CalendarNavigator.CLASSES contains constants
+ * for the class values applied to the CalendarNaviatgator's
+ * DOM elements
+ * @property YAHOO.widget.CalendarNavigator.CLASSES
+ * @type Object
+ * @static
+ */
+ CN.CLASSES = {
+ /**
+ * Class applied to the Calendar Navigator's bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.NAV
+ * @type String
+ * @static
+ */
+ NAV :"yui-cal-nav",
+ /**
+ * Class applied to the Calendar/CalendarGroup's bounding box to indicate
+ * the Navigator is currently visible
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.NAV_VISIBLE
+ * @type String
+ * @static
+ */
+ NAV_VISIBLE: "yui-cal-nav-visible",
+ /**
+ * Class applied to the Navigator mask's bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.MASK
+ * @type String
+ * @static
+ */
+ MASK : "yui-cal-nav-mask",
+ /**
+ * Class applied to the year label/control bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.YEAR
+ * @type String
+ * @static
+ */
+ YEAR : "yui-cal-nav-y",
+ /**
+ * Class applied to the month label/control bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.MONTH
+ * @type String
+ * @static
+ */
+ MONTH : "yui-cal-nav-m",
+ /**
+ * Class applied to the submit/cancel button's bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.BUTTONS
+ * @type String
+ * @static
+ */
+ BUTTONS : "yui-cal-nav-b",
+ /**
+ * Class applied to buttons wrapping element
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.BUTTON
+ * @type String
+ * @static
+ */
+ BUTTON : "yui-cal-nav-btn",
+ /**
+ * Class applied to the validation error area's bounding box
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.ERROR
+ * @type String
+ * @static
+ */
+ ERROR : "yui-cal-nav-e",
+ /**
+ * Class applied to the year input control
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.YEAR_CTRL
+ * @type String
+ * @static
+ */
+ YEAR_CTRL : "yui-cal-nav-yc",
+ /**
+ * Class applied to the month input control
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.MONTH_CTRL
+ * @type String
+ * @static
+ */
+ MONTH_CTRL : "yui-cal-nav-mc",
+ /**
+ * Class applied to controls with invalid data (e.g. a year input field with invalid an year)
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.INVALID
+ * @type String
+ * @static
+ */
+ INVALID : "yui-invalid",
+ /**
+ * Class applied to default controls
+ * @property YAHOO.widget.CalendarNavigator.CLASSES.DEFAULT
+ * @type String
+ * @static
+ */
+ DEFAULT : "yui-default"
+ };
- // Locale properties
-
/**
- * The short month labels for the current locale.
- * @config MONTHS_SHORT
- * @type String[]
- * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
- */
- this.cfg.addProperty(defCfg.MONTHS_SHORT.key, { value:defCfg.MONTHS_SHORT.value, handler:this.delegateConfig } );
-
+ * Object literal containing the default configuration values for the CalendarNavigator
+ * The configuration object is expected to follow the format below, with the properties being
+ * case sensitive.
+ *
+ *
strings
+ *
Object : An object with the properties shown below, defining the string labels to use in the Navigator's UI
+ *
+ *
month
String : The string to use for the month label. Defaults to "Month".
+ *
year
String : The string to use for the year label. Defaults to "Year".
+ *
submit
String : The string to use for the submit button label. Defaults to "Okay".
+ *
cancel
String : The string to use for the cancel button label. Defaults to "Cancel".
+ *
invalidYear
String : The string to use for invalid year values. Defaults to "Year needs to be a number".
+ *
+ *
+ *
monthFormat
String : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG
+ *
initialFocus
String : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"
+ *
+ * @property _DEFAULT_CFG
+ * @protected
+ * @type Object
+ * @static
+ */
+ CN._DEFAULT_CFG = {
+ strings : {
+ month: "Month",
+ year: "Year",
+ submit: "Okay",
+ cancel: "Cancel",
+ invalidYear : "Year needs to be a number"
+ },
+ monthFormat: YAHOO.widget.Calendar.LONG,
+ initialFocus: "year"
+ };
+
/**
- * The long month labels for the current locale.
- * @config MONTHS_LONG
- * @type String[]
- * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- */
- this.cfg.addProperty(defCfg.MONTHS_LONG.key, { value:defCfg.MONTHS_LONG.value, handler:this.delegateConfig } );
-
+ * The suffix added to the Calendar/CalendarGroup's ID, to generate
+ * a unique ID for the Navigator and it's bounding box.
+ * @property YAHOO.widget.CalendarNavigator.ID_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.ID_SUFFIX = "_nav";
/**
- * The 1-character weekday labels for the current locale.
- * @config WEEKDAYS_1CHAR
- * @type String[]
- * @default ["S", "M", "T", "W", "T", "F", "S"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key, { value:defCfg.WEEKDAYS_1CHAR.value, handler:this.delegateConfig } );
-
+ * The suffix added to the Navigator's ID, to generate
+ * a unique ID for the month control.
+ * @property YAHOO.widget.CalendarNavigator.MONTH_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.MONTH_SUFFIX = "_month";
/**
- * The short weekday labels for the current locale.
- * @config WEEKDAYS_SHORT
- * @type String[]
- * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key, { value:defCfg.WEEKDAYS_SHORT.value, handler:this.delegateConfig } );
-
+ * The suffix added to the Navigator's ID, to generate
+ * a unique ID for the year control.
+ * @property YAHOO.widget.CalendarNavigator.YEAR_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.YEAR_SUFFIX = "_year";
/**
- * The medium weekday labels for the current locale.
- * @config WEEKDAYS_MEDIUM
- * @type String[]
- * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key, { value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.delegateConfig } );
-
+ * The suffix added to the Navigator's ID, to generate
+ * a unique ID for the error bounding box.
+ * @property YAHOO.widget.CalendarNavigator.ERROR_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.ERROR_SUFFIX = "_error";
/**
- * The long weekday labels for the current locale.
- * @config WEEKDAYS_LONG
- * @type String[]
- * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- */
- this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key, { value:defCfg.WEEKDAYS_LONG.value, handler:this.delegateConfig } );
+ * The suffix added to the Navigator's ID, to generate
+ * a unique ID for the "Cancel" button.
+ * @property YAHOO.widget.CalendarNavigator.CANCEL_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.CANCEL_SUFFIX = "_cancel";
+ /**
+ * The suffix added to the Navigator's ID, to generate
+ * a unique ID for the "Submit" button.
+ * @property YAHOO.widget.CalendarNavigator.SUBMIT_SUFFIX
+ * @static
+ * @type String
+ * @final
+ */
+ CN.SUBMIT_SUFFIX = "_submit";
/**
- * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
- * @config LOCALE_MONTHS
- * @type String
- * @default "long"
- */
- this.cfg.addProperty(defCfg.LOCALE_MONTHS.key, { value:defCfg.LOCALE_MONTHS.value, handler:this.delegateConfig } );
+ * The number of digits to which the year input control is to be limited.
+ * @property YAHOO.widget.CalendarNavigator.YR_MAX_DIGITS
+ * @static
+ * @type Number
+ */
+ CN.YR_MAX_DIGITS = 4;
/**
- * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
- * @config LOCALE_WEEKDAYS
- * @type String
- * @default "short"
- */
- this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key, { value:defCfg.LOCALE_WEEKDAYS.value, handler:this.delegateConfig } );
+ * The amount by which to increment the current year value,
+ * when the arrow up/down key is pressed on the year control
+ * @property YAHOO.widget.CalendarNavigator.YR_MINOR_INC
+ * @static
+ * @type Number
+ */
+ CN.YR_MINOR_INC = 1;
/**
- * The value used to delimit individual dates in a date string passed to various Calendar functions.
- * @config DATE_DELIMITER
- * @type String
- * @default ","
- */
- this.cfg.addProperty(defCfg.DATE_DELIMITER.key, { value:defCfg.DATE_DELIMITER.value, handler:this.delegateConfig } );
+ * The amount by which to increment the current year value,
+ * when the page up/down key is pressed on the year control
+ * @property YAHOO.widget.CalendarNavigator.YR_MAJOR_INC
+ * @static
+ * @type Number
+ */
+ CN.YR_MAJOR_INC = 10;
/**
- * The value used to delimit date fields in a date string passed to various Calendar functions.
- * @config DATE_FIELD_DELIMITER
- * @type String
- * @default "/"
- */
- this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key,{ value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.delegateConfig } );
+ * Artificial delay (in ms) between the time the Navigator is hidden
+ * and the Calendar/CalendarGroup state is updated. Allows the user
+ * the see the Calendar/CalendarGroup page changing. If set to 0
+ * the Calendar/CalendarGroup page will be updated instantly
+ * @property YAHOO.widget.CalendarNavigator.UPDATE_DELAY
+ * @static
+ * @type Number
+ */
+ CN.UPDATE_DELAY = 50;
/**
- * The value used to delimit date ranges in a date string passed to various Calendar functions.
- * @config DATE_RANGE_DELIMITER
- * @type String
- * @default "-"
- */
- this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key,{ value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.delegateConfig } );
+ * Regular expression used to validate the year input
+ * @property YAHOO.widget.CalendarNavigator.YR_PATTERN
+ * @static
+ * @type RegExp
+ */
+ CN.YR_PATTERN = /^\d+$/;
+ /**
+ * Regular expression used to trim strings
+ * @property YAHOO.widget.CalendarNavigator.TRIM
+ * @static
+ * @type RegExp
+ */
+ CN.TRIM = /^\s*(.*?)\s*$/;
+})();
+YAHOO.widget.CalendarNavigator.prototype = {
+
/**
- * The position of the month in a month/year date string
- * @config MY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key, { value:defCfg.MY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
+ * The unique ID for this CalendarNavigator instance
+ * @property id
+ * @type String
+ */
+ id : null,
+
/**
- * The position of the year in a month/year date string
- * @config MY_YEAR_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key, { value:defCfg.MY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
+ * The Calendar/CalendarGroup instance to which the navigator belongs
+ * @property cal
+ * @type {Calendar|CalendarGroup}
+ */
+ cal : null,
+
/**
- * The position of the month in a month/day date string
- * @config MD_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key, { value:defCfg.MD_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
+ * Reference to the HTMLElement used to render the navigator's bounding box
+ * @property navEl
+ * @type HTMLElement
+ */
+ navEl : null,
+
/**
- * The position of the day in a month/year date string
- * @config MD_DAY_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MD_DAY_POSITION.key, { value:defCfg.MD_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
+ * Reference to the HTMLElement used to render the navigator's mask
+ * @property maskEl
+ * @type HTMLElement
+ */
+ maskEl : null,
+
/**
- * The position of the month in a month/day/year date string
- * @config MDY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key, { value:defCfg.MDY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
-
+ * Reference to the HTMLElement used to input the year
+ * @property yearEl
+ * @type HTMLElement
+ */
+ yearEl : null,
+
/**
- * The position of the day in a month/day/year date string
- * @config MDY_DAY_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key, { value:defCfg.MDY_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+ * Reference to the HTMLElement used to input the month
+ * @property monthEl
+ * @type HTMLElement
+ */
+ monthEl : null,
+
+ /**
+ * Reference to the HTMLElement used to display validation errors
+ * @property errorEl
+ * @type HTMLElement
+ */
+ errorEl : null,
+
+ /**
+ * Reference to the HTMLElement used to update the Calendar/Calendar group
+ * with the month/year values
+ * @property submitEl
+ * @type HTMLElement
+ */
+ submitEl : null,
/**
- * The position of the year in a month/day/year date string
- * @config MDY_YEAR_POSITION
- * @type Number
- * @default 3
- */
- this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key, { value:defCfg.MDY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+ * Reference to the HTMLElement used to hide the navigator without updating the
+ * Calendar/Calendar group
+ * @property cancelEl
+ * @type HTMLElement
+ */
+ cancelEl : null,
+ /**
+ * Reference to the first focusable control in the navigator (by default monthEl)
+ * @property firstCtrl
+ * @type HTMLElement
+ */
+ firstCtrl : null,
+
+ /**
+ * Reference to the last focusable control in the navigator (by default cancelEl)
+ * @property lastCtrl
+ * @type HTMLElement
+ */
+ lastCtrl : null,
+
/**
- * The position of the month in the month year label string used as the Calendar header
- * @config MY_LABEL_MONTH_POSITION
- * @type Number
- * @default 1
- */
- this.cfg.addProperty(defCfg.MY_LABEL_MONTH_POSITION.key, { value:defCfg.MY_LABEL_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+ * The document containing the Calendar/Calendar group instance
+ * @protected
+ * @property _doc
+ * @type HTMLDocument
+ */
+ _doc : null,
/**
- * The position of the year in the month year label string used as the Calendar header
- * @config MY_LABEL_YEAR_POSITION
- * @type Number
- * @default 2
- */
- this.cfg.addProperty(defCfg.MY_LABEL_YEAR_POSITION.key, { value:defCfg.MY_LABEL_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
+ * Internal state property for the current year displayed in the navigator
+ * @protected
+ * @property _year
+ * @type Number
+ */
+ _year: null,
/**
- * The suffix used after the month when rendering the Calendar header
- * @config MY_LABEL_MONTH_SUFFIX
- * @type String
- * @default " "
- */
- this.cfg.addProperty(defCfg.MY_LABEL_MONTH_SUFFIX.key, { value:defCfg.MY_LABEL_MONTH_SUFFIX.value, handler:this.delegateConfig } );
-
+ * Internal state property for the current month index displayed in the navigator
+ * @protected
+ * @property _month
+ * @type Number
+ */
+ _month: 0,
+
/**
- * The suffix used after the year when rendering the Calendar header
- * @config MY_LABEL_YEAR_SUFFIX
- * @type String
- * @default ""
- */
- this.cfg.addProperty(defCfg.MY_LABEL_YEAR_SUFFIX.key, { value:defCfg.MY_LABEL_YEAR_SUFFIX.value, handler:this.delegateConfig } );
-};
+ * Private internal state property which indicates whether or not the
+ * Navigator has been rendered.
+ * @private
+ * @property __rendered
+ * @type Boolean
+ */
+ __rendered: false,
-/**
-* Initializes CalendarGroup's built-in CustomEvents
-* @method initEvents
-*/
-YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
- var me = this;
- var strEvent = "Event";
+ /**
+ * Init lifecycle method called as part of construction
+ *
+ * @method init
+ * @param {Calendar} cal The instance of the Calendar or CalendarGroup to which this CalendarNavigator should be attached
+ */
+ init : function(cal) {
+ var calBox = cal.oDomContainer;
+ this.cal = cal;
+ this.id = calBox.id + YAHOO.widget.CalendarNavigator.ID_SUFFIX;
+ this._doc = calBox.ownerDocument;
+
+ /**
+ * Private flag, to identify IE Quirks
+ * @private
+ * @property __isIEQuirks
+ */
+ var ie = YAHOO.env.ua.ie;
+ this.__isIEQuirks = (ie && ((ie <= 6) || (this._doc.compatMode == "BackCompat")));
+ },
+
/**
- * Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
- * @method sub
- * @private
- * @param {Function} fn The function to subscribe to this CustomEvent
- * @param {Object} obj The CustomEvent's scope object
- * @param {Boolean} bOverride Whether or not to apply scope correction
- */
- var sub = function(fn, obj, bOverride) {
- for (var p=0;p= 0 && nMonth < 12) {
+ this._month = nMonth;
+ }
+ this._updateMonthUI();
+ },
/**
- * Fired when the Calendar is rendered
- * @event renderEvent
- */
- this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
- this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;
+ * Sets the current year on the Navigator, and updates the UI. If the
+ * provided year is invalid, it will not be set.
+ *
+ * @method setYear
+ * @param {Number} nYear The full year value to set the Navigator to.
+ */
+ setYear : function(nYear) {
+ var yrPattern = YAHOO.widget.CalendarNavigator.YR_PATTERN;
+ if (YAHOO.lang.isNumber(nYear) && yrPattern.test(nYear+"")) {
+ this._year = nYear;
+ }
+ this._updateYearUI();
+ },
/**
- * Fired when the Calendar is reset
- * @event resetEvent
- */
- this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET);
- this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;
+ * Renders the HTML for the navigator, adding it to the
+ * document and attaches event listeners if it has not
+ * already been rendered.
+ *
+ * @method render
+ */
+ render: function() {
+ this.cal.beforeRenderNavEvent.fire();
+ if (!this.__rendered) {
+ this.createNav();
+ this.createMask();
+ this.applyListeners();
+ this.__rendered = true;
+ }
+ this.cal.renderNavEvent.fire();
+ },
/**
- * Fired when the Calendar is cleared
- * @event clearEvent
- */
- this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
- this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;
+ * Creates the navigator's containing HTMLElement, it's contents, and appends
+ * the containg element to the Calendar/CalendarGroup's container.
+ *
+ * @method createNav
+ */
+ createNav : function() {
+ var NAV = YAHOO.widget.CalendarNavigator;
+ var doc = this._doc;
-};
+ var d = doc.createElement("div");
+ d.className = NAV.CLASSES.NAV;
-/**
-* The default Config handler for the "pages" property
-* @method configPages
-* @param {String} type The CustomEvent type (usually the property name)
-* @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
- var pageCount = args[0];
+ var htmlBuf = this.renderNavContents([]);
- var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
+ d.innerHTML = htmlBuf.join('');
+ this.cal.oDomContainer.appendChild(d);
- // Define literals outside loop
- var sep = "_";
- var groupCalClass = "groupcal";
+ this.navEl = d;
- var firstClass = "first-of-type";
- var lastClass = "last-of-type";
+ this.yearEl = doc.getElementById(this.id + NAV.YEAR_SUFFIX);
+ this.monthEl = doc.getElementById(this.id + NAV.MONTH_SUFFIX);
+ this.errorEl = doc.getElementById(this.id + NAV.ERROR_SUFFIX);
+ this.submitEl = doc.getElementById(this.id + NAV.SUBMIT_SUFFIX);
+ this.cancelEl = doc.getElementById(this.id + NAV.CANCEL_SUFFIX);
- for (var p=0;p
+ * The method is also registered as an HTMLElement resize listener on the Calendars container element.
+ *
+ * @protected
+ * @method _syncMask
+ */
+ _syncMask : function() {
+ var c = this.cal.oDomContainer;
+ if (c && this.maskEl) {
+ var r = YAHOO.util.Dom.getRegion(c);
+ YAHOO.util.Dom.setStyle(this.maskEl, "width", r.right - r.left + "px");
+ YAHOO.util.Dom.setStyle(this.maskEl, "height", r.bottom - r.top + "px");
}
+ },
- cal.parent = this;
- cal.index = p;
+ /**
+ * Renders the contents of the navigator
+ *
+ * @method renderNavContents
+ *
+ * @param {Array} html The HTML buffer to append the HTML to.
+ * @return {Array} A reference to the buffer passed in.
+ */
+ renderNavContents : function(html) {
+ var NAV = YAHOO.widget.CalendarNavigator,
+ C = NAV.CLASSES,
+ h = html; // just to use a shorter name
- this.pages[this.pages.length] = cal;
- }
-};
+ h[h.length] = '
';
+ this.renderMonth(h);
+ h[h.length] = '
';
+ h[h.length] = '
';
+ this.renderYear(h);
+ h[h.length] = '
';
+ h[h.length] = '
';
+ this.renderButtons(h);
+ h[h.length] = '
';
+ h[h.length] = '';
-/**
-* The default Config handler for the "pagedate" property
-* @method configPageDate
-* @param {String} type The CustomEvent type (usually the property name)
-* @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
- var val = args[0];
- var firstPageDate;
-
- var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
-
- for (var p=0;p 0) {
+ h[h.length] = '';
+ h[h.length] = '';
}
- }
-};
+ return h;
+ },
-/**
-* The default Config handler for the CalendarGroup "selected" property
-* @method configSelected
-* @param {String} type The CustomEvent type (usually the property name)
-* @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.configSelected = function(type, args, obj) {
- var cfgSelected = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key;
- this.delegateConfig(type, args, obj);
- var selected = (this.pages.length > 0) ? this.pages[0].cfg.getProperty(cfgSelected) : [];
- this.cfg.setProperty(cfgSelected, selected, true);
-};
+ /**
+ * Renders the year label and control for the navigator
+ *
+ * @method renderYear
+ * @param {Array} html The HTML buffer to append the HTML to.
+ * @return {Array} A reference to the buffer passed in.
+ */
+ renderYear : function(html) {
+ var NAV = YAHOO.widget.CalendarNavigator,
+ C = NAV.CLASSES;
+ var id = this.id + NAV.YEAR_SUFFIX,
+ size = NAV.YR_MAX_DIGITS,
+ h = html;
-/**
-* Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
-* @method delegateConfig
-* @param {String} type The CustomEvent type (usually the property name)
-* @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
-* @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
-*/
-YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
- var val = args[0];
- var cal;
+ h[h.length] = '';
+ h[h.length] = '';
+ return h;
+ },
- for (var p=0;p';
+ h[h.length] = '';
+ h[h.length] = '';
+ h[h.length] = '';
+ h[h.length] = '';
+ h[h.length] = '';
-/**
-* Adds a function to all child Calendars within this CalendarGroup.
-* @method setChildFunction
-* @param {String} fnName The name of the function
-* @param {Function} fn The function to apply to each Calendar page object
-*/
-YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
- var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
+ return h;
+ },
- for (var p=0;p
+ * The method will call applyKeyListeners, to setup keyboard specific
+ * listeners
+ *
+ * @method applyListeners
+ */
+ applyListeners : function() {
+ var E = YAHOO.util.Event;
-/**
-* Calls a function within all child Calendars within this CalendarGroup.
-* @method callChildFunction
-* @param {String} fnName The name of the function
-* @param {Array} args The arguments to pass to the function
-*/
-YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
- var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
+ function yearUpdateHandler() {
+ if (this.validate()) {
+ this.setYear(this._getYearFromUI());
+ }
+ }
- for (var p=0;p
+ * NOTE: MacOSX Safari 2.x doesn't let you tab to buttons and
+ * MacOSX Gecko does not let you tab to buttons or select controls,
+ * so for these browsers, Tab/Shift-Tab looping is limited to the
+ * elements which can be reached using the tab key.
+ *
+ * @method applyKeyListeners
+ */
+ applyKeyListeners : function() {
+ var E = YAHOO.util.Event,
+ ua = YAHOO.env.ua;
- year = parseInt(year, 10);
- for (var p=0;p0) {
- year+=1;
- }
- cal.setYear(year);
- }
-};
-/**
-* Calls the render function of all child calendars within the group.
-* @method render
-*/
-YAHOO.widget.CalendarGroup.prototype.render = function() {
- this.renderHeader();
- for (var p=0;p
-*
If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.
-*
If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.
-*
-* @method selectCell
-* @param {Number} cellIndex The index of the cell to be selected.
-* @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
-*/
-YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
- for (var p=0;p
+ * If the currently set month/year is invalid, a validation error will be displayed and the
+ * Calendar/CalendarGroup's pagedate will not be updated.
+ *
+ * @method submit
+ */
+ submit : function() {
+ if (this.validate()) {
+ this.hide();
-/**
-* Clears the selected dates in the current calendar widget and sets the calendar
-* to the current month and year.
-* @method clear
-*/
-YAHOO.widget.CalendarGroup.prototype.clear = function() {
- for (var p=0;p=0;--p) {
- var cal = this.pages[p];
- cal.previousMonth();
- }
-};
+ // Artificial delay, just to help the user see something changed
+ var delay = YAHOO.widget.CalendarNavigator.UPDATE_DELAY;
+ if (delay > 0) {
+ var nav = this;
+ window.setTimeout(function(){ nav._update(cal); }, delay);
+ } else {
+ this._update(cal);
+ }
+ }
+ },
-/**
-* Navigates to the next year in the currently selected month in the calendar widget.
-* @method nextYear
-*/
-YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
- for (var p=0;p 11)) {
- var DM = YAHOO.widget.DateMath;
- var newDate = DM.add(date, DM.MONTH, iMonth-date.getMonth());
- date.setTime(newDate.getTime());
- } else {
- date.setMonth(iMonth);
- }
-};
+ /**
+ * Returns the month value (index), from the month UI element
+ * @protected
+ * @method _getMonthFromUI
+ * @return {Number} The month index, or 0 if a UI element for the month
+ * is not found
+ */
+ _getMonthFromUI : function() {
+ if (this.monthEl) {
+ return this.monthEl.selectedIndex;
+ } else {
+ return 0; // Default to Jan
+ }
+ },
-/**
- * Fixes the width of the CalendarGroup container element, to account for miswrapped floats
- * @method _fixWidth
- * @private
- */
-YAHOO.widget.CalendarGroup.prototype._fixWidth = function() {
- var startW = this.oDomContainer.offsetWidth;
- var w = 0;
- for (var p=0;p 0) {
- this.oDomContainer.style.width = w + "px";
- }
-};
+ /**
+ * Returns the year value, from the Navitator's year UI element
+ * @protected
+ * @method _getYearFromUI
+ * @return {Number} The year value set in the UI, if valid. null is returned if
+ * the UI does not contain a valid year value.
+ */
+ _getYearFromUI : function() {
+ var NAV = YAHOO.widget.CalendarNavigator;
+ var yr = null;
+ if (this.yearEl) {
+ var value = this.yearEl.value;
+ value = value.replace(NAV.TRIM, "$1");
-/**
-* CSS class representing the container for the calendar
-* @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
+ if (NAV.YR_PATTERN.test(value)) {
+ yr = parseInt(value, 10);
+ }
+ }
+ return yr;
+ },
-/**
-* CSS class representing the container for the calendar
-* @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";
+ /**
+ * Updates the Navigator's year UI, based on the year value set on the Navigator object
+ * @protected
+ * @method _updateYearUI
+ */
+ _updateYearUI : function() {
+ if (this.yearEl && this._year !== null) {
+ this.yearEl.value = this._year;
+ }
+ },
-/**
-* CSS class representing the title for the 2-up calendar
-* @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
-* @static
-* @final
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";
+ /**
+ * Updates the Navigator's month UI, based on the month value set on the Navigator object
+ * @protected
+ * @method _updateMonthUI
+ */
+ _updateMonthUI : function() {
+ if (this.monthEl) {
+ this.monthEl.selectedIndex = this._month;
+ }
+ },
-/**
-* CSS class representing the close icon for the 2-up calendar
-* @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
-* @static
-* @final
-* @deprecated Along with Calendar.IMG_ROOT and NAV_ARROW_LEFT, NAV_ARROW_RIGHT configuration properties.
-* Calendar's Style.CSS_CLOSE property now represents the CSS class used to render the close icon
-* @type String
-*/
-YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";
+ /**
+ * Sets up references to the first and last focusable element in the Navigator's UI
+ * in terms of tab order (Naviagator's firstEl and lastEl properties). The references
+ * are used to control modality by looping around from the first to the last control
+ * and visa versa for tab/shift-tab navigation.
+ *
+ * @protected
+ * @method _setFirstLastElements
+ */
+ _setFirstLastElements : function() {
+ this.firstCtrl = this.monthEl;
+ this.lastCtrl = this.cancelEl;
-YAHOO.lang.augmentProto(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
- "buildMonthLabel",
- "renderOutOfBoundsDate",
- "renderRowHeader",
- "renderRowFooter",
- "renderCellDefault",
- "styleCellDefault",
- "renderCellStyleHighlight1",
- "renderCellStyleHighlight2",
- "renderCellStyleHighlight3",
- "renderCellStyleHighlight4",
- "renderCellStyleToday",
- "renderCellStyleSelected",
- "renderCellNotThisMonth",
- "renderBodyCellRestricted",
- "initStyles",
- "configTitle",
- "configClose",
- "configIframe",
- "hide",
- "browser");
+ // Special handling for MacOSX.
+ // - Safari 2.x can't focus on buttons
+ // - Gecko can't focus on select boxes or buttons
+ if (this.__isMac) {
+ if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420){
+ this.firstCtrl = this.monthEl;
+ this.lastCtrl = this.yearEl;
+ }
+ if (YAHOO.env.ua.gecko) {
+ this.firstCtrl = this.yearEl;
+ this.lastCtrl = this.yearEl;
+ }
+ }
+ },
-/**
-* The set of default Config property keys and values for the CalendarGroup
-* @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
-* @final
-* @static
-* @private
-* @type Object
-*/
-YAHOO.widget.CalendarGroup._DEFAULT_CONFIG = YAHOO.widget.Calendar._DEFAULT_CONFIG;
-YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
+ /**
+ * Default Keyboard event handler to capture Enter
+ * on the Navigator's year control (yearEl)
+ *
+ * @method _handleEnterKey
+ * @protected
+ * @param {Event} e The DOM event being handled
+ */
+ _handleEnterKey : function(e) {
+ var KEYS = YAHOO.util.KeyListener.KEY;
-/**
-* Returns a string representation of the object.
-* @method toString
-* @return {String} A string representation of the CalendarGroup object.
-*/
-YAHOO.widget.CalendarGroup.prototype.toString = function() {
- return "CalendarGroup " + this.id;
-};
+ if (YAHOO.util.Event.getCharCode(e) == KEYS.ENTER) {
+ YAHOO.util.Event.preventDefault(e);
+ this.submit();
+ }
+ },
-YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
+ /**
+ * Default Keyboard event handler to capture up/down/pgup/pgdown
+ * on the Navigator's year control (yearEl).
+ *
+ * @method _handleDirectionKeys
+ * @protected
+ * @param {Event} e The DOM event being handled
+ */
+ _handleDirectionKeys : function(e) {
+ var E = YAHOO.util.Event,
+ KEYS = YAHOO.util.KeyListener.KEY,
+ NAV = YAHOO.widget.CalendarNavigator;
-/**
-* @class YAHOO.widget.Calendar2up
-* @extends YAHOO.widget.CalendarGroup
-* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
-*/
-YAHOO.widget.Calendar2up = function(id, containerId, config) {
- this.init(id, containerId, config);
-};
+ var value = (this.yearEl.value) ? parseInt(this.yearEl.value, 10) : null;
+ if (isFinite(value)) {
+ var dir = false;
+ switch(E.getCharCode(e)) {
+ case KEYS.UP:
+ this.yearEl.value = value + NAV.YR_MINOR_INC;
+ dir = true;
+ break;
+ case KEYS.DOWN:
+ this.yearEl.value = Math.max(value - NAV.YR_MINOR_INC, 0);
+ dir = true;
+ break;
+ case KEYS.PAGE_UP:
+ this.yearEl.value = value + NAV.YR_MAJOR_INC;
+ dir = true;
+ break;
+ case KEYS.PAGE_DOWN:
+ this.yearEl.value = Math.max(value - NAV.YR_MAJOR_INC, 0);
+ dir = true;
+ break;
+ default:
+ break;
+ }
+ if (dir) {
+ E.preventDefault(e);
+ try {
+ this.yearEl.select();
+ } catch(err) {
+ // Ignore
+ }
+ }
+ }
+ },
-YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);
+ /**
+ * Default Keyboard event handler to capture Tab
+ * on the last control (lastCtrl) in the Navigator.
+ *
+ * @method _handleTabKey
+ * @protected
+ * @param {Event} e The DOM event being handled
+ */
+ _handleTabKey : function(e) {
+ var E = YAHOO.util.Event,
+ KEYS = YAHOO.util.KeyListener.KEY;
-/**
-* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
-*/
-YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
+ if (E.getCharCode(e) == KEYS.TAB && !e.shiftKey) {
+ try {
+ E.preventDefault(e);
+ this.firstCtrl.focus();
+ } catch (err) {
+ // Ignore - mainly for focus edge cases
+ }
+ }
+ },
-YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.3.0", build: "442"});
+ /**
+ * Default Keyboard event handler to capture Shift-Tab
+ * on the first control (firstCtrl) in the Navigator.
+ *
+ * @method _handleShiftTabKey
+ * @protected
+ * @param {Event} e The DOM event being handled
+ */
+ _handleShiftTabKey : function(e) {
+ var E = YAHOO.util.Event,
+ KEYS = YAHOO.util.KeyListener.KEY;
+
+ if (e.shiftKey && E.getCharCode(e) == KEYS.TAB) {
+ try {
+ E.preventDefault(e);
+ this.lastCtrl.focus();
+ } catch (err) {
+ // Ignore - mainly for focus edge cases
+ }
+ }
+ },
+
+ /**
+ * Retrieve Navigator configuration values from
+ * the parent Calendar/CalendarGroup's config value.
+ *
+ * If it has not been set in the user provided configuration, the method will
+ * return the default value of the configuration property, as set in _DEFAULT_CFG
+ *
+ * @private
+ * @method __getCfg
+ * @param {String} Case sensitive property name.
+ * @param {Boolean} true, if the property is a string property, false if not.
+ * @return The value of the configuration property
+ */
+ __getCfg : function(prop, bIsStr) {
+ var DEF_CFG = YAHOO.widget.CalendarNavigator._DEFAULT_CFG;
+ var cfg = this.cal.cfg.getProperty("navigator");
+
+ if (bIsStr) {
+ return (cfg !== true && cfg.strings && cfg.strings[prop]) ? cfg.strings[prop] : DEF_CFG.strings[prop];
+ } else {
+ return (cfg !== true && cfg[prop]) ? cfg[prop] : DEF_CFG[prop];
+ }
+ },
+
+ /**
+ * Private flag, to identify MacOS
+ * @private
+ * @property __isMac
+ */
+ __isMac : (navigator.userAgent.toLowerCase().indexOf("macintosh") != -1)
+
+};
+
+YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.7.0", build: "1799"});