/src/main/resources/org/apache/struts2/static/calendar/calendar-debug.js
JavaScript | 7178 lines | 3040 code | 916 blank | 3222 comment | 560 complexity | e465b111e655819506047a645708c328 MD5 | raw file
- /*
- Copyright (c) 2009, Yahoo! Inc. All rights reserved.
- Code licensed under the BSD License:
- http://developer.yahoo.net/yui/license.txt
- version: 2.7.0
- */
- (function () {
- /**
- * Config is a utility used within an Object to allow the implementer to
- * maintain a list of local configuration properties and listen for changes
- * to those properties dynamically using CustomEvent. The initial values are
- * also maintained so that the configuration can be reset at any given point
- * to its initial state.
- * @namespace YAHOO.util
- * @class Config
- * @constructor
- * @param {Object} owner The owner Object to which this Config Object belongs
- */
- YAHOO.util.Config = function (owner) {
- if (owner) {
- this.init(owner);
- }
- if (!owner) { YAHOO.log("No owner specified for Config object", "error", "Config"); }
- };
- var Lang = YAHOO.lang,
- 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
- * @private
- * @static
- * @final
- */
- Config.CONFIG_CHANGED_EVENT = "configChanged";
-
- /**
- * Constant representing the boolean type string
- * @property YAHOO.util.Config.BOOLEAN_TYPE
- * @private
- * @static
- * @final
- */
- Config.BOOLEAN_TYPE = "boolean";
-
- Config.prototype = {
-
- /**
- * Object reference to the owner of this Config Object
- * @property owner
- * @type Object
- */
- owner: null,
-
- /**
- * Boolean flag that specifies whether a queue is currently
- * being executed
- * @property queueInProgress
- * @type Boolean
- */
- queueInProgress: false,
-
- /**
- * Maintains the local collection of configuration property objects and
- * their specified values
- * @property config
- * @private
- * @type Object
- */
- config: null,
-
- /**
- * Maintains the local collection of configuration property objects as
- * they were initially applied.
- * This object is used when resetting a property.
- * @property initialConfig
- * @private
- * @type Object
- */
- initialConfig: null,
-
- /**
- * Maintains the local, normalized CustomEvent queue
- * @property eventQueue
- * @private
- * @type Object
- */
- eventQueue: null,
-
- /**
- * Custom Event, notifying subscribers when Config properties are set
- * (setProperty is called without the silent flag
- * @event configChangedEvent
- */
- configChangedEvent: null,
-
- /**
- * Initializes the configuration Object and all of its local members.
- * @method init
- * @param {Object} owner The owner Object to which this Config
- * Object belongs
- */
- init: function (owner) {
-
- this.owner = owner;
-
- this.configChangedEvent =
- this.createEvent(Config.CONFIG_CHANGED_EVENT);
-
- this.configChangedEvent.signature = CustomEvent.LIST;
- this.queueInProgress = false;
- this.config = {};
- this.initialConfig = {};
- this.eventQueue = [];
-
- },
-
- /**
- * Validates that the value passed in is a Boolean.
- * @method checkBoolean
- * @param {Object} val The value to validate
- * @return {Boolean} true, if the value is valid
- */
- checkBoolean: function (val) {
- return (typeof val == Config.BOOLEAN_TYPE);
- },
-
- /**
- * Validates that the value passed in is a number.
- * @method checkNumber
- * @param {Object} val The value to validate
- * @return {Boolean} true, if the value is valid
- */
- checkNumber: function (val) {
- return (!isNaN(val));
- },
-
- /**
- * Fires a configuration property event using the specified value.
- * @method fireEvent
- * @private
- * @param {String} key The configuration property's name
- * @param {value} Object The value of the correct type for the property
- */
- fireEvent: function ( key, value ) {
- YAHOO.log("Firing Config event: " + key + "=" + value, "info", "Config");
- var property = this.config[key];
-
- if (property && property.event) {
- property.event.fire(value);
- }
- },
-
- /**
- * Adds a property to the Config Object's private config hash.
- * @method addProperty
- * @param {String} key The configuration property's name
- * @param {Object} propertyObject The Object containing all of this
- * property's arguments
- */
- addProperty: function ( key, propertyObject ) {
- key = key.toLowerCase();
- YAHOO.log("Added property: " + key, "info", "Config");
-
- this.config[key] = propertyObject;
-
- propertyObject.event = this.createEvent(key, { scope: this.owner });
- propertyObject.event.signature = CustomEvent.LIST;
-
-
- propertyObject.key = key;
-
- if (propertyObject.handler) {
- propertyObject.event.subscribe(propertyObject.handler,
- this.owner);
- }
-
- this.setProperty(key, propertyObject.value, true);
-
- if (! propertyObject.suppressEvent) {
- this.queueProperty(key, propertyObject.value);
- }
-
- },
-
- /**
- * Returns a key-value configuration map of the values currently set in
- * the Config Object.
- * @method getConfig
- * @return {Object} The current config, represented in a key-value map
- */
- getConfig: function () {
-
- var cfg = {},
- currCfg = this.config,
- prop,
- property;
-
- for (prop in currCfg) {
- if (Lang.hasOwnProperty(currCfg, prop)) {
- property = currCfg[prop];
- if (property && property.event) {
- cfg[prop] = property.value;
- }
- }
- }
- return cfg;
- },
-
- /**
- * Returns the value of specified property.
- * @method getProperty
- * @param {String} key The name of the property
- * @return {Object} The value of the specified property
- */
- getProperty: function (key) {
- var property = this.config[key.toLowerCase()];
- if (property && property.event) {
- return property.value;
- } else {
- return undefined;
- }
- },
-
- /**
- * Resets the specified property's value to its initial value.
- * @method resetProperty
- * @param {String} key The name of the property
- * @return {Boolean} True is the property was reset, false if not
- */
- resetProperty: function (key) {
-
- key = key.toLowerCase();
-
- var property = this.config[key];
-
- if (property && property.event) {
-
- if (this.initialConfig[key] &&
- !Lang.isUndefined(this.initialConfig[key])) {
-
- this.setProperty(key, this.initialConfig[key]);
- return true;
-
- }
-
- } else {
-
- return false;
- }
-
- },
-
- /**
- * Sets the value of a property. If the silent property is passed as
- * true, the property's event will not be fired.
- * @method setProperty
- * @param {String} key The name of the property
- * @param {String} value The value to set the property to
- * @param {Boolean} silent Whether the value should be set silently,
- * without firing the property event.
- * @return {Boolean} True, if the set was successful, false if it failed.
- */
- setProperty: function (key, value, silent) {
-
- var property;
-
- key = key.toLowerCase();
- YAHOO.log("setProperty: " + key + "=" + value, "info", "Config");
-
- if (this.queueInProgress && ! silent) {
- // Currently running through a queue...
- this.queueProperty(key,value);
- return true;
-
- } else {
- property = this.config[key];
- if (property && property.event) {
- if (property.validator && !property.validator(value)) {
- return false;
- } else {
- property.value = value;
- if (! silent) {
- this.fireEvent(key, value);
- this.configChangedEvent.fire([key, value]);
- }
- return true;
- }
- } else {
- return false;
- }
- }
- },
-
- /**
- * Sets the value of a property and queues its event to execute. If the
- * event is already scheduled to execute, it is
- * moved from its current position to the end of the queue.
- * @method queueProperty
- * @param {String} key The name of the property
- * @param {String} value The value to set the property to
- * @return {Boolean} true, if the set was successful, false if
- * it failed.
- */
- queueProperty: function (key, value) {
-
- key = key.toLowerCase();
- YAHOO.log("queueProperty: " + key + "=" + value, "info", "Config");
-
- var property = this.config[key],
- foundDuplicate = false,
- iLen,
- queueItem,
- queueItemKey,
- queueItemValue,
- sLen,
- supercedesCheck,
- qLen,
- queueItemCheck,
- queueItemCheckKey,
- queueItemCheckValue,
- i,
- s,
- q;
-
- if (property && property.event) {
-
- if (!Lang.isUndefined(value) && property.validator &&
- !property.validator(value)) { // validator
- return false;
- } else {
-
- if (!Lang.isUndefined(value)) {
- property.value = value;
- } else {
- value = property.value;
- }
-
- foundDuplicate = false;
- iLen = this.eventQueue.length;
-
- for (i = 0; i < iLen; i++) {
- queueItem = this.eventQueue[i];
-
- if (queueItem) {
- queueItemKey = queueItem[0];
- queueItemValue = queueItem[1];
- if (queueItemKey == key) {
-
- /*
- found a dupe... push to end of queue, null
- current item, and break
- */
-
- this.eventQueue[i] = null;
-
- this.eventQueue.push(
- [key, (!Lang.isUndefined(value) ?
- value : queueItemValue)]);
-
- foundDuplicate = true;
- break;
- }
- }
- }
-
- // this is a refire, or a new property in the queue
-
- if (! foundDuplicate && !Lang.isUndefined(value)) {
- this.eventQueue.push([key, value]);
- }
- }
-
- 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;
- }
- }
- }
- }
- }
- YAHOO.log("Config event queue: " + this.outputEventQueue(), "info", "Config");
- return true;
- } else {
- return false;
- }
- },
-
- /**
- * Fires the event for a property using the property's current value.
- * @method refireEvent
- * @param {String} key The name of the property
- */
- refireEvent: function (key) {
-
- key = key.toLowerCase();
-
- var property = this.config[key];
-
- if (property && property.event &&
-
- !Lang.isUndefined(property.value)) {
-
- if (this.queueInProgress) {
-
- this.queueProperty(key);
-
- } else {
-
- this.fireEvent(key, property.value);
-
- }
-
- }
- },
-
- /**
- * Applies a key-value Object literal to the configuration, replacing
- * any existing values, and queueing the property events.
- * Although the values will be set, fireQueue() must be called for their
- * associated events to execute.
- * @method applyConfig
- * @param {Object} userConfig The configuration Object literal
- * @param {Boolean} init When set to true, the initialConfig will
- * be set to the userConfig passed in, so that calling a reset will
- * reset the properties to the passed values.
- */
- applyConfig: function (userConfig, init) {
-
- var sKey,
- oConfig;
- if (init) {
- oConfig = {};
- for (sKey in userConfig) {
- if (Lang.hasOwnProperty(userConfig, sKey)) {
- oConfig[sKey.toLowerCase()] = userConfig[sKey];
- }
- }
- this.initialConfig = oConfig;
- }
- for (sKey in userConfig) {
- if (Lang.hasOwnProperty(userConfig, sKey)) {
- this.queueProperty(sKey, userConfig[sKey]);
- }
- }
- },
-
- /**
- * Refires the events for all configuration properties using their
- * current values.
- * @method refresh
- */
- refresh: function () {
- var prop;
- for (prop in this.config) {
- if (Lang.hasOwnProperty(this.config, prop)) {
- this.refireEvent(prop);
- }
- }
- },
-
- /**
- * Fires the normalized list of queued property change events
- * @method fireQueue
- */
- fireQueue: function () {
-
- var i,
- queueItem,
- key,
- value,
- property;
-
- this.queueInProgress = true;
- for (i = 0;i < this.eventQueue.length; i++) {
- queueItem = this.eventQueue[i];
- if (queueItem) {
-
- 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);
- }
- }
-
- this.queueInProgress = false;
- this.eventQueue = [];
- },
-
- /**
- * Subscribes an external handler to the change event for any
- * given property.
- * @method subscribeToConfigEvent
- * @param {String} key The property name
- * @param {Function} handler The handler function to use subscribe to
- * the property's event
- * @param {Object} obj The Object to use for scoping the event handler
- * (see CustomEvent documentation)
- * @param {Boolean} override Optional. If true, will override "this"
- * within the handler to map to the scope Object passed into the method.
- * @return {Boolean} True, if the subscription was successful,
- * otherwise false.
- */
- subscribeToConfigEvent: function (key, handler, obj, override) {
-
- 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;
- }
-
- },
-
- /**
- * Unsubscribes an external handler from the change event for any
- * given property.
- * @method unsubscribeFromConfigEvent
- * @param {String} key The property name
- * @param {Function} handler The handler function to use subscribe to
- * the property's event
- * @param {Object} obj The Object to use for scoping the event
- * handler (see CustomEvent documentation)
- * @return {Boolean} True, if the unsubscription was successful,
- * otherwise false.
- */
- unsubscribeFromConfigEvent: function (key, handler, obj) {
- var property = this.config[key.toLowerCase()];
- if (property && property.event) {
- return property.event.unsubscribe(handler, obj);
- } else {
- return false;
- }
- },
-
- /**
- * Returns a string representation of the Config object
- * @method toString
- * @return {String} The Config object in string format.
- */
- toString: function () {
- var output = "Config";
- if (this.owner) {
- output += " [" + this.owner.toString() + "]";
- }
- return output;
- },
-
- /**
- * Returns a string representation of the Config object's current
- * CustomEvent queue
- * @method outputEventQueue
- * @return {String} The string list of CustomEvents currently queued
- * for execution
- */
- outputEventQueue: function () {
- var output = "",
- queueItem,
- q,
- nQueue = this.eventQueue.length;
-
- for (q = 0; q < nQueue; q++) {
- queueItem = this.eventQueue[q];
- if (queueItem) {
- output += queueItem[0] + "=" + queueItem[1] + ", ";
- }
- }
- return output;
- },
- /**
- * Sets all properties to null, unsubscribes all listeners from each
- * property's change event and all listeners from the configChangedEvent.
- * @method destroy
- */
- destroy: function () {
- var oConfig = this.config,
- sProperty,
- oProperty;
- for (sProperty in oConfig) {
-
- if (Lang.hasOwnProperty(oConfig, sProperty)) {
- oProperty = oConfig[sProperty];
- oProperty.event.unsubscribeAll();
- oProperty.event = null;
- }
-
- }
-
- this.configChangedEvent.unsubscribeAll();
-
- this.configChangedEvent = null;
- this.owner = null;
- this.config = null;
- this.initialConfig = null;
- this.eventQueue = null;
-
- }
- };
-
-
-
- /**
- * Checks to determine if a particular function/Object pair are already
- * subscribed to the specified CustomEvent
- * @method YAHOO.util.Config.alreadySubscribed
- * @static
- * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check
- * the subscriptions
- * @param {Function} fn The function to look for in the subscribers list
- * @param {Object} obj The execution scope Object for the subscription
- * @return {Boolean} true, if the function/Object pair is already subscribed
- * to the CustomEvent passed in
- */
- Config.alreadySubscribed = function (evt, fn, obj) {
-
- var nSubscribers = evt.subscribers.length,
- subsc,
- 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.
- * @namespace YAHOO.widget
- * @class DateMath
- */
- YAHOO.widget.DateMath = {
- /**
- * Constant field representing Day
- * @property DAY
- * @static
- * @final
- * @type String
- */
- DAY : "D",
- /**
- * Constant field representing Week
- * @property WEEK
- * @static
- * @final
- * @type String
- */
- WEEK : "W",
- /**
- * Constant field representing Year
- * @property YEAR
- * @static
- * @final
- * @type String
- */
- YEAR : "Y",
- /**
- * Constant field representing Month
- * @property MONTH
- * @static
- * @final
- * @type String
- */
- MONTH : "M",
- /**
- * Constant field representing one day, in milliseconds
- * @property ONE_DAY_MS
- * @static
- * @final
- * @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.
- * <p>
- * 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.
- * </p>
- * @property WEEK_ONE_JAN_DATE
- * @static
- * @type Number
- */
- WEEK_ONE_JAN_DATE : 1,
- /**
- * Adds the specified amount of time to the this instance.
- * @method add
- * @param {Date} date The JavaScript Date object to perform addition on
- * @param {String} field The field constant to be used for performing addition.
- * @param {Number} amount The number of units (measured in the field constant) to add to the date.
- * @return {Date} The resulting Date object
- */
- add : function(date, field, amount) {
- var d = new Date(date.getTime());
- switch (field) {
- case this.MONTH:
- var newMonth = date.getMonth() + amount;
- var years = 0;
- if (newMonth < 0) {
- while (newMonth < 0) {
- newMonth += 12;
- years -= 1;
- }
- } else if (newMonth > 11) {
- while (newMonth > 11) {
- newMonth -= 12;
- years += 1;
- }
- }
- d.setMonth(newMonth);
- d.setFullYear(date.getFullYear() + years);
- break;
- case this.DAY:
- this._addDays(d, amount);
- // d.setDate(date.getDate() + amount);
- break;
- case this.YEAR:
- d.setFullYear(date.getFullYear() + amount);
- break;
- case this.WEEK:
- 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.
- * <p>
- * Fix approach and original findings are available here:
- * http://brianary.blogspot.com/2006/03/safari-date-bug.html
- * </p>
- * @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
- * @param {Number} field The this field constant to be used for performing subtraction.
- * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
- * @return {Date} The resulting Date object
- */
- subtract : function(date, field, amount) {
- return this.add(date, field, (amount*-1));
- },
- /**
- * Determines whether a given date is before another date on the calendar.
- * @method before
- * @param {Date} date The Date object to compare with the compare argument
- * @param {Date} compareTo The Date object to use for the comparison
- * @return {Boolean} true if the date occurs before the compared date; false if not.
- */
- before : function(date, compareTo) {
- var ms = compareTo.getTime();
- if (date.getTime() < ms) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Determines whether a given date is after another date on the calendar.
- * @method after
- * @param {Date} date The Date object to compare with the compare argument
- * @param {Date} compareTo The Date object to use for the comparison
- * @return {Boolean} true if the date occurs after the compared date; false if not.
- */
- after : function(date, compareTo) {
- var ms = compareTo.getTime();
- if (date.getTime() > ms) {
- return true;
- } else {
- return false;
- }
- },
- /**
- * Determines whether a given date is between two other dates on the calendar.
- * @method between
- * @param {Date} date The date to check for
- * @param {Date} dateBegin The start of the range
- * @param {Date} dateEnd The end of the range
- * @return {Boolean} true if the date occurs between the compared dates; false if not.
- */
- between : function(date, dateBegin, dateEnd) {
- if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
- return true;
- } else {
- return false;
- }
- },
-
- /**
- * Retrieves a JavaScript Date object representing January 1 of any given year.
- * @method getJan1
- * @param {Number} calendarYear The calendar year for which to retrieve January 1
- * @return {Date} January 1 of the calendar year specified.
- */
- getJan1 : function(calendarYear) {
- return this.getDate(calendarYear,0,1);
- },
- /**
- * Calculates the number of days the specified date is from January 1 of the specified calendar year.
- * Passing January 1 to this function would return an offset value of zero.
- * @method getDayOffset
- * @param {Date} date The JavaScript date for which to find the offset
- * @param {Number} calendarYear The calendar year to use for determining the offset
- * @return {Number} The number of days since January 1 of the given year
- */
- getDayOffset : function(date, calendarYear) {
- var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
-
- // Find the number of days the passed in date is away from the calendar year start
- var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
- return dayOffset;
- },
- /**
- * Calculates the week number for the given date. 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} 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, firstDayOfWeek, janDate) {
- // Setup Defaults
- firstDayOfWeek = firstDayOfWeek || 0;
- janDate = janDate || this.WEEK_ONE_JAN_DATE;
- 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.
- * @return {Boolean} true if the date overlaps two different years.
- */
- isYearOverlapWeek : function(weekBeginDate) {
- var overlaps = false;
- var nextWeek = this.add(weekBeginDate, this.DAY, 6);
- if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
- overlaps = true;
- }
- return overlaps;
- },
- /**
- * Determines if a given week overlaps two different months.
- * @method isMonthOverlapWeek
- * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
- * @return {Boolean} true if the date overlaps two different months.
- */
- isMonthOverlapWeek : function(weekBeginDate) {
- var overlaps = false;
- var nextWeek = this.add(weekBeginDate, this.DAY, 6);
- if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
- overlaps = true;
- }
- return overlaps;
- },
- /**
- * Gets the first day of a month containing a given date.
- * @method findMonthStart
- * @param {Date} date The JavaScript Date used to calculate the month start
- * @return {Date} The JavaScript Date representing the first day of the month
- */
- findMonthStart : function(date) {
- var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
- return start;
- },
- /**
- * Gets the last day of a month containing a given date.
- * @method findMonthEnd
- * @param {Date} date The JavaScript Date used to calculate the month end
- * @return {Date} The JavaScript Date representing the last day of the month
- */
- findMonthEnd : function(date) {
- var start = this.findMonthStart(date);
- var nextMonth = this.add(start, this.MONTH, 1);
- var end = this.subtract(nextMonth, this.DAY, 1);
- return end;
- },
- /**
- * Clears the time fields from a given date, effectively setting the time to 12 noon.
- * @method clearTime
- * @param {Date} date The JavaScript Date for which the time fields will be cleared
- * @return {Date} The JavaScript Date cleared of all time fields
- */
- 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.
- * <p>
- * <em>NOTE:</em>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.
- * </p>
- * @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.
- * @module calendar
- * @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
- * that can be manipulated to select a single date, move back and forth between
- * months and years.
- * <p>To construct the placeholder for the calendar widget, the code is as
- * follows:
- * <xmp>
- * <div id="calContainer"></div>
- * </xmp>
- * </p>
- * <p>
- * <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
- * 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.:
- * <xmp>
- * var c = new YAHOO.widget.Calendar("calContainer", configOptions);
- * </xmp>
- * or:
- * <xmp>
- * var containerDiv = YAHOO.util.Dom.get("calContainer");
- * var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
- * </xmp>
- * </p>
- * <p>
- * 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".
- * </p>
- *
- * @namespace YAHOO.widget
- * @class Calendar
- * @constructor
- * @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.
- */
- function Calendar(id, containerId, config) {
- this.init.apply(this, arguments);
- }
- /**
- * The path to be used for images loaded for the Calendar
- * @property YAHOO.widget.Calendar.IMG_ROOT
- * @static
- * @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
- */
- Calendar.IMG_ROOT = null;
- /**
- * Type constant used for renderers to represent an individual date (M/D/Y)
- * @property YAHOO.widget.Calendar.DATE
- * @static
- * @final
- * @type String
- */
- Calendar.DATE = "D";
- /**
- * Type constant used for renderers to represent an individual date across any year (M/D)
- * @property YAHOO.widget.Calendar.MONTH_DAY
- * @static
- * @final
- * @type String
- */
- Calendar.MONTH_DAY = "MD";
- /**
- * Type constant used for renderers to represent a weekday
- * @property YAHOO.widget.Calendar.WEEKDAY
- * @static
- * @final
- * @type String
- */
- Calendar.WEEKDAY = "WD";
- /**
- * Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
- * @property YAHOO.widget.Calendar.RANGE
- * @static
- * @final
- * @type String
- */
- Calendar.RANGE = "R";
- /**
- * Type constant used for renderers to represent a month across any year
- * @property YAHOO.widget.Calendar.MONTH
- * @static
- * @final
- * @type String
- */
- Calendar.MONTH = "M";
- /**
- * Constant that represents the total number of date cells that are displayed in a given month
- * @property YAHOO.widget.Calendar.DISPLAY_DAYS
- * @static
- * @final
- * @type Number
- */
- Calendar.DISPLAY_DAYS = 42;
- /**
- * Constant used for halting the execution of the remainder of the render stack
- * @property YAHOO.widget.Calendar.STOP_RENDER
- * @static
- * @final
- * @type String
- */
- Calendar.STOP_RENDER = "S";
- /**
- * Constant used to represent short date field string formats (e.g. Tu or Feb)
- * @property YAHOO.widget.Calendar.SHORT
- * @static
- * @final
- * @type String
- */
- Calendar.SHORT = "short";
- /**
- * Constant used to represent long date field string formats (e.g. Monday or February)
- * @property YAHOO.widget.Calendar.LONG
- * @static
- * @final
- * @type String
- */
- Calendar.LONG = "long";
- /**
- * Constant used to represent medium date field string formats (e.g. Mon)
- * @property YAHOO.widget.Calendar.MEDIUM
- * @static
- * @final
- * @type String
- */
- Calendar.MEDIUM = "medium";
- /**
- * Constant used to represent single character date field string formats (e.g. M, T, W)
- * @property YAHOO.widget.Calendar.ONE_CHAR
- * @static
- * @final
- * @type String
- */
- Calendar.ONE_CHAR = "1char";
- /**
- * The set of default Config property keys and values for the Calendar
- * @property YAHOO.widget.Calendar._DEFAULT_CONFIG
- * @final
- * @static
- * @private
- * @type Object
- */
- 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},
- TITLE : {key:"title", value:""},
- CLOSE : {key:"close", value:false},
- IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
- MINDATE : {key:"mindate", value:null},
- MAXDATE : {key:"maxdate", value:null},
- MULTI_SELECT : {key:"multi_select", value:false},
- START_WEEKDAY : {key:"start_weekday", value:0},
- SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
- SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
- SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
- HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
- NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
- NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
- MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
- MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
- WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
- WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
- WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
- WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
- LOCALE_MONTHS:{key:"locale_months", value:"long"},
- LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
- DATE_DELIMITER:{key:"date_delimiter", value:","},
- DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
- DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
- MY_MONTH_POSITION:{key:"my_month_position", value:1},
- MY_YEAR_POSITION:{key:"my_year_position", value:2},
- MD_MONTH_POSITION:{key:"md_month_position", value:1},
- MD_DAY_POSITION:{key:"md_day_position", value:2},
- MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
- MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
- MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
- 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:""},
- 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
- * @final
- * @static
- * @private
- * @type Object
- */
- 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",
- 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"
- };
- /**
- * The set of default style constants for the Calendar
- * @property YAHOO.widget.Calendar._STYLES
- * @final
- * @static
- * @private
- * @type Object
- */
- Calendar._STYLES = {
- CSS_ROW_HEADER: "calrowhead",
- CSS_ROW_FOOTER: "calrowfoot",
- CSS_CELL : "calcell",
- CSS_CELL_SELECTOR : "selector",
- CSS_CELL_SELECTED : "selected",
- CSS_CELL_SELECTABLE : "selectable",
- CSS_CELL_RESTRICTED : "restricted",
- CSS_CELL_TODAY : "today",
- CSS_CELL_OOM : "oom",
- CSS_CELL_OOB : "previous",
- CSS_HEADER : "calheader",
- CSS_HEADER_TEXT : "calhead",
- CSS_BODY : "calbody",
- CSS_WEEKDAY_CELL : "calweekdaycell",
- CSS_WEEKDAY_ROW : "calweekdayrow",
- CSS_FOOTER : "calfoot",
- CSS_CALENDAR : "yui-calendar",
- CSS_SINGLE : "single",
- 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",
- CSS_CELL_RIGHT : "calcellright",
- CSS_CELL_BOTTOM : "calcellbottom",
- CSS_CELL_HOVER : "calcellhover",
- CSS_CELL_HIGHLIGHT1 : "highlight1",
- CSS_CELL_HIGHLIGHT2 : "highlight2",
- CSS_CELL_HIGHLIGHT3 : "highlight3",
- CSS_CELL_HIGHLIGHT4 : "highlight4"
- };
- Calendar.prototype = {
- /**
- * The configuration object used to set up the calendars various locale and style options.
- * @property Config
- * @private
- * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
- * @type Object
- */
- Config : null,
- /**
- * The parent CalendarGroup, only to be set explicitly by the parent group
- * @property parent
- * @type CalendarGroup
- */
- parent : null,
- /**
- * The index of this item in the parent group
- * @property index
- * @type Number
- */
- index : -1,
- /**
- * The collection of calendar table cells
- * @property cells
- * @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
- * @type Array[](Number[])
- */
- cellDates : null,
- /**
- * 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
- */
- oDomContainer : null,
- /**
- * A Date object representing today's date.
- * @property today
- * @type Date
- */
- today : null,
- /**
- * The list of render functions, along with required parameters, used to render cells.
- * @property renderStack
- * @type Array[]
- */
- renderStack : null,
- /**
- * A copy of the initial render functions created before rendering.
- * @property _renderStack
- * @private
- * @type Array
- */
- _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
- * @type Array
- */
- _selectedDates : null,
- /**
- * A map of DOM event handlers to attach to cells associated with specific CSS class names
- * @property domEventMap
- * @type Object
- */
- domEventMap : null,
- /**
- * 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
- new Calendar(String)
- new Calendar(HTMLElement)
- new Calendar(String, ConfigObject)
- new Calendar(HTMLElement, ConfigObject)
- Pre 2.4.0 Constructor signatures
- 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};
- 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;
- }
- break;
- default: // 3+
- nArgs.id = args[0];
- nArgs.container = args[1];
- nArgs.config = args[2];
- break;
- }
- } else {
- this.logger.log("Invalid constructor/init arguments", "error");
- }
- return nArgs;
- },
- /**
- * 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.
- */
- init : function(id, container, config) {
- // Normalize 2.4.0, pre 2.4.0 args
- var nArgs = this._parseArgs(arguments);
- id = nArgs.id;
- container = nArgs.container;
- config = nArgs.config;
- this.oDomContainer = Dom.get(container);
- if (!this.oDomContainer) { this.logger.log("Container not found in document.", "error"); }
- if (!this.oDomContainer.id) {
- this.oDomContainer.id = Dom.generateId();
- }
- if (!id) {
- id = this.oDomContainer.id + "_t";
- }
- this.id = id;
- this.containerId = this.oDomContainer.id;
- this.logger = new YAHOO.widget.LogWriter("Calendar " + this.id);
- this.initEvents();
- this.today = new Date();
- DateMath.clearTime(this.today);
- /**
- * 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 = {};
- /**
- * The local object which contains the Calendar's locale settings
- * @property Locale
- * @type Object
- */
- this.Locale = {};
- this.initStyles();
- Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
- Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
- this.cellDates = [];
- this.cells = [];
- this.renderStack = [];
- this._renderStack = [];
- 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
- */
- 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;
- }
- }
- }
- }
- },
- /**
- * Default handler for the "title" property
- * @method configTitle
- */
- 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(" ");
- }
- }
- },
-
- /**
- * Default handler for the "close" property
- * @method configClose
- */
- 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();
- }
- }
- },
- /**
- * Initializes Calendar's built-in CustomEvents
- * @method initEvents
- */
- initEvents : function() {
- var defEvents = Calendar._EVENT_TYPES,
- CE = YAHOO.util.CustomEvent,
- cal = this; // To help with minification
- /**
- * Fired before a date selection is made
- * @event beforeSelectEvent
- */
- cal.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
- /**
- * 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);
- /**
- * 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);
- /**
- * Fired just before the Calendar is to be destroyed
- * @event beforeDestroyEvent
- */
- cal.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
- /**
- * 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);
- /**
- * Fired when the Calendar is reset
- * @event resetEvent
- */
- cal.resetEvent = new CE(defEvents.RESET);
- /**
- * Fired when the Calendar is cleared
- * @event clearEvent
- */
- cal.clearEvent = new CE(defEvents.CLEAR);
- /**
- * Fired just before the Calendar is to be shown
- * @event beforeShowEvent
- */
- cal.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
- /**
- * Fired after the Calendar is shown
- * @event showEvent
- */
- cal.showEvent = new CE(defEvents.SHOW);
- /**
- * Fired just before the Calendar is to be hidden
- * @event beforeHideEvent
- */
- cal.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
- /**
- * Fired after the Calendar is hidden
- * @event hideEvent
- */
- cal.hideEvent = new CE(defEvents.HIDE);
- /**
- * Fired just before the CalendarNavigator is to be shown
- * @event beforeShowNavEvent
- */
- cal.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
-
- /**
- * Fired after the CalendarNavigator is shown
- * @event showNavEvent
- */
- cal.showNavEvent = new CE(defEvents.SHOW_NAV);
-
- /**
- * Fired just before the CalendarNavigator is to be hidden
- * @event beforeHideNavEvent
- */
- cal.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
-
- /**
- * Fired after the CalendarNavigator is hidden
- * @event hideNavEvent
- */
- cal.hideNavEvent = new CE(defEvents.HIDE_NAV);
- /**
- * Fired just before the CalendarNavigator is to be rendered
- * @event beforeRenderNavEvent
- */
- cal.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
- /**
- * Fired after the CalendarNavigator is rendered
- * @event renderNavEvent
- */
- cal.renderNavEvent = new CE(defEvents.RENDER_NAV);
- 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 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
- */
- 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 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 default event handler for date cell selection. Currently attached to
- * the Calendar's bounding box, referenced by it's <a href="#property_oDomContainer">oDomContainer</a> property.
- *
- * @method doSelectCell
- * @param {DOMEvent} e The DOM event
- * @param {Calendar} cal A reference to the calendar
- */
- doSelectCell : function(e, cal) {
- var cell, d, date, index;
- var target = Event.getTarget(e),
- tagName = target.tagName.toLowerCase(),
- defSelector = false;
- while (tagName != "td" && !Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- if (!defSelector && tagName == "a" && Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
- defSelector = true;
- }
- target = target.parentNode;
- tagName = target.tagName.toLowerCase();
- if (target == this.oDomContainer || tagName == "html") {
- return;
- }
- }
- if (defSelector) {
- // Stop link href navigation for default renderer
- Event.preventDefault(e);
- }
-
- cell = target;
- 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;
- cal.logger.log("Selecting cell " + index + " via click", "info");
- if (cal.Options.MULTI_SELECT) {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
- var cellDate = cal.cellDates[index];
- var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
- if (cellDateIndex > -1) {
- cal.deselectCell(index);
- } else {
- cal.selectCell(index);
- }
- } else {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
- cal.selectCell(index);
- }
- }
- }
- }
- },
- /**
- * 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;
- }
- while (target.tagName && target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (!target.tagName || target.tagName.toLowerCase() == "html") {
- return;
- }
- }
- if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
- }
- },
- /**
- * 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;
- }
- while (target.tagName && target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (!target.tagName || target.tagName.toLowerCase() == "html") {
- return;
- }
- }
- if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
- }
- },
- setupConfig : function() {
- var cfg = this.cfg;
- /**
- * The month/year representing the current visible Calendar date (mm/yyyy)
- * @config pagedate
- * @type String | Date
- * @default today's date
- */
- cfg.addProperty(DEF_CFG.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
- /**
- * The date or range of dates representing the current Calendar selection
- * @config selected
- * @type String
- * @default []
- */
- cfg.addProperty(DEF_CFG.SELECTED.key, { value:[], handler:this.configSelected } );
- /**
- * The title to display above the Calendar's month header
- * @config title
- * @type String
- * @default ""
- */
- cfg.addProperty(DEF_CFG.TITLE.key, { value:DEF_CFG.TITLE.value, handler:this.configTitle } );
- /**
- * Whether or not a close button should be displayed for this Calendar
- * @config close
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.CLOSE.key, { value:DEF_CFG.CLOSE.value, handler:this.configClose } );
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.IFRAME.key, { value:DEF_CFG.IFRAME.value, handler:this.configIframe, validator:cfg.checkBoolean } );
- /**
- * The minimum selectable date in the current Calendar (mm/dd/yyyy)
- * @config mindate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MINDATE.key, { value:DEF_CFG.MINDATE.value, handler:this.configMinDate } );
- /**
- * The maximum selectable date in the current Calendar (mm/dd/yyyy)
- * @config maxdate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MAXDATE.key, { value:DEF_CFG.MAXDATE.value, handler:this.configMaxDate } );
-
-
- // Options properties
-
- /**
- * True if the Calendar should allow multiple selections. False by default.
- * @config MULTI_SELECT
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.MULTI_SELECT.key, { value:DEF_CFG.MULTI_SELECT.value, handler:this.configOptions, validator:cfg.checkBoolean } );
- /**
- * The weekday the week begins on. Default is 0 (Sunday = 0, Monday = 1 ... Saturday = 6).
- * @config START_WEEKDAY
- * @type number
- * @default 0
- */
- cfg.addProperty(DEF_CFG.START_WEEKDAY.key, { value:DEF_CFG.START_WEEKDAY.value, handler:this.configOptions, validator:cfg.checkNumber } );
-
- /**
- * True if the Calendar should show weekday labels. True by default.
- * @config SHOW_WEEKDAYS
- * @type Boolean
- * @default true
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEKDAYS.key, { value:DEF_CFG.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row headers. False by default.
- * @config SHOW_WEEK_HEADER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_HEADER.key, { value:DEF_CFG.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row footers. False by default.
- * @config SHOW_WEEK_FOOTER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_FOOTER.key,{ value:DEF_CFG.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.HIDE_BLANK_WEEKS.key, { value:DEF_CFG.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator: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
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_LEFT.key, { value:DEF_CFG.NAV_ARROW_LEFT.value, handler:this.configOptions } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_RIGHT.key, { value:DEF_CFG.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
-
- // 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"]
- */
- cfg.addProperty(DEF_CFG.MONTHS_SHORT.key, { value:DEF_CFG.MONTHS_SHORT.value, handler:this.configLocale } );
-
- /**
- * 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"
- */
- cfg.addProperty(DEF_CFG.MONTHS_LONG.key, { value:DEF_CFG.MONTHS_LONG.value, handler:this.configLocale } );
- /**
- * The 1-character weekday labels for the current locale.
- * @config WEEKDAYS_1CHAR
- * @type String[]
- * @default ["S", "M", "T", "W", "T", "F", "S"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_1CHAR.key, { value:DEF_CFG.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
-
- /**
- * The short weekday labels for the current locale.
- * @config WEEKDAYS_SHORT
- * @type String[]
- * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_SHORT.key, { value:DEF_CFG.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"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_MEDIUM.key, { value:DEF_CFG.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"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_LONG.key, { value:DEF_CFG.WEEKDAYS_LONG.value, handler:this.configLocale } );
-
- /**
- * Refreshes the locale values used to build the Calendar.
- * @method refreshLocale
- * @private
- */
- var refreshLocale = function() {
- cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
- cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
- };
-
- cfg.subscribeToConfigEvent(DEF_CFG.START_WEEKDAY.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_SHORT.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_LONG.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_SHORT.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.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"
- */
- cfg.addProperty(DEF_CFG.LOCALE_MONTHS.key, { value:DEF_CFG.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"
- */
- cfg.addProperty(DEF_CFG.LOCALE_WEEKDAYS.key, { value:DEF_CFG.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
-
- /**
- * The value used to delimit individual dates in a date string passed to various Calendar functions.
- * @config DATE_DELIMITER
- * @type String
- * @default ","
- */
- cfg.addProperty(DEF_CFG.DATE_DELIMITER.key, { value:DEF_CFG.DATE_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The value used to delimit date fields in a date string passed to various Calendar functions.
- * @config DATE_FIELD_DELIMITER
- * @type String
- * @default "/"
- */
- cfg.addProperty(DEF_CFG.DATE_FIELD_DELIMITER.key, { value:DEF_CFG.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 "-"
- */
- cfg.addProperty(DEF_CFG.DATE_RANGE_DELIMITER.key, { value:DEF_CFG.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The position of the month in a month/year date string
- * @config MY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MY_MONTH_POSITION.key, { value:DEF_CFG.MY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/year date string
- * @config MY_YEAR_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MY_YEAR_POSITION.key, { value:DEF_CFG.MY_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day date string
- * @config MD_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MD_MONTH_POSITION.key, { value:DEF_CFG.MD_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/year date string
- * @config MD_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MD_DAY_POSITION.key, { value:DEF_CFG.MD_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day/year date string
- * @config MDY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MDY_MONTH_POSITION.key, { value:DEF_CFG.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/day/year date string
- * @config MDY_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MDY_DAY_POSITION.key, { value:DEF_CFG.MDY_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/day/year date string
- * @config MDY_YEAR_POSITION
- * @type Number
- * @default 3
- */
- cfg.addProperty(DEF_CFG.MDY_YEAR_POSITION.key, { value:DEF_CFG.MDY_YEAR_POSITION.value, handler:this.configLocale, validator: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
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_POSITION.key, { value:DEF_CFG.MY_LABEL_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_POSITION.key, { value:DEF_CFG.MY_LABEL_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The suffix used after the month when rendering the Calendar header
- * @config MY_LABEL_MONTH_SUFFIX
- * @type String
- * @default " "
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_SUFFIX.key, { value:DEF_CFG.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 ""
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_SUFFIX.key, { value:DEF_CFG.MY_LABEL_YEAR_SUFFIX.value, handler:this.configLocale } );
- /**
- * Configuration for the Month/Year CalendarNavigator UI which allows the user to jump directly to a
- * specific Month/Year without having to scroll sequentially through months.
- * <p>
- * Setting this property to null (default value) or false, will disable the CalendarNavigator UI.
- * </p>
- * <p>
- * Setting this property to true will enable the CalendarNavigatior UI with the default CalendarNavigator configuration values.
- * </p>
- * <p>
- * 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).
- * </p>
- * <dl>
- * <dt>strings</dt>
- * <dd><em>Object</em> : An object with the properties shown below, defining the string labels to use in the Navigator's UI
- * <dl>
- * <dt>month</dt><dd><em>String</em> : The string to use for the month label. Defaults to "Month".</dd>
- * <dt>year</dt><dd><em>String</em> : The string to use for the year label. Defaults to "Year".</dd>
- * <dt>submit</dt><dd><em>String</em> : The string to use for the submit button label. Defaults to "Okay".</dd>
- * <dt>cancel</dt><dd><em>String</em> : The string to use for the cancel button label. Defaults to "Cancel".</dd>
- * <dt>invalidYear</dt><dd><em>String</em> : The string to use for invalid year values. Defaults to "Year needs to be a number".</dd>
- * </dl>
- * </dd>
- * <dt>monthFormat</dt><dd><em>String</em> : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG</dd>
- * <dt>initialFocus</dt><dd><em>String</em> : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"</dd>
- * </dl>
- * <p>E.g.</p>
- * <pre>
- * var navConfig = {
- * strings: {
- * month:"Calendar Month",
- * year:"Calendar Year",
- * submit: "Submit",
- * cancel: "Cancel",
- * invalidYear: "Please enter a valid year"
- * },
- * monthFormat: YAHOO.widget.Calendar.SHORT,
- * initialFocus: "month"
- * }
- * </pre>
- * @config navigator
- * @type {Object|Boolean}
- * @default null
- */
- cfg.addProperty(DEF_CFG.NAV.key, { value:DEF_CFG.NAV.value, handler:this.configNavigator } );
- /**
- * The map of UI strings which the Calendar UI uses.
- *
- * @config strings
- * @type {Object}
- * @default An object with the properties shown below:
- * <dl>
- * <dt>previousMonth</dt><dd><em>String</em> : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".</dd>
- * <dt>nextMonth</dt><dd><em>String</em> : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".</dd>
- * <dt>close</dt><dd><em>String</em> : The string to use for the close button label. Defaults to "Close".</dd>
- * </dl>
- */
- 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
- });
- },
- /**
- * The default handler for the "strings" property
- * @method configStrings
- */
- configStrings : function(type, args, obj) {
- var val = Lang.merge(DEF_CFG.STRINGS.value, args[0]);
- this.cfg.setProperty(DEF_CFG.STRINGS.key, val, true);
- },
- /**
- * The default handler for the "pagedate" property
- * @method configPageDate
- */
- configPageDate : function(type, args, obj) {
- this.cfg.setProperty(DEF_CFG.PAGEDATE.key, this._parsePageDate(args[0]), true);
- },
- /**
- * The default handler for the "mindate" property
- * @method configMinDate
- */
- configMinDate : function(type, args, obj) {
- var val = args[0];
- if (Lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(DEF_CFG.MINDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
- }
- },
- /**
- * The default handler for the "maxdate" property
- * @method configMaxDate
- */
- configMaxDate : function(type, args, obj) {
- var val = args[0];
- if (Lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(DEF_CFG.MAXDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
- }
- },
- /**
- * The default handler for the "selected" property
- * @method configSelected
- */
- configSelected : function(type, args, obj) {
- var selected = args[0],
- cfgSelected = DEF_CFG.SELECTED.key;
-
- if (selected) {
- if (Lang.isString(selected)) {
- this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
- }
- }
- if (! this._selectedDates) {
- this._selectedDates = this.cfg.getProperty(cfgSelected);
- }
- },
-
- /**
- * The default handler for all configuration options properties
- * @method configOptions
- */
- configOptions : function(type, args, obj) {
- this.Options[type.toUpperCase()] = args[0];
- },
- /**
- * The default handler for all configuration locale properties
- * @method configLocale
- */
- configLocale : function(type, args, obj) {
- this.Locale[type.toUpperCase()] = args[0];
- this.cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
- this.cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
- },
-
- /**
- * The default handler for all configuration locale field length properties
- * @method configLocaleValues
- */
- configLocaleValues : function(type, args, obj) {
- type = type.toLowerCase();
- var val = args[0],
- cfg = this.cfg,
- Locale = this.Locale;
- switch (type) {
- case DEF_CFG.LOCALE_MONTHS.key:
- switch (val) {
- case Calendar.SHORT:
- Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_SHORT.key).concat();
- break;
- case Calendar.LONG:
- Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_LONG.key).concat();
- break;
- }
- break;
- case DEF_CFG.LOCALE_WEEKDAYS.key:
- switch (val) {
- case Calendar.ONE_CHAR:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_1CHAR.key).concat();
- break;
- case Calendar.SHORT:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_SHORT.key).concat();
- break;
- case Calendar.MEDIUM:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_MEDIUM.key).concat();
- break;
- case Calendar.LONG:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_LONG.key).concat();
- break;
- }
-
- var START_WEEKDAY = cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
-
- if (START_WEEKDAY > 0) {
- for (var w=0; w < START_WEEKDAY; ++w) {
- Locale.LOCALE_WEEKDAYS.push(Locale.LOCALE_WEEKDAYS.shift());
- }
- }
- break;
- }
- },
- /**
- * The default handler for the "navigator" property
- * @method configNavigator
- */
- configNavigator : function(type, args, obj) {
- var val = args[0];
- if (YAHOO.widget.CalendarNavigator && (val === true || Lang.isObject(val))) {
- if (!this.oNavigator) {
- this.oNavigator = new YAHOO.widget.CalendarNavigator(this);
- // Cleanup DOM Refs/Events before innerHTML is removed.
- this.beforeRenderEvent.subscribe(function () {
- if (!this.pages) {
- this.oNavigator.erase();
- }
- }, this, true);
- }
- } else {
- if (this.oNavigator) {
- this.oNavigator.destroy();
- this.oNavigator = null;
- }
- }
- },
- /**
- * Defines the style constants for the Calendar
- * @method initStyles
- */
- initStyles : function() {
- var defStyle = Calendar._STYLES;
- this.Style = {
- /**
- * @property Style.CSS_ROW_HEADER
- */
- CSS_ROW_HEADER: defStyle.CSS_ROW_HEADER,
- /**
- * @property Style.CSS_ROW_FOOTER
- */
- CSS_ROW_FOOTER: defStyle.CSS_ROW_FOOTER,
- /**
- * @property Style.CSS_CELL
- */
- CSS_CELL : defStyle.CSS_CELL,
- /**
- * @property Style.CSS_CELL_SELECTOR
- */
- CSS_CELL_SELECTOR : defStyle.CSS_CELL_SELECTOR,
- /**
- * @property Style.CSS_CELL_SELECTED
- */
- CSS_CELL_SELECTED : defStyle.CSS_CELL_SELECTED,
- /**
- * @property Style.CSS_CELL_SELECTABLE
- */
- CSS_CELL_SELECTABLE : defStyle.CSS_CELL_SELECTABLE,
- /**
- * @property Style.CSS_CELL_RESTRICTED
- */
- CSS_CELL_RESTRICTED : defStyle.CSS_CELL_RESTRICTED,
- /**
- * @property Style.CSS_CELL_TODAY
- */
- CSS_CELL_TODAY : defStyle.CSS_CELL_TODAY,
- /**
- * @property Style.CSS_CELL_OOM
- */
- CSS_CELL_OOM : defStyle.CSS_CELL_OOM,
- /**
- * @property Style.CSS_CELL_OOB
- */
- CSS_CELL_OOB : defStyle.CSS_CELL_OOB,
- /**
- * @property Style.CSS_HEADER
- */
- CSS_HEADER : defStyle.CSS_HEADER,
- /**
- * @property Style.CSS_HEADER_TEXT
- */
- CSS_HEADER_TEXT : defStyle.CSS_HEADER_TEXT,
- /**
- * @property Style.CSS_BODY
- */
- CSS_BODY : defStyle.CSS_BODY,
- /**
- * @property Style.CSS_WEEKDAY_CELL
- */
- CSS_WEEKDAY_CELL : defStyle.CSS_WEEKDAY_CELL,
- /**
- * @property Style.CSS_WEEKDAY_ROW
- */
- CSS_WEEKDAY_ROW : defStyle.CSS_WEEKDAY_ROW,
- /**
- * @property Style.CSS_FOOTER
- */
- CSS_FOOTER : defStyle.CSS_FOOTER,
- /**
- * @property Style.CSS_CALENDAR
- */
- CSS_CALENDAR : defStyle.CSS_CALENDAR,
- /**
- * @property Style.CSS_SINGLE
- */
- CSS_SINGLE : defStyle.CSS_SINGLE,
- /**
- * @property Style.CSS_CONTAINER
- */
- CSS_CONTAINER : defStyle.CSS_CONTAINER,
- /**
- * @property Style.CSS_NAV_LEFT
- */
- CSS_NAV_LEFT : defStyle.CSS_NAV_LEFT,
- /**
- * @property Style.CSS_NAV_RIGHT
- */
- CSS_NAV_RIGHT : defStyle.CSS_NAV_RIGHT,
- /**
- * @property Style.CSS_NAV
- */
- CSS_NAV : defStyle.CSS_NAV,
- /**
- * @property Style.CSS_CLOSE
- */
- CSS_CLOSE : defStyle.CSS_CLOSE,
- /**
- * @property Style.CSS_CELL_TOP
- */
- CSS_CELL_TOP : defStyle.CSS_CELL_TOP,
- /**
- * @property Style.CSS_CELL_LEFT
- */
- CSS_CELL_LEFT : defStyle.CSS_CELL_LEFT,
- /**
- * @property Style.CSS_CELL_RIGHT
- */
- CSS_CELL_RIGHT : defStyle.CSS_CELL_RIGHT,
- /**
- * @property Style.CSS_CELL_BOTTOM
- */
- CSS_CELL_BOTTOM : defStyle.CSS_CELL_BOTTOM,
- /**
- * @property Style.CSS_CELL_HOVER
- */
- CSS_CELL_HOVER : defStyle.CSS_CELL_HOVER,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT1
- */
- CSS_CELL_HIGHLIGHT1 : defStyle.CSS_CELL_HIGHLIGHT1,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT2
- */
- CSS_CELL_HIGHLIGHT2 : defStyle.CSS_CELL_HIGHLIGHT2,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT3
- */
- CSS_CELL_HIGHLIGHT3 : defStyle.CSS_CELL_HIGHLIGHT3,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT4
- */
- CSS_CELL_HIGHLIGHT4 : defStyle.CSS_CELL_HIGHLIGHT4
- };
- },
- /**
- * Builds the date label that will be displayed in the calendar header or
- * footer, depending on configuration.
- * @method buildMonthLabel
- * @return {String} The formatted calendar month label
- */
- buildMonthLabel : function() {
- return this._buildMonthLabel(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
- },
- /**
- * Helper method, to format a Month Year string, given a JavaScript Date, based on the
- * Calendar localization settings
- *
- * @method _buildMonthLabel
- * @private
- * @param {Date} date
- * @return {String} Formated month, year string
- */
- _buildMonthLabel : function(date) {
- var monthLabel = this.Locale.LOCALE_MONTHS[date.getMonth()] + this.Locale.MY_LABEL_MONTH_SUFFIX,
- yearLabel = date.getFullYear() + this.Locale.MY_LABEL_YEAR_SUFFIX;
- if (this.Locale.MY_LABEL_MONTH_POSITION == 2 || this.Locale.MY_LABEL_YEAR_POSITION == 1) {
- return yearLabel + monthLabel;
- } else {
- return monthLabel + yearLabel;
- }
- },
-
- /**
- * Builds the date digit that will be displayed in calendar cells
- * @method buildDayLabel
- * @param {Date} workingDate The current working date
- * @return {String} The formatted day label
- */
- buildDayLabel : function(workingDate) {
- return workingDate.getDate();
- },
-
- /**
- * Creates the title bar element and adds it to Calendar container DIV
- *
- * @method createTitleBar
- * @param {String} strTitle The title to display in the title bar
- * @return The title bar element
- */
- createTitleBar : function(strTitle) {
- var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
- tDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
- tDiv.innerHTML = strTitle;
- this.oDomContainer.insertBefore(tDiv, this.oDomContainer.firstChild);
-
- Dom.addClass(this.oDomContainer, "withtitle");
-
- return tDiv;
- },
-
- /**
- * Removes the title bar element from the DOM
- *
- * @method removeTitleBar
- */
- removeTitleBar : function() {
- var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
- if (tDiv) {
- Event.purgeElement(tDiv);
- this.oDomContainer.removeChild(tDiv);
- }
- Dom.removeClass(this.oDomContainer, "withtitle");
- },
-
- /**
- * Creates the close button HTML element and adds it to Calendar container DIV
- *
- * @method createCloseButton
- * @return The close HTML element created
- */
- createCloseButton : function() {
- var cssClose = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE,
- DEPR_CLOSE_PATH = "us/my/bn/x_d.gif",
- lnk = Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0],
- strings = this.cfg.getProperty(DEF_CFG.STRINGS.key),
- closeStr = (strings && strings.close) ? strings.close : "";
- if (!lnk) {
- lnk = document.createElement("a");
- Event.addListener(lnk, "click", function(e, cal) {
- cal.hide();
- Event.preventDefault(e);
- }, this);
- }
- lnk.href = "#";
- lnk.className = "link-close";
- if (Calendar.IMG_ROOT !== null) {
- var img = Dom.getElementsByClassName(cssClose, "img", lnk)[0] || document.createElement("img");
- img.src = Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
- img.className = cssClose;
- lnk.appendChild(img);
- } else {
- lnk.innerHTML = '<span class="' + cssClose + ' ' + this.Style.CSS_CLOSE + '">' + closeStr + '</span>';
- }
- this.oDomContainer.appendChild(lnk);
- return lnk;
- },
-
- /**
- * Removes the close button HTML element from the DOM
- *
- * @method removeCloseButton
- */
- removeCloseButton : function() {
- var btn = Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
- if (btn) {
- Event.purgeElement(btn);
- this.oDomContainer.removeChild(btn);
- }
- },
- /**
- * Renders the calendar header.
- * @method renderHeader
- * @param {Array} html The current working HTML array
- * @return {Array} The current working HTML array
- */
- renderHeader : function(html) {
- this.logger.log("Rendering header", "render");
- var colSpan = 7,
- DEPR_NAV_LEFT = "us/tr/callt.gif",
- DEPR_NAV_RIGHT = "us/tr/calrt.gif",
- cfg = this.cfg,
- pageDate = cfg.getProperty(DEF_CFG.PAGEDATE.key),
- strings= cfg.getProperty(DEF_CFG.STRINGS.key),
- prevStr = (strings && strings.previousMonth) ? strings.previousMonth : "",
- nextStr = (strings && strings.nextMonth) ? strings.nextMonth : "",
- monthLabel;
- if (cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key)) {
- colSpan += 1;
- }
-
- if (cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key)) {
- colSpan += 1;
- }
- html[html.length] = "<thead>";
- html[html.length] = "<tr>";
- html[html.length] = '<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
- html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
- var renderLeft, renderRight = false;
- if (this.parent) {
- if (this.index === 0) {
- renderLeft = true;
- }
- if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
- renderRight = true;
- }
- } else {
- renderLeft = true;
- renderRight = true;
- }
- if (renderLeft) {
- monthLabel = this._buildMonthLabel(DateMath.subtract(pageDate, DateMath.MONTH, 1));
- var leftArrow = cfg.getProperty(DEF_CFG.NAV_ARROW_LEFT.key);
- // Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
- if (leftArrow === null && Calendar.IMG_ROOT !== null) {
- leftArrow = Calendar.IMG_ROOT + DEPR_NAV_LEFT;
- }
- var leftStyle = (leftArrow === null) ? "" : ' style="background-image:url(' + leftArrow + ')"';
- html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '"' + leftStyle + ' href="#">' + prevStr + ' (' + monthLabel + ')' + '</a>';
- }
- var lbl = this.buildMonthLabel();
- var cal = this.parent || this;
- if (cal.cfg.getProperty("navigator")) {
- lbl = "<a class=\"" + this.Style.CSS_NAV + "\" href=\"#\">" + lbl + "</a>";
- }
- html[html.length] = lbl;
- if (renderRight) {
- monthLabel = this._buildMonthLabel(DateMath.add(pageDate, DateMath.MONTH, 1));
- var rightArrow = cfg.getProperty(DEF_CFG.NAV_ARROW_RIGHT.key);
- if (rightArrow === null && Calendar.IMG_ROOT !== null) {
- rightArrow = Calendar.IMG_ROOT + DEPR_NAV_RIGHT;
- }
- var rightStyle = (rightArrow === null) ? "" : ' style="background-image:url(' + rightArrow + ')"';
- html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '"' + rightStyle + ' href="#">' + nextStr + ' (' + monthLabel + ')' + '</a>';
- }
- html[html.length] = '</div>\n</th>\n</tr>';
- if (cfg.getProperty(DEF_CFG.SHOW_WEEKDAYS.key)) {
- html = this.buildWeekdays(html);
- }
-
- html[html.length] = '</thead>';
-
- return html;
- },
-
- /**
- * Renders the Calendar's weekday headers.
- * @method buildWeekdays
- * @param {Array} html The current working HTML array
- * @return {Array} The current working HTML array
- */
- buildWeekdays : function(html) {
- html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
- if (this.cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key)) {
- html[html.length] = '<th> </th>';
- }
- for(var i=0;i < this.Locale.LOCALE_WEEKDAYS.length; ++i) {
- html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
- }
- if (this.cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key)) {
- html[html.length] = '<th> </th>';
- }
- html[html.length] = '</tr>';
- 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) {
- this.logger.log("Rendering body", "render");
- var startDay = this.cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
- this.preMonthDays = workingDate.getDay();
- if (startDay > 0) {
- this.preMonthDays -= startDay;
- }
- if (this.preMonthDays < 0) {
- this.preMonthDays += 7;
- }
- this.monthDays = DateMath.findMonthEnd(workingDate).getDate();
- this.postMonthDays = Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
- this.logger.log(this.preMonthDays + " preciding out-of-month days", "render");
- this.logger.log(this.monthDays + " month days", "render");
- this.logger.log(this.postMonthDays + " post-month days", "render");
- workingDate = DateMath.subtract(workingDate, DateMath.DAY, this.preMonthDays);
- this.logger.log("Calendar page starts on " + workingDate, "render");
-
- 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);
- if (mindate) {
- mindate = DateMath.clearTime(mindate);
- }
- if (maxdate) {
- maxdate = DateMath.clearTime(maxdate);
- }
- html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
- var i = 0,
- tempDiv = document.createElement("div"),
- cell = document.createElement("td");
- tempDiv.appendChild(cell);
- var cal = this.parent || this;
- for (var r=0;r<6;r++) {
- weekNum = DateMath.getWeekNumber(workingDate, startDay);
- weekClass = weekPrefix + weekNum;
- // Local OOM check for performance, since we already have pagedate
- if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
- break;
- } else {
- html[html.length] = '<tr class="' + weekClass + '">';
- if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
- for (var d=0; d < 7; d++){ // Render actual days
- cellRenderers = [];
- this.clearElement(cell);
- cell.className = this.Style.CSS_CELL;
- cell.id = this.id + cellPrefix + i;
- this.logger.log("Rendering cell " + cell.id + " (" + workingDate.getFullYear() + "-" + (workingDate.getMonth()+1) + "-" + workingDate.getDate() + ")", "cellrender");
- if (workingDate.getDate() == todayDate &&
- workingDate.getMonth() == todayMonth &&
- workingDate.getFullYear() == todayYear) {
- cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
- }
- var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
- this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
- // 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());
- for (var s=0;s<this.renderStack.length;++s) {
- renderer = null;
- var rArray = this.renderStack[s],
- type = rArray[0],
- month,
- day,
- year;
- switch (type) {
- case Calendar.DATE:
- month = rArray[1][1];
- day = rArray[1][2];
- year = rArray[1][0];
- 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 (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 (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
- renderer = rArray[2];
- if (workingDate.getTime()==d2.getTime()) {
- this.renderStack.splice(s,1);
- }
- }
- break;
- case Calendar.WEEKDAY:
- var weekday = rArray[1][0];
- if (workingDate.getDay()+1 == weekday) {
- renderer = rArray[2];
- }
- break;
- case Calendar.MONTH:
- month = rArray[1][0];
- if (workingDate.getMonth()+1 == month) {
- renderer = rArray[2];
- }
- break;
- }
- if (renderer) {
- cellRenderers[cellRenderers.length]=renderer;
- }
- }
- }
- if (this._indexOfSelectedFieldArray(workingArray) > -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) {
- this.logger.log("renderer[" + x + "] for (" + workingDate.getFullYear() + "-" + (workingDate.getMonth()+1) + "-" + workingDate.getDate() + ")", "cellrender");
- 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<blankWeeks;++p) {
- postDays -= 7;
- }
- }
-
- if (i >= ((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] = '</tr>';
- }
- }
-
- html[html.length] = '</tbody>';
-
- 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();
- // Find starting day of the current month
- var workingDate = DateMath.findMonthStart(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
- this.resetRenderers();
- this.cellDates.length = 0;
- Event.purgeElement(this.oDomContainer, true);
- var html = [];
- html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
- html = this.renderHeader(html);
- html = this.renderBody(workingDate, html);
- html = this.renderFooter(html);
- html[html.length] = '</table>';
- this.oDomContainer.innerHTML = html.join("\n");
- 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);
- this.renderEvent.fire();
- },
- /**
- * 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);
- if (linkLeft && linkLeft.length > 0) {
- this.linkLeft = linkLeft[0];
- Event.addListener(this.linkLeft, click, this.doPreviousMonthNav, cal, true);
- }
- if (linkRight && linkRight.length > 0) {
- this.linkRight = linkRight[0];
- Event.addListener(this.linkRight, click, this.doNextMonthNav, cal, true);
- }
- if (cal.cfg.getProperty("navigator") !== null) {
- this.applyNavListeners();
- }
- 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<items.length;i++) {
- var item = items[i];
- elements = Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
-
- for (var c=0;c<elements.length;c++) {
- el = elements[c];
- Event.addListener(el, item.event, item.handler, item.scope, item.correct );
- }
- }
- }
- }
- }
- Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
- Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
- Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
- },
- applyNavListeners : function() {
- var calParent = this.parent || this,
- cal = this,
- navBtns = Dom.getElementsByClassName(this.Style.CSS_NAV, "a", this.oDomContainer);
- if (navBtns.length > 0) {
- 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();
- }
- });
- }
- },
- /**
- * 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;
- },
- /**
- * Find the Calendar's cell index for a given date.
- * If the date is not found, the method returns -1.
- * <p>
- * 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.
- * </p>
- *
- * See <a href="#cells">cells</a>, <a href="#selectCell">selectCell</a>.
- *
- * @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;
- 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;
- },
- /**
- * 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");
- if (li > -1) {
- idx = parseInt(strId.substring(li + 5), 10);
- }
- 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] = '<th class="calrowhead">' + weekNum + '</th>';
- 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] = '<th class="calrowfoot">' + weekNum + '</th>';
- 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 = '<a href="#" class="' + this.Style.CSS_CELL_SELECTOR + '">' + this.buildDayLabel(workingDate) + "</a>";
- },
-
- /**
- * 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();
- },
- /**
- * 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) {
- this.logger.log("Select: " + date, "info");
- var aToBeSelected = this._toFieldArray(date),
- validDates = [],
- selected = [],
- cfgSelected = DEF_CFG.SELECTED.key;
- this.logger.log("Selection field array: " + aToBeSelected, "info");
-
- 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);
- }
- validDates.push(toSelect);
- if (this._indexOfSelectedFieldArray(toSelect) == -1) {
- selected[selected.length] = toSelect;
- }
- }
- }
- if (validDates.length === 0) { this.logger.log("All provided dates were OOB. beforeSelect and select events not fired", "info"); }
- if (validDates.length > 0) {
- if (this.parent) {
- this.parent.cfg.setProperty(cfgSelected, selected);
- } else {
- this.cfg.setProperty(cfgSelected, selected);
- }
- this.selectEvent.fire(validDates);
- }
- 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 cell = this.cells[cellIndex],
- cellDate = this.cellDates[cellIndex],
- dCellDate = this._toDate(cellDate),
- selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
- this.logger.log("Select: " + dCellDate, "info");
- if (!selectable) {this.logger.log("The cell at cellIndex:" + cellIndex + " is not a selectable cell. beforeSelect, select events not fired", "info"); }
- 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;
- }
- 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) {
- this.logger.log("Deselect: " + date, "info");
- var aToBeDeselected = this._toFieldArray(date),
- validDates = [],
- selected = [],
- cfgSelected = DEF_CFG.SELECTED.key;
- this.logger.log("Deselection field array: " + aToBeDeselected, "info");
- for (var a=0; a < aToBeDeselected.length; ++a) {
- var toDeselect = aToBeDeselected[a];
-
- 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) { this.logger.log("All provided dates were OOB. beforeDeselect and deselect events not fired");}
-
- 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);
- var selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
- if (!selectable) { this.logger.log("The cell at cellIndex:" + cellIndex + " is not a selectable/deselectable cell", "info"); }
- if (selectable) {
- this.beforeDeselectEvent.fire();
- var selected = this.cfg.getProperty(DEF_CFG.SELECTED.key),
- dCellDate = this._toDate(cellDate),
- selectDate = cellDate.concat();
- 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, []);
- } else {
- this.cfg.setProperty(cfgSelected, []);
- }
-
- 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<date.length;++i) {
- var d = date[i];
- returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
- }
- }
-
- return returnDate;
- },
-
- /**
- * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object. The date field array
- * is the format in which dates are as provided as arguments to selectEvent and deselectEvent listeners.
- *
- * @method toDate
- * @param {Number[]} dateFieldArray The date field array to convert to a JavaScript Date.
- * @return {Date} JavaScript Date object representing the date field array.
- */
- toDate : function(dateFieldArray) {
- return this._toDate(dateFieldArray);
- },
-
- /**
- * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
- * @method _toDate
- * @private
- * @deprecated Made public, toDate
- * @param {Number[]} dateFieldArray The date field array to convert to a JavaScript Date.
- * @return {Date} JavaScript Date object representing the date field array
- */
- _toDate : function(dateFieldArray) {
- if (dateFieldArray instanceof Date) {
- return dateFieldArray;
- } else {
- return DateMath.getDate(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
- }
- },
-
- // END TYPE CONVERSION METHODS
-
- // BEGIN UTILITY METHODS
-
- /**
- * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
- * @method _fieldArraysAreEqual
- * @private
- * @param {Number[]} array1 The first date field array to compare
- * @param {Number[]} array2 The first date field array to compare
- * @return {Boolean} The boolean that represents the equality of the two arrays
- */
- _fieldArraysAreEqual : function(array1, array2) {
- var match = false;
-
- if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
- match=true;
- }
-
- return match;
- },
-
- /**
- * Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
- * @method _indexOfSelectedFieldArray
- * @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.
- */
- _indexOfSelectedFieldArray : function(find) {
- var selected = -1,
- seldates = this.cfg.getProperty(DEF_CFG.SELECTED.key);
-
- for (var s=0;s<seldates.length;++s) {
- var sArray = seldates[s];
- if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
- selected = s;
- break;
- }
- }
-
- return selected;
- },
-
- /**
- * Determines whether a given date is OOM (out of month).
- * @method isDateOOM
- * @param {Date} date The JavaScript Date object for which to check the OOM status
- * @return {Boolean} true if the date is OOM
- */
- isDateOOM : function(date) {
- return (date.getMonth() != this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getMonth());
- },
-
- /**
- * Determines whether a given date is OOB (out of bounds - less than the mindate or more than the maxdate).
- *
- * @method isDateOOB
- * @param {Date} date The JavaScript Date object for which to check the OOB status
- * @return {Boolean} true if the date is OOB
- */
- isDateOOB : function(date) {
- var minDate = this.cfg.getProperty(DEF_CFG.MINDATE.key),
- maxDate = this.cfg.getProperty(DEF_CFG.MAXDATE.key),
- dm = DateMath;
-
- if (minDate) {
- minDate = dm.clearTime(minDate);
- }
- if (maxDate) {
- maxDate = dm.clearTime(maxDate);
- }
-
- var clearedDate = new Date(date.getTime());
- clearedDate = dm.clearTime(clearedDate);
-
- return ((minDate && clearedDate.getTime() < minDate.getTime()) || (maxDate && clearedDate.getTime() > 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;
- 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);
- 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();
- },
- /**
- * Event executed when the calendar widget is rendered.
- * @deprecated Event handlers for this event should be susbcribed to renderEvent.
- */
- onRender : function() { },
- /**
- * 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(); },
- /**
- * 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<rArray.length;i++) {
- rArray[i] = parseInt(rArray[i], 10);
- }
-
- return rArray;
- },
-
- /**
- * Converts a multi or single-date string to an array of date field arrays
- * @private
- * @param {String} sDates Date string with one or more comma-delimited dates. Valid formats are mm/dd, mm/dd/yyyy, mm/dd/yyyy-mm/dd/yyyy
- * @return An array of date field arrays
- * @type Array[](Number[])
- */
- _parseDates : function(sDates) {
- var aReturn = [],
- aDates = sDates.split(this.Locale.DATE_DELIMITER);
-
- for (var d=0;d<aDates.length;++d) {
- var sDate = aDates[d];
-
- if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
- // This is a range
- var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER),
- dateStart = this._parseDate(aRange[0]),
- dateEnd = this._parseDate(aRange[1]),
- fullRange = this._parseRange(dateStart, dateEnd);
- aReturn = aReturn.concat(fullRange);
- } else {
- // This is not a range
- var aDate = this._parseDate(sDate);
- aReturn.push(aDate);
- }
- }
- return aReturn;
- },
-
- /**
- * Converts a date range to the full list of included dates
- * @private
- * @param {Number[]} startDate Date field array representing the first date in the range
- * @param {Number[]} endDate Date field array representing the last date in the range
- * @return An array of date field arrays
- * @type Array[](Number[])
- */
- _parseRange : function(startDate, endDate) {
- var dCurrent = DateMath.add(DateMath.getDate(startDate[0],startDate[1]-1,startDate[2]),DateMath.DAY,1),
- dEnd = DateMath.getDate(endDate[0], endDate[1]-1, endDate[2]),
- results = [];
- results.push(startDate);
- while (dCurrent.getTime() <= dEnd.getTime()) {
- results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
- dCurrent = DateMath.add(dCurrent,DateMath.DAY,1);
- }
- return results;
- },
-
- // END DATE PARSE METHODS
-
- // BEGIN RENDERER METHODS
-
- /**
- * Resets the render stack of the current calendar to its original pre-render value.
- */
- resetRenderers : function() {
- this.renderStack = this._renderStack.concat();
- },
-
- /**
- * Removes all custom renderers added to the Calendar through the addRenderer, addMonthRenderer and
- * addWeekdayRenderer methods. Calendar's render method needs to be called after removing renderers
- * to re-render the Calendar without custom renderers applied.
- */
- removeRenderers : function() {
- this._renderStack = [];
- this.renderStack = [];
- },
- /**
- * Clears the inner HTML, CSS class and style information from the specified cell.
- * @method clearElement
- * @param {HTMLTableCellElement} cell The cell to clear
- */
- clearElement : function(cell) {
- cell.innerHTML = " ";
- cell.className="";
- },
-
- /**
- * 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.
- */
- addRenderer : function(sDates, fnRender) {
- var aDates = this._parseDates(sDates);
- for (var i=0;i<aDates.length;++i) {
- var aDate = aDates[i];
-
- if (aDate.length == 2) { // this is either a range or a month/day combo
- if (aDate[0] instanceof Array) { // this is a range
- this._addRenderer(Calendar.RANGE,aDate,fnRender);
- } else { // this is a month/day combo
- this._addRenderer(Calendar.MONTH_DAY,aDate,fnRender);
- }
- } else if (aDate.length == 3) {
- this._addRenderer(Calendar.DATE,aDate,fnRender);
- }
- }
- },
-
- /**
- * The private method used for adding cell renderers to the local render stack.
- * This method is called by other methods that set the renderer type prior to the method call.
- * @method _addRenderer
- * @private
- * @param {String} type The type string that indicates the type of date renderer being added.
- * Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
- * YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
- * @param {Array} aDates An array of dates used to construct the renderer. The format varies based
- * on the renderer type
- * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
- */
- _addRenderer : function(type, aDates, fnRender) {
- var add = [type,aDates,fnRender];
- this.renderStack.unshift(add);
- this._renderStack = this.renderStack.concat();
- },
- /**
- * Adds a month to the render stack. The function reference passed to this method will be executed
- * when a date cell matches the month passed to this method.
- * @method addMonthRenderer
- * @param {Number} month The month (1-12) to associate with this renderer
- * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
- */
- addMonthRenderer : function(month, fnRender) {
- this._addRenderer(Calendar.MONTH,[month],fnRender);
- },
- /**
- * 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<this.cells.length;++c) {
- Dom.removeClass(this.cells[c],style);
- }
- },
-
- // END CSS METHODS
-
- // BEGIN GETTER/SETTER METHODS
- /**
- * Sets the calendar's month explicitly
- * @method setMonth
- * @param {Number} month The numeric month, from 0 (January) to 11 (December)
- */
- setMonth : function(month) {
- var cfgPageDate = DEF_CFG.PAGEDATE.key,
- current = this.cfg.getProperty(cfgPageDate);
- current.setMonth(parseInt(month, 10));
- this.cfg.setProperty(cfgPageDate, current);
- },
- /**
- * Sets the calendar's year explicitly.
- * @method setYear
- * @param {Number} year The numeric 4-digit year
- */
- setYear : function(year) {
- var cfgPageDate = DEF_CFG.PAGEDATE.key,
- current = this.cfg.getProperty(cfgPageDate);
- current.setFullYear(parseInt(year, 10));
- this.cfg.setProperty(cfgPageDate, current);
- },
- /**
- * Gets the list of currently selected dates from the calendar.
- * @method getSelectedDates
- * @return {Date[]} An array of currently selected JavaScript Date objects.
- */
- getSelectedDates : function() {
- var returnDates = [],
- selected = this.cfg.getProperty(DEF_CFG.SELECTED.key);
- for (var d=0;d<selected.length;++d) {
- var dateArray = selected[d];
- var date = DateMath.getDate(dateArray[0],dateArray[1]-1,dateArray[2]);
- returnDates.push(date);
- }
- returnDates.sort( function(a,b) { return a-b; } );
- return returnDates;
- },
- /// 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();
- }
- },
- /**
- * Shows the Calendar's outer container.
- * @method show
- */
- show : function() {
- if (this.beforeShowEvent.fire()) {
- this.oDomContainer.style.display = "block";
- this.showEvent.fire();
- }
- },
- /**
- * 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;
- },
- /**
- * 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() {
- if (this.beforeDestroyEvent.fire()) {
- var cal = this;
- // 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, "withtitle");
- Dom.removeClass(cal.oDomContainer, cal.Style.CSS_CONTAINER);
- Dom.removeClass(cal.oDomContainer, cal.Style.CSS_SINGLE);
- cal.oDomContainer.innerHTML = "";
- // JS-to-DOM references
- cal.oDomContainer = null;
- cal.cells = null;
- this.destroyEvent.fire();
- }
- }
- };
- YAHOO.widget.Calendar = Calendar;
- /**
- * @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;
- YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
- })();
- (function() {
- var Dom = YAHOO.util.Dom,
- DateMath = YAHOO.widget.DateMath,
- Event = YAHOO.util.Event,
- Lang = YAHOO.lang,
- Calendar = YAHOO.widget.Calendar;
- /**
- * 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:
- * <xmp>
- * <div id="cal1Container_0"></div>
- * <div id="cal1Container_1"></div>
- * </xmp>
- * The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
- *
- * <p>
- * <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
- * 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.:
- * <xmp>
- * var c = new YAHOO.widget.CalendarGroup("calContainer", configOptions);
- * </xmp>
- * or:
- * <xmp>
- * var containerDiv = YAHOO.util.Dom.get("calContainer");
- * var c = new YAHOO.widget.CalendarGroup(containerDiv, configOptions);
- * </xmp>
- * </p>
- * <p>
- * 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".
- * </p>
- *
- * @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.
- */
- function CalendarGroup(id, containerId, config) {
- if (arguments.length > 0) {
- this.init.apply(this, arguments);
- }
- }
- /**
- * The set of default Config property keys and values for the CalendarGroup
- * @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
- * @final
- * @static
- * @private
- * @type Object
- */
- CalendarGroup._DEFAULT_CONFIG = Calendar._DEFAULT_CONFIG;
- CalendarGroup._DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
- var DEF_CFG = CalendarGroup._DEFAULT_CONFIG;
- CalendarGroup.prototype = {
- /**
- * Initializes the calendar group. All subclasses must call this method in order for the
- * group to be initialized properly.
- * @method init
- * @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.
- */
- init : function(id, container, config) {
- // Normalize 2.4.0, pre 2.4.0 args
- var nArgs = this._parseArgs(arguments);
- id = nArgs.id;
- container = nArgs.container;
- config = nArgs.config;
- this.oDomContainer = Dom.get(container);
- if (!this.oDomContainer) { this.logger.log("Container not found in document.", "error"); }
- if (!this.oDomContainer.id) {
- this.oDomContainer.id = Dom.generateId();
- }
- if (!id) {
- id = this.oDomContainer.id + "_t";
- }
- /**
- * The unique id associated with the CalendarGroup
- * @property id
- * @type String
- */
- this.id = id;
- /**
- * The unique id associated with the CalendarGroup container
- * @property containerId
- * @type String
- */
- this.containerId = this.oDomContainer.id;
- this.logger = new YAHOO.widget.LogWriter("CalendarGroup " + this.id);
- this.initEvents();
- this.initStyles();
- /**
- * The collection of Calendar pages contained within the CalendarGroup
- * @property pages
- * @type YAHOO.widget.Calendar[]
- */
- this.pages = [];
- Dom.addClass(this.oDomContainer, CalendarGroup.CSS_CONTAINER);
- Dom.addClass(this.oDomContainer, CalendarGroup.CSS_MULTI_UP);
- /**
- * 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);
- /**
- * The local object which contains the CalendarGroup's options
- * @property Options
- * @type Object
- */
- this.Options = {};
- /**
- * The local object which contains the CalendarGroup's locale settings
- * @property Locale
- * @type Object
- */
- this.Locale = {};
- this.setupConfig();
- if (config) {
- this.cfg.applyConfig(config, true);
- }
- this.cfg.fireQueue();
- // OPERA HACK FOR MISWRAPPED FLOATS
- if (YAHOO.env.ua.opera){
- this.renderEvent.subscribe(this._fixWidth, this, true);
- this.showEvent.subscribe(this._fixWidth, this, true);
- }
- this.logger.log("Initialized " + this.pages.length + "-page CalendarGroup", "info");
- },
- setupConfig : function() {
- var cfg = this.cfg;
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.PAGES.key, { value:DEF_CFG.PAGES.value, validator:cfg.checkNumber, handler:this.configPages } );
- /**
- * The month/year representing the current visible Calendar date (mm/yyyy)
- * @config pagedate
- * @type String | Date
- * @default today's date
- */
- cfg.addProperty(DEF_CFG.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
- /**
- * The date or range of dates representing the current Calendar selection
- *
- * @config selected
- * @type String
- * @default []
- */
- cfg.addProperty(DEF_CFG.SELECTED.key, { value:[], handler:this.configSelected } );
- /**
- * The title to display above the CalendarGroup's month header
- * @config title
- * @type String
- * @default ""
- */
- cfg.addProperty(DEF_CFG.TITLE.key, { value:DEF_CFG.TITLE.value, handler:this.configTitle } );
- /**
- * Whether or not a close button should be displayed for this CalendarGroup
- * @config close
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.CLOSE.key, { value:DEF_CFG.CLOSE.value, handler:this.configClose } );
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.IFRAME.key, { value:DEF_CFG.IFRAME.value, handler:this.configIframe, validator:cfg.checkBoolean } );
-
- /**
- * The minimum selectable date in the current Calendar (mm/dd/yyyy)
- * @config mindate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MINDATE.key, { value:DEF_CFG.MINDATE.value, handler:this.delegateConfig } );
-
- /**
- * The maximum selectable date in the current Calendar (mm/dd/yyyy)
- * @config maxdate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MAXDATE.key, { value:DEF_CFG.MAXDATE.value, handler:this.delegateConfig } );
-
- // Options properties
- /**
- * True if the Calendar should allow multiple selections. False by default.
- * @config MULTI_SELECT
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.MULTI_SELECT.key, { value:DEF_CFG.MULTI_SELECT.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
- /**
- * The weekday the week begins on. Default is 0 (Sunday).
- * @config START_WEEKDAY
- * @type number
- * @default 0
- */
- cfg.addProperty(DEF_CFG.START_WEEKDAY.key, { value:DEF_CFG.START_WEEKDAY.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * True if the Calendar should show weekday labels. True by default.
- * @config SHOW_WEEKDAYS
- * @type Boolean
- * @default true
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEKDAYS.key, { value:DEF_CFG.SHOW_WEEKDAYS.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row headers. False by default.
- * @config SHOW_WEEK_HEADER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_HEADER.key,{ value:DEF_CFG.SHOW_WEEK_HEADER.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row footers. False by default.
- * @config SHOW_WEEK_FOOTER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_FOOTER.key,{ value:DEF_CFG.SHOW_WEEK_FOOTER.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.HIDE_BLANK_WEEKS.key,{ value:DEF_CFG.HIDE_BLANK_WEEKS.value, handler:this.delegateConfig, validator: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
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_LEFT.key, { value:DEF_CFG.NAV_ARROW_LEFT.value, handler:this.delegateConfig } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_RIGHT.key, { value:DEF_CFG.NAV_ARROW_RIGHT.value, handler:this.delegateConfig } );
-
- // 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"]
- */
- cfg.addProperty(DEF_CFG.MONTHS_SHORT.key, { value:DEF_CFG.MONTHS_SHORT.value, handler:this.delegateConfig } );
-
- /**
- * 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"
- */
- cfg.addProperty(DEF_CFG.MONTHS_LONG.key, { value:DEF_CFG.MONTHS_LONG.value, handler:this.delegateConfig } );
-
- /**
- * The 1-character weekday labels for the current locale.
- * @config WEEKDAYS_1CHAR
- * @type String[]
- * @default ["S", "M", "T", "W", "T", "F", "S"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_1CHAR.key, { value:DEF_CFG.WEEKDAYS_1CHAR.value, handler:this.delegateConfig } );
-
- /**
- * The short weekday labels for the current locale.
- * @config WEEKDAYS_SHORT
- * @type String[]
- * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_SHORT.key, { value:DEF_CFG.WEEKDAYS_SHORT.value, handler:this.delegateConfig } );
-
- /**
- * The medium weekday labels for the current locale.
- * @config WEEKDAYS_MEDIUM
- * @type String[]
- * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_MEDIUM.key, { value:DEF_CFG.WEEKDAYS_MEDIUM.value, handler:this.delegateConfig } );
-
- /**
- * The long weekday labels for the current locale.
- * @config WEEKDAYS_LONG
- * @type String[]
- * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_LONG.key, { value:DEF_CFG.WEEKDAYS_LONG.value, handler:this.delegateConfig } );
-
- /**
- * 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"
- */
- cfg.addProperty(DEF_CFG.LOCALE_MONTHS.key, { value:DEF_CFG.LOCALE_MONTHS.value, handler:this.delegateConfig } );
-
- /**
- * 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"
- */
- cfg.addProperty(DEF_CFG.LOCALE_WEEKDAYS.key, { value:DEF_CFG.LOCALE_WEEKDAYS.value, handler:this.delegateConfig } );
-
- /**
- * The value used to delimit individual dates in a date string passed to various Calendar functions.
- * @config DATE_DELIMITER
- * @type String
- * @default ","
- */
- cfg.addProperty(DEF_CFG.DATE_DELIMITER.key, { value:DEF_CFG.DATE_DELIMITER.value, handler:this.delegateConfig } );
-
- /**
- * The value used to delimit date fields in a date string passed to various Calendar functions.
- * @config DATE_FIELD_DELIMITER
- * @type String
- * @default "/"
- */
- cfg.addProperty(DEF_CFG.DATE_FIELD_DELIMITER.key,{ value:DEF_CFG.DATE_FIELD_DELIMITER.value, handler:this.delegateConfig } );
-
- /**
- * The value used to delimit date ranges in a date string passed to various Calendar functions.
- * @config DATE_RANGE_DELIMITER
- * @type String
- * @default "-"
- */
- cfg.addProperty(DEF_CFG.DATE_RANGE_DELIMITER.key,{ value:DEF_CFG.DATE_RANGE_DELIMITER.value, handler:this.delegateConfig } );
-
- /**
- * The position of the month in a month/year date string
- * @config MY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MY_MONTH_POSITION.key, { value:DEF_CFG.MY_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/year date string
- * @config MY_YEAR_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MY_YEAR_POSITION.key, { value:DEF_CFG.MY_YEAR_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day date string
- * @config MD_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MD_MONTH_POSITION.key, { value:DEF_CFG.MD_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/year date string
- * @config MD_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MD_DAY_POSITION.key, { value:DEF_CFG.MD_DAY_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day/year date string
- * @config MDY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MDY_MONTH_POSITION.key, { value:DEF_CFG.MDY_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/day/year date string
- * @config MDY_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MDY_DAY_POSITION.key, { value:DEF_CFG.MDY_DAY_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/day/year date string
- * @config MDY_YEAR_POSITION
- * @type Number
- * @default 3
- */
- cfg.addProperty(DEF_CFG.MDY_YEAR_POSITION.key, { value:DEF_CFG.MDY_YEAR_POSITION.value, handler:this.delegateConfig, validator: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
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_POSITION.key, { value:DEF_CFG.MY_LABEL_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
-
- /**
- * 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
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_POSITION.key, { value:DEF_CFG.MY_LABEL_YEAR_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
- /**
- * The suffix used after the month when rendering the Calendar header
- * @config MY_LABEL_MONTH_SUFFIX
- * @type String
- * @default " "
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_SUFFIX.key, { value:DEF_CFG.MY_LABEL_MONTH_SUFFIX.value, handler:this.delegateConfig } );
-
- /**
- * The suffix used after the year when rendering the Calendar header
- * @config MY_LABEL_YEAR_SUFFIX
- * @type String
- * @default ""
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_SUFFIX.key, { value:DEF_CFG.MY_LABEL_YEAR_SUFFIX.value, handler:this.delegateConfig } );
- /**
- * Configuration for the Month Year Navigation UI. By default it is disabled
- * @config NAV
- * @type Object
- * @default null
- */
- cfg.addProperty(DEF_CFG.NAV.key, { value:DEF_CFG.NAV.value, handler:this.configNavigator } );
- /**
- * The map of UI strings which the CalendarGroup UI uses.
- *
- * @config strings
- * @type {Object}
- * @default An object with the properties shown below:
- * <dl>
- * <dt>previousMonth</dt><dd><em>String</em> : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".</dd>
- * <dt>nextMonth</dt><dd><em>String</em> : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".</dd>
- * <dt>close</dt><dd><em>String</em> : The string to use for the close button label. Defaults to "Close".</dd>
- * </dl>
- */
- 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
- });
- },
- /**
- * Initializes CalendarGroup's built-in CustomEvents
- * @method initEvents
- */
- initEvents : function() {
- var me = this,
- strEvent = "Event",
- CE = YAHOO.util.CustomEvent;
- /**
- * 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<me.pages.length;++p) {
- var cal = me.pages[p];
- cal[this.type + strEvent].subscribe(fn, obj, bOverride);
- }
- };
- /**
- * Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
- * @method unsub
- * @private
- * @param {Function} fn The function to subscribe to this CustomEvent
- * @param {Object} obj The CustomEvent's scope object
- */
- var unsub = function(fn, obj) {
- for (var p=0;p<me.pages.length;++p) {
- var cal = me.pages[p];
- cal[this.type + strEvent].unsubscribe(fn, obj);
- }
- };
- var defEvents = Calendar._EVENT_TYPES;
- /**
- * Fired before a date selection is made
- * @event beforeSelectEvent
- */
- me.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
- me.beforeSelectEvent.subscribe = sub; me.beforeSelectEvent.unsubscribe = unsub;
- /**
- * Fired when a date selection is made
- * @event selectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- me.selectEvent = new CE(defEvents.SELECT);
- me.selectEvent.subscribe = sub; me.selectEvent.unsubscribe = unsub;
- /**
- * Fired before a date or set of dates is deselected
- * @event beforeDeselectEvent
- */
- me.beforeDeselectEvent = new CE(defEvents.BEFORE_DESELECT);
- me.beforeDeselectEvent.subscribe = sub; me.beforeDeselectEvent.unsubscribe = unsub;
- /**
- * Fired when a date or set of dates has been deselected
- * @event deselectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- me.deselectEvent = new CE(defEvents.DESELECT);
- me.deselectEvent.subscribe = sub; me.deselectEvent.unsubscribe = unsub;
-
- /**
- * Fired when the Calendar page is changed
- * @event changePageEvent
- */
- me.changePageEvent = new CE(defEvents.CHANGE_PAGE);
- me.changePageEvent.subscribe = sub; me.changePageEvent.unsubscribe = unsub;
- /**
- * Fired before the Calendar is rendered
- * @event beforeRenderEvent
- */
- me.beforeRenderEvent = new CE(defEvents.BEFORE_RENDER);
- me.beforeRenderEvent.subscribe = sub; me.beforeRenderEvent.unsubscribe = unsub;
-
- /**
- * Fired when the Calendar is rendered
- * @event renderEvent
- */
- me.renderEvent = new CE(defEvents.RENDER);
- me.renderEvent.subscribe = sub; me.renderEvent.unsubscribe = unsub;
-
- /**
- * Fired when the Calendar is reset
- * @event resetEvent
- */
- me.resetEvent = new CE(defEvents.RESET);
- me.resetEvent.subscribe = sub; me.resetEvent.unsubscribe = unsub;
-
- /**
- * Fired when the Calendar is cleared
- * @event clearEvent
- */
- me.clearEvent = new CE(defEvents.CLEAR);
- me.clearEvent.subscribe = sub; me.clearEvent.unsubscribe = unsub;
- /**
- * Fired just before the CalendarGroup is to be shown
- * @event beforeShowEvent
- */
- me.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
-
- /**
- * Fired after the CalendarGroup is shown
- * @event showEvent
- */
- me.showEvent = new CE(defEvents.SHOW);
-
- /**
- * Fired just before the CalendarGroup is to be hidden
- * @event beforeHideEvent
- */
- me.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
-
- /**
- * Fired after the CalendarGroup is hidden
- * @event hideEvent
- */
- me.hideEvent = new CE(defEvents.HIDE);
- /**
- * Fired just before the CalendarNavigator is to be shown
- * @event beforeShowNavEvent
- */
- me.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
-
- /**
- * Fired after the CalendarNavigator is shown
- * @event showNavEvent
- */
- me.showNavEvent = new CE(defEvents.SHOW_NAV);
-
- /**
- * Fired just before the CalendarNavigator is to be hidden
- * @event beforeHideNavEvent
- */
- me.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
- /**
- * Fired after the CalendarNavigator is hidden
- * @event hideNavEvent
- */
- me.hideNavEvent = new CE(defEvents.HIDE_NAV);
- /**
- * Fired just before the CalendarNavigator is to be rendered
- * @event beforeRenderNavEvent
- */
- me.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
- /**
- * Fired after the CalendarNavigator is rendered
- * @event renderNavEvent
- */
- me.renderNavEvent = new CE(defEvents.RENDER_NAV);
- /**
- * Fired just before the CalendarGroup is to be destroyed
- * @event beforeDestroyEvent
- */
- me.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
- /**
- * Fired after the CalendarGroup is destroyed. This event should be used
- * for notification only. When this event is fired, important CalendarGroup instance
- * properties, dom references and event listeners have already been
- * removed/dereferenced, and hence the CalendarGroup instance is not in a usable
- * state.
- *
- * @event destroyEvent
- */
- me.destroyEvent = new CE(defEvents.DESTROY);
- },
-
- /**
- * 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.
- */
- configPages : function(type, args, obj) {
- var pageCount = args[0],
- cfgPageDate = DEF_CFG.PAGEDATE.key,
- sep = "_",
- caldate,
- firstPageDate = null,
- groupCalClass = "groupcal",
- firstClass = "first-of-type",
- lastClass = "last-of-type";
- for (var p=0;p<pageCount;++p) {
- var calId = this.id + sep + p,
- calContainerId = this.containerId + sep + p,
- childConfig = this.cfg.getConfig();
- childConfig.close = false;
- childConfig.title = false;
- childConfig.navigator = null;
- if (p > 0) {
- caldate = new Date(firstPageDate);
- this._setMonthOnDate(caldate, caldate.getMonth() + p);
- childConfig.pageDate = caldate;
- }
- var cal = this.constructChild(calId, calContainerId, childConfig);
- Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
- Dom.addClass(cal.oDomContainer, groupCalClass);
- 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;
- var cfgPageDate = DEF_CFG.PAGEDATE.key;
-
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- if (p === 0) {
- firstPageDate = cal._parsePageDate(val);
- cal.cfg.setProperty(cfgPageDate, firstPageDate);
- } else {
- var pageDate = new Date(firstPageDate);
- this._setMonthOnDate(pageDate, pageDate.getMonth() + p);
- cal.cfg.setProperty(cfgPageDate, pageDate);
- }
- }
- },
-
- /**
- * 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.
- */
- configSelected : function(type, args, obj) {
- var cfgSelected = DEF_CFG.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);
- },
-
- /**
- * 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.
- */
- delegateConfig : function(type, args, obj) {
- var val = args[0];
- var cal;
-
- for (var p=0;p<this.pages.length;p++) {
- cal = this.pages[p];
- cal.cfg.setProperty(type, val);
- }
- },
- /**
- * 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
- */
- setChildFunction : function(fnName, fn) {
- var pageCount = this.cfg.getProperty(DEF_CFG.PAGES.key);
-
- for (var p=0;p<pageCount;++p) {
- this.pages[p][fnName] = fn;
- }
- },
- /**
- * 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
- */
- callChildFunction : function(fnName, args) {
- var pageCount = this.cfg.getProperty(DEF_CFG.PAGES.key);
- for (var p=0;p<pageCount;++p) {
- var page = this.pages[p];
- if (page[fnName]) {
- var fn = page[fnName];
- fn.call(page, args);
- }
- }
- },
- /**
- * Constructs a child calendar. This method can be overridden if a subclassed version of the default
- * calendar is to be used.
- * @method constructChild
- * @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
- * @return {YAHOO.widget.Calendar} The YAHOO.widget.Calendar instance that is constructed
- */
- constructChild : function(id,containerId,config) {
- var container = document.getElementById(containerId);
- if (! container) {
- container = document.createElement("div");
- container.id = containerId;
- this.oDomContainer.appendChild(container);
- }
- return new Calendar(id,containerId,config);
- },
-
- /**
- * Sets the calendar group's month explicitly. This month will be set into the first
- * page of the multi-page calendar, and all other months will be iterated appropriately.
- * @method setMonth
- * @param {Number} month The numeric month, from 0 (January) to 11 (December)
- */
- setMonth : function(month) {
- month = parseInt(month, 10);
- var currYear;
- var cfgPageDate = DEF_CFG.PAGEDATE.key;
- for (var p=0; p<this.pages.length; ++p) {
- var cal = this.pages[p];
- var pageDate = cal.cfg.getProperty(cfgPageDate);
- if (p === 0) {
- currYear = pageDate.getFullYear();
- } else {
- pageDate.setFullYear(currYear);
- }
- this._setMonthOnDate(pageDate, month+p);
- cal.cfg.setProperty(cfgPageDate, pageDate);
- }
- },
- /**
- * Sets the calendar group's year explicitly. This year will be set into the first
- * page of the multi-page calendar, and all other months will be iterated appropriately.
- * @method setYear
- * @param {Number} year The numeric 4-digit year
- */
- setYear : function(year) {
-
- var cfgPageDate = DEF_CFG.PAGEDATE.key;
-
- year = parseInt(year, 10);
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- var pageDate = cal.cfg.getProperty(cfgPageDate);
-
- if ((pageDate.getMonth()+1) == 1 && p>0) {
- year+=1;
- }
- cal.setYear(year);
- }
- },
- /**
- * Calls the render function of all child calendars within the group.
- * @method render
- */
- render : function() {
- this.renderHeader();
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.render();
- }
- this.renderFooter();
- },
- /**
- * 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.
- * @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) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.select(date);
- }
- return this.getSelectedDates();
- },
- /**
- * Selects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
- * The value of the MULTI_SELECT Configuration attribute will determine the set of dates which get selected.
- * <ul>
- * <li>If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.</li>
- * <li>If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.</li>
- * </ul>
- * @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<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.selectCell(cellIndex);
- }
- 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.
- * @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) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.deselect(date);
- }
- 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() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.deselectAll();
- }
- return this.getSelectedDates();
- },
- /**
- * Deselects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
- * deselectCell will deselect the cell at the specified index on each displayed Calendar page.
- *
- * @method deselectCell
- * @param {Number} cellIndex The index of the cell to deselect.
- * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
- */
- deselectCell : function(cellIndex) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.deselectCell(cellIndex);
- }
- return this.getSelectedDates();
- },
- /**
- * Resets the calendar widget to the originally selected month and year, and
- * sets the calendar to the initial selection(s).
- * @method reset
- */
- reset : function() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.reset();
- }
- },
- /**
- * Clears the selected dates in the current calendar widget and sets the calendar
- * to the current month and year.
- * @method clear
- */
- clear : function() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.clear();
- }
- this.cfg.setProperty(DEF_CFG.SELECTED.key, []);
- this.cfg.setProperty(DEF_CFG.PAGEDATE.key, new Date(this.pages[0].today.getTime()));
- this.render();
- },
- /**
- * Navigates to the next month page in the calendar widget.
- * @method nextMonth
- */
- nextMonth : function() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.nextMonth();
- }
- },
-
- /**
- * Navigates to the previous month page in the calendar widget.
- * @method previousMonth
- */
- previousMonth : function() {
- for (var p=this.pages.length-1;p>=0;--p) {
- var cal = this.pages[p];
- cal.previousMonth();
- }
- },
-
- /**
- * Navigates to the next year in the currently selected month in the calendar widget.
- * @method nextYear
- */
- nextYear : function() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.nextYear();
- }
- },
- /**
- * Navigates to the previous year in the currently selected month in the calendar widget.
- * @method previousYear
- */
- previousYear : function() {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.previousYear();
- }
- },
- /**
- * Gets the list of currently selected dates from the calendar.
- * @return An array of currently selected JavaScript Date objects.
- * @type Date[]
- */
- getSelectedDates : function() {
- var returnDates = [];
- var selected = this.cfg.getProperty(DEF_CFG.SELECTED.key);
- for (var d=0;d<selected.length;++d) {
- var dateArray = selected[d];
- var date = DateMath.getDate(dateArray[0],dateArray[1]-1,dateArray[2]);
- returnDates.push(date);
- }
- returnDates.sort( function(a,b) { return a-b; } );
- return returnDates;
- },
- /**
- * 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.
- */
- addRenderer : function(sDates, fnRender) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.addRenderer(sDates, fnRender);
- }
- },
- /**
- * Adds a month to the render stack. The function reference passed to this method will be executed
- * when a date cell matches the month passed to this method.
- * @method addMonthRenderer
- * @param {Number} month The month (1-12) to associate with this renderer
- * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
- */
- addMonthRenderer : function(month, fnRender) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.addMonthRenderer(month, fnRender);
- }
- },
- /**
- * 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 (1-7) to associate with this renderer. 1=Sunday, 2=Monday etc.
- * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
- */
- addWeekdayRenderer : function(weekday, fnRender) {
- for (var p=0;p<this.pages.length;++p) {
- var cal = this.pages[p];
- cal.addWeekdayRenderer(weekday, fnRender);
- }
- },
- /**
- * Removes all custom renderers added to the CalendarGroup through the addRenderer, addMonthRenderer and
- * addWeekRenderer methods. CalendarGroup's render method needs to be called to after removing renderers
- * to see the changes applied.
- *
- * @method removeRenderers
- */
- removeRenderers : function() {
- this.callChildFunction("removeRenderers");
- },
- /**
- * Renders the header for the CalendarGroup.
- * @method renderHeader
- */
- renderHeader : function() {
- // EMPTY DEFAULT IMPL
- },
- /**
- * Renders a footer for the 2-up calendar container. By default, this method is
- * unimplemented.
- * @method renderFooter
- */
- renderFooter : function() {
- // EMPTY DEFAULT IMPL
- },
- /**
- * 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) {
- this.callChildFunction("addMonths", count);
- },
-
- /**
- * 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) {
- this.callChildFunction("subtractMonths", count);
- },
- /**
- * 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) {
- this.callChildFunction("addYears", count);
- },
- /**
- * 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) {
- this.callChildFunction("subtractYears", count);
- },
- /**
- * Returns the Calendar page instance which has a pagedate (month/year) matching the given date.
- * Returns null if no match is found.
- *
- * @method getCalendarPage
- * @param {Date} date The JavaScript Date object for which a Calendar page is to be found.
- * @return {Calendar} The Calendar page instance representing the month to which the date
- * belongs.
- */
- getCalendarPage : function(date) {
- var cal = null;
- if (date) {
- var y = date.getFullYear(),
- m = date.getMonth();
- var pages = this.pages;
- for (var i = 0; i < pages.length; ++i) {
- var pageDate = pages[i].cfg.getProperty("pagedate");
- if (pageDate.getFullYear() === y && pageDate.getMonth() === m) {
- cal = pages[i];
- break;
- }
- }
- }
- return cal;
- },
- /**
- * Sets the month on a Date object, taking into account year rollover if the month is less than 0 or greater than 11.
- * The Date object passed in is modified. It should be cloned before passing it into this method if the original value needs to be maintained
- * @method _setMonthOnDate
- * @private
- * @param {Date} date The Date object on which to set the month index
- * @param {Number} iMonth The month index to set
- */
- _setMonthOnDate : function(date, iMonth) {
- // Bug in Safari 1.3, 2.0 (WebKit build < 420), Date.setMonth does not work consistently if iMonth is not 0-11
- if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420 && (iMonth < 0 || iMonth > 11)) {
- var newDate = DateMath.add(date, DateMath.MONTH, iMonth-date.getMonth());
- date.setTime(newDate.getTime());
- } else {
- date.setMonth(iMonth);
- }
- },
-
- /**
- * 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<this.pages.length;++p) {
- var cal = this.pages[p];
- w += cal.oDomContainer.offsetWidth;
- }
- if (w > 0) {
- this.oDomContainer.style.width = w + "px";
- }
- },
-
- /**
- * Returns a string representation of the object.
- * @method toString
- * @return {String} A string representation of the CalendarGroup object.
- */
- toString : function() {
- return "CalendarGroup " + this.id;
- },
- /**
- * 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;
-
- // 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 <a href="YAHOO.widget.Calendar.html#Style.CSS_CLOSE">Style.CSS_CLOSE</a> 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;
- /**
- * 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"
- };
- /**
- * 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.
- * <dl>
- * <dt>strings</dt>
- * <dd><em>Object</em> : An object with the properties shown below, defining the string labels to use in the Navigator's UI
- * <dl>
- * <dt>month</dt><dd><em>String</em> : The string to use for the month label. Defaults to "Month".</dd>
- * <dt>year</dt><dd><em>String</em> : The string to use for the year label. Defaults to "Year".</dd>
- * <dt>submit</dt><dd><em>String</em> : The string to use for the submit button label. Defaults to "Okay".</dd>
- * <dt>cancel</dt><dd><em>String</em> : The string to use for the cancel button label. Defaults to "Cancel".</dd>
- * <dt>invalidYear</dt><dd><em>String</em> : The string to use for invalid year values. Defaults to "Year needs to be a number".</dd>
- * </dl>
- * </dd>
- * <dt>monthFormat</dt><dd><em>String</em> : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG</dd>
- * <dt>initialFocus</dt><dd><em>String</em> : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"</dd>
- * </dl>
- * @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 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 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 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 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 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 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 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 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;
- /**
- * 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;
- /**
- * 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 unique ID for this CalendarNavigator instance
- * @property id
- * @type String
- */
- id : null,
- /**
- * The Calendar/CalendarGroup instance to which the navigator belongs
- * @property cal
- * @type {Calendar|CalendarGroup}
- */
- cal : null,
- /**
- * Reference to the HTMLElement used to render the navigator's bounding box
- * @property navEl
- * @type HTMLElement
- */
- navEl : null,
- /**
- * Reference to the HTMLElement used to render the navigator's mask
- * @property maskEl
- * @type HTMLElement
- */
- maskEl : null,
- /**
- * Reference to the HTMLElement used to input the year
- * @property yearEl
- * @type HTMLElement
- */
- yearEl : null,
- /**
- * 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,
-
- /**
- * 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 document containing the Calendar/Calendar group instance
- * @protected
- * @property _doc
- * @type HTMLDocument
- */
- _doc : null,
- /**
- * Internal state property for the current year displayed in the navigator
- * @protected
- * @property _year
- * @type Number
- */
- _year: null,
-
- /**
- * Internal state property for the current month index displayed in the navigator
- * @protected
- * @property _month
- * @type Number
- */
- _month: 0,
- /**
- * Private internal state property which indicates whether or not the
- * Navigator has been rendered.
- * @private
- * @property __rendered
- * @type Boolean
- */
- __rendered: false,
- /**
- * 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")));
- },
- /**
- * Displays the navigator and mask, updating the input controls to reflect the
- * currently set month and year. The show method will invoke the render method
- * if the navigator has not been renderered already, allowing for lazy rendering
- * of the control.
- *
- * The show method will fire the Calendar/CalendarGroup's beforeShowNav and showNav events
- *
- * @method show
- */
- show : function() {
- var CLASSES = YAHOO.widget.CalendarNavigator.CLASSES;
- if (this.cal.beforeShowNavEvent.fire()) {
- if (!this.__rendered) {
- this.render();
- }
- this.clearErrors();
- this._updateMonthUI();
- this._updateYearUI();
- this._show(this.navEl, true);
- this.setInitialFocus();
- this.showMask();
- YAHOO.util.Dom.addClass(this.cal.oDomContainer, CLASSES.NAV_VISIBLE);
- this.cal.showNavEvent.fire();
- }
- },
- /**
- * Hides the navigator and mask
- *
- * The show method will fire the Calendar/CalendarGroup's beforeHideNav event and hideNav events
- * @method hide
- */
- hide : function() {
- var CLASSES = YAHOO.widget.CalendarNavigator.CLASSES;
- if (this.cal.beforeHideNavEvent.fire()) {
- this._show(this.navEl, false);
- this.hideMask();
- YAHOO.util.Dom.removeClass(this.cal.oDomContainer, CLASSES.NAV_VISIBLE);
- this.cal.hideNavEvent.fire();
- }
- },
-
- /**
- * Displays the navigator's mask element
- *
- * @method showMask
- */
- showMask : function() {
- this._show(this.maskEl, true);
- if (this.__isIEQuirks) {
- this._syncMask();
- }
- },
- /**
- * Hides the navigator's mask element
- *
- * @method hideMask
- */
- hideMask : function() {
- this._show(this.maskEl, false);
- },
- /**
- * Returns the current month set on the navigator
- *
- * Note: This may not be the month set in the UI, if
- * the UI contains an invalid value.
- *
- * @method getMonth
- * @return {Number} The Navigator's current month index
- */
- getMonth: function() {
- return this._month;
- },
- /**
- * Returns the current year set on the navigator
- *
- * Note: This may not be the year set in the UI, if
- * the UI contains an invalid value.
- *
- * @method getYear
- * @return {Number} The Navigator's current year value
- */
- getYear: function() {
- return this._year;
- },
- /**
- * Sets the current month on the Navigator, and updates the UI
- *
- * @method setMonth
- * @param {Number} nMonth The month index, from 0 (Jan) through 11 (Dec).
- */
- setMonth : function(nMonth) {
- if (nMonth >= 0 && nMonth < 12) {
- this._month = nMonth;
- }
- this._updateMonthUI();
- },
- /**
- * 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();
- },
- /**
- * 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();
- },
- /**
- * 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;
- var htmlBuf = this.renderNavContents([]);
- d.innerHTML = htmlBuf.join('');
- this.cal.oDomContainer.appendChild(d);
- this.navEl = d;
- 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);
- if (YAHOO.env.ua.gecko && this.yearEl && this.yearEl.type == "text") {
- // Avoid XUL error on focus, select [ https://bugzilla.mozilla.org/show_bug.cgi?id=236791,
- // supposedly fixed in 1.8.1, but there are reports of it still being around for methods other than blur ]
- this.yearEl.setAttribute("autocomplete", "off");
- }
- this._setFirstLastElements();
- },
- /**
- * Creates the Mask HTMLElement and appends it to the Calendar/CalendarGroups
- * container.
- *
- * @method createMask
- */
- createMask : function() {
- var C = YAHOO.widget.CalendarNavigator.CLASSES;
- var d = this._doc.createElement("div");
- d.className = C.MASK;
- this.cal.oDomContainer.appendChild(d);
- this.maskEl = d;
- },
- /**
- * Used to set the width/height of the mask in pixels to match the Calendar Container.
- * Currently only used for IE6 or IE in quirks mode. The other A-Grade browser are handled using CSS (width/height 100%).
- * <p>
- * The method is also registered as an HTMLElement resize listener on the Calendars container element.
- * </p>
- * @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");
- }
- },
- /**
- * 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
- h[h.length] = '<div class="' + C.MONTH + '">';
- this.renderMonth(h);
- h[h.length] = '</div>';
- h[h.length] = '<div class="' + C.YEAR + '">';
- this.renderYear(h);
- h[h.length] = '</div>';
- h[h.length] = '<div class="' + C.BUTTONS + '">';
- this.renderButtons(h);
- h[h.length] = '</div>';
- h[h.length] = '<div class="' + C.ERROR + '" id="' + this.id + NAV.ERROR_SUFFIX + '"></div>';
- return h;
- },
- /**
- * Renders the month label and control for the navigator
- *
- * @method renderNavContents
- * @param {Array} html The HTML buffer to append the HTML to.
- * @return {Array} A reference to the buffer passed in.
- */
- renderMonth : function(html) {
- var NAV = YAHOO.widget.CalendarNavigator,
- C = NAV.CLASSES;
- var id = this.id + NAV.MONTH_SUFFIX,
- mf = this.__getCfg("monthFormat"),
- months = this.cal.cfg.getProperty((mf == YAHOO.widget.Calendar.SHORT) ? "MONTHS_SHORT" : "MONTHS_LONG"),
- h = html;
- if (months && months.length > 0) {
- h[h.length] = '<label for="' + id + '">';
- h[h.length] = this.__getCfg("month", true);
- h[h.length] = '</label>';
- h[h.length] = '<select name="' + id + '" id="' + id + '" class="' + C.MONTH_CTRL + '">';
- for (var i = 0; i < months.length; i++) {
- h[h.length] = '<option value="' + i + '">';
- h[h.length] = months[i];
- h[h.length] = '</option>';
- }
- h[h.length] = '</select>';
- }
- return h;
- },
- /**
- * 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;
- h[h.length] = '<label for="' + id + '">';
- h[h.length] = this.__getCfg("year", true);
- h[h.length] = '</label>';
- h[h.length] = '<input type="text" name="' + id + '" id="' + id + '" class="' + C.YEAR_CTRL + '" maxlength="' + size + '"/>';
- return h;
- },
- /**
- * Renders the submit/cancel buttons for the navigator
- *
- * @method renderButton
- * @return {String} The HTML created for the Button UI
- */
- renderButtons : function(html) {
- var C = YAHOO.widget.CalendarNavigator.CLASSES;
- var h = html;
- h[h.length] = '<span class="' + C.BUTTON + ' ' + C.DEFAULT + '">';
- h[h.length] = '<button type="button" id="' + this.id + '_submit' + '">';
- h[h.length] = this.__getCfg("submit", true);
- h[h.length] = '</button>';
- h[h.length] = '</span>';
- h[h.length] = '<span class="' + C.BUTTON +'">';
- h[h.length] = '<button type="button" id="' + this.id + '_cancel' + '">';
- h[h.length] = this.__getCfg("cancel", true);
- h[h.length] = '</button>';
- h[h.length] = '</span>';
- return h;
- },
- /**
- * Attaches DOM event listeners to the rendered elements
- * <p>
- * The method will call applyKeyListeners, to setup keyboard specific
- * listeners
- * </p>
- * @method applyListeners
- */
- applyListeners : function() {
- var E = YAHOO.util.Event;
- function yearUpdateHandler() {
- if (this.validate()) {
- this.setYear(this._getYearFromUI());
- }
- }
- function monthUpdateHandler() {
- this.setMonth(this._getMonthFromUI());
- }
- E.on(this.submitEl, "click", this.submit, this, true);
- E.on(this.cancelEl, "click", this.cancel, this, true);
- E.on(this.yearEl, "blur", yearUpdateHandler, this, true);
- E.on(this.monthEl, "change", monthUpdateHandler, this, true);
- if (this.__isIEQuirks) {
- YAHOO.util.Event.on(this.cal.oDomContainer, "resize", this._syncMask, this, true);
- }
- this.applyKeyListeners();
- },
- /**
- * Removes/purges DOM event listeners from the rendered elements
- *
- * @method purgeListeners
- */
- purgeListeners : function() {
- var E = YAHOO.util.Event;
- E.removeListener(this.submitEl, "click", this.submit);
- E.removeListener(this.cancelEl, "click", this.cancel);
- E.removeListener(this.yearEl, "blur");
- E.removeListener(this.monthEl, "change");
- if (this.__isIEQuirks) {
- E.removeListener(this.cal.oDomContainer, "resize", this._syncMask);
- }
- this.purgeKeyListeners();
- },
- /**
- * Attaches DOM listeners for keyboard support.
- * Tab/Shift-Tab looping, Enter Key Submit on Year element,
- * Up/Down/PgUp/PgDown year increment on Year element
- * <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.
- * </p>
- * @method applyKeyListeners
- */
- applyKeyListeners : function() {
- var E = YAHOO.util.Event,
- ua = YAHOO.env.ua;
- // IE/Safari 3.1 doesn't fire keypress for arrow/pg keys (non-char keys)
- var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
- // - IE/Safari 3.1 doesn't fire keypress for non-char keys
- // - Opera doesn't allow us to cancel keydown or keypress for tab, but
- // changes focus successfully on keydown (keypress is too late to change focus - opera's already moved on).
- var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
- // Everyone likes keypress for Enter (char keys) - whoo hoo!
- E.on(this.yearEl, "keypress", this._handleEnterKey, this, true);
- E.on(this.yearEl, arrowEvt, this._handleDirectionKeys, this, true);
- E.on(this.lastCtrl, tabEvt, this._handleTabKey, this, true);
- E.on(this.firstCtrl, tabEvt, this._handleShiftTabKey, this, true);
- },
- /**
- * Removes/purges DOM listeners for keyboard support
- *
- * @method purgeKeyListeners
- */
- purgeKeyListeners : function() {
- var E = YAHOO.util.Event,
- ua = YAHOO.env.ua;
- var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
- var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
- E.removeListener(this.yearEl, "keypress", this._handleEnterKey);
- E.removeListener(this.yearEl, arrowEvt, this._handleDirectionKeys);
- E.removeListener(this.lastCtrl, tabEvt, this._handleTabKey);
- E.removeListener(this.firstCtrl, tabEvt, this._handleShiftTabKey);
- },
- /**
- * Updates the Calendar/CalendarGroup's pagedate with the currently set month and year if valid.
- * <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.
- * </p>
- * @method submit
- */
- submit : function() {
- if (this.validate()) {
- this.hide();
- this.setMonth(this._getMonthFromUI());
- this.setYear(this._getYearFromUI());
- var cal = this.cal;
- // 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);
- }
- }
- },
- /**
- * Updates the Calendar rendered state, based on the state of the CalendarNavigator
- * @method _update
- * @param cal The Calendar instance to update
- * @protected
- */
- _update : function(cal) {
- cal.setYear(this.getYear());
- cal.setMonth(this.getMonth());
- cal.render();
- },
- /**
- * Hides the navigator and mask, without updating the Calendar/CalendarGroup's state
- *
- * @method cancel
- */
- cancel : function() {
- this.hide();
- },
- /**
- * Validates the current state of the UI controls
- *
- * @method validate
- * @return {Boolean} true, if the current UI state contains valid values, false if not
- */
- validate : function() {
- if (this._getYearFromUI() !== null) {
- this.clearErrors();
- return true;
- } else {
- this