2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
10 * Config is a utility used within an Object to allow the implementer to
11 * maintain a list of local configuration properties and listen for changes
12 * to those properties dynamically using CustomEvent. The initial values are
13 * also maintained so that the configuration can be reset at any given point
14 * to its initial state.
15 * @namespace YAHOO.util
18 * @param {Object} owner The owner Object to which this Config Object belongs
20 YAHOO.util.Config = function (owner) {
36 var Lang = YAHOO.lang,
37 CustomEvent = YAHOO.util.CustomEvent,
38 Config = YAHOO.util.Config;
42 * Constant representing the CustomEvent type for the config changed event.
43 * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
48 Config.CONFIG_CHANGED_EVENT = "configChanged";
51 * Constant representing the boolean type string
52 * @property YAHOO.util.Config.BOOLEAN_TYPE
57 Config.BOOLEAN_TYPE = "boolean";
62 * Object reference to the owner of this Config Object
69 * Boolean flag that specifies whether a queue is currently
71 * @property queueInProgress
74 queueInProgress: false,
77 * Maintains the local collection of configuration property objects and
78 * their specified values
86 * Maintains the local collection of configuration property objects as
87 * they were initially applied.
88 * This object is used when resetting a property.
89 * @property initialConfig
96 * Maintains the local, normalized CustomEvent queue
97 * @property eventQueue
104 * Custom Event, notifying subscribers when Config properties are set
105 * (setProperty is called without the silent flag
106 * @event configChangedEvent
108 configChangedEvent: null,
111 * Initializes the configuration Object and all of its local members.
113 * @param {Object} owner The owner Object to which this Config
116 init: function (owner) {
120 this.configChangedEvent =
121 this.createEvent(Config.CONFIG_CHANGED_EVENT);
123 this.configChangedEvent.signature = CustomEvent.LIST;
124 this.queueInProgress = false;
126 this.initialConfig = {};
127 this.eventQueue = [];
132 * Validates that the value passed in is a Boolean.
133 * @method checkBoolean
134 * @param {Object} val The value to validate
135 * @return {Boolean} true, if the value is valid
137 checkBoolean: function (val) {
138 return (typeof val == Config.BOOLEAN_TYPE);
142 * Validates that the value passed in is a number.
143 * @method checkNumber
144 * @param {Object} val The value to validate
145 * @return {Boolean} true, if the value is valid
147 checkNumber: function (val) {
148 return (!isNaN(val));
152 * Fires a configuration property event using the specified value.
155 * @param {String} key The configuration property's name
156 * @param {value} Object The value of the correct type for the property
158 fireEvent: function ( key, value ) {
159 var property = this.config[key];
161 if (property && property.event) {
162 property.event.fire(value);
167 * Adds a property to the Config Object's private config hash.
168 * @method addProperty
169 * @param {String} key The configuration property's name
170 * @param {Object} propertyObject The Object containing all of this
171 * property's arguments
173 addProperty: function ( key, propertyObject ) {
174 key = key.toLowerCase();
176 this.config[key] = propertyObject;
178 propertyObject.event = this.createEvent(key, { scope: this.owner });
179 propertyObject.event.signature = CustomEvent.LIST;
182 propertyObject.key = key;
184 if (propertyObject.handler) {
185 propertyObject.event.subscribe(propertyObject.handler,
189 this.setProperty(key, propertyObject.value, true);
191 if (! propertyObject.suppressEvent) {
192 this.queueProperty(key, propertyObject.value);
198 * Returns a key-value configuration map of the values currently set in
201 * @return {Object} The current config, represented in a key-value map
203 getConfig: function () {
209 for (prop in this.config) {
210 property = this.config[prop];
211 if (property && property.event) {
212 cfg[prop] = property.value;
220 * Returns the value of specified property.
221 * @method getProperty
222 * @param {String} key The name of the property
223 * @return {Object} The value of the specified property
225 getProperty: function (key) {
226 var property = this.config[key.toLowerCase()];
227 if (property && property.event) {
228 return property.value;
235 * Resets the specified property's value to its initial value.
236 * @method resetProperty
237 * @param {String} key The name of the property
238 * @return {Boolean} True is the property was reset, false if not
240 resetProperty: function (key) {
242 key = key.toLowerCase();
244 var property = this.config[key];
246 if (property && property.event) {
248 if (this.initialConfig[key] &&
249 !Lang.isUndefined(this.initialConfig[key])) {
251 this.setProperty(key, this.initialConfig[key]);
265 * Sets the value of a property. If the silent property is passed as
266 * true, the property's event will not be fired.
267 * @method setProperty
268 * @param {String} key The name of the property
269 * @param {String} value The value to set the property to
270 * @param {Boolean} silent Whether the value should be set silently,
271 * without firing the property event.
272 * @return {Boolean} True, if the set was successful, false if it failed.
274 setProperty: function (key, value, silent) {
278 key = key.toLowerCase();
280 if (this.queueInProgress && ! silent) {
281 // Currently running through a queue...
282 this.queueProperty(key,value);
286 property = this.config[key];
287 if (property && property.event) {
288 if (property.validator && !property.validator(value)) {
291 property.value = value;
293 this.fireEvent(key, value);
294 this.configChangedEvent.fire([key, value]);
305 * Sets the value of a property and queues its event to execute. If the
306 * event is already scheduled to execute, it is
307 * moved from its current position to the end of the queue.
308 * @method queueProperty
309 * @param {String} key The name of the property
310 * @param {String} value The value to set the property to
311 * @return {Boolean} true, if the set was successful, false if
314 queueProperty: function (key, value) {
316 key = key.toLowerCase();
318 var property = this.config[key],
319 foundDuplicate = false,
334 if (property && property.event) {
336 if (!Lang.isUndefined(value) && property.validator &&
337 !property.validator(value)) { // validator
341 if (!Lang.isUndefined(value)) {
342 property.value = value;
344 value = property.value;
347 foundDuplicate = false;
348 iLen = this.eventQueue.length;
350 for (i = 0; i < iLen; i++) {
351 queueItem = this.eventQueue[i];
354 queueItemKey = queueItem[0];
355 queueItemValue = queueItem[1];
357 if (queueItemKey == key) {
360 found a dupe... push to end of queue, null
361 current item, and break
364 this.eventQueue[i] = null;
366 this.eventQueue.push(
367 [key, (!Lang.isUndefined(value) ?
368 value : queueItemValue)]);
370 foundDuplicate = true;
376 // this is a refire, or a new property in the queue
378 if (! foundDuplicate && !Lang.isUndefined(value)) {
379 this.eventQueue.push([key, value]);
383 if (property.supercedes) {
385 sLen = property.supercedes.length;
387 for (s = 0; s < sLen; s++) {
389 supercedesCheck = property.supercedes[s];
390 qLen = this.eventQueue.length;
392 for (q = 0; q < qLen; q++) {
393 queueItemCheck = this.eventQueue[q];
395 if (queueItemCheck) {
396 queueItemCheckKey = queueItemCheck[0];
397 queueItemCheckValue = queueItemCheck[1];
399 if (queueItemCheckKey ==
400 supercedesCheck.toLowerCase() ) {
402 this.eventQueue.push([queueItemCheckKey,
403 queueItemCheckValue]);
405 this.eventQueue[q] = null;
422 * Fires the event for a property using the property's current value.
423 * @method refireEvent
424 * @param {String} key The name of the property
426 refireEvent: function (key) {
428 key = key.toLowerCase();
430 var property = this.config[key];
432 if (property && property.event &&
434 !Lang.isUndefined(property.value)) {
436 if (this.queueInProgress) {
438 this.queueProperty(key);
442 this.fireEvent(key, property.value);
450 * Applies a key-value Object literal to the configuration, replacing
451 * any existing values, and queueing the property events.
452 * Although the values will be set, fireQueue() must be called for their
453 * associated events to execute.
454 * @method applyConfig
455 * @param {Object} userConfig The configuration Object literal
456 * @param {Boolean} init When set to true, the initialConfig will
457 * be set to the userConfig passed in, so that calling a reset will
458 * reset the properties to the passed values.
460 applyConfig: function (userConfig, init) {
465 this.initialConfig = userConfig;
467 for (prop in userConfig) {
468 this.queueProperty(prop, userConfig[prop]);
473 * Refires the events for all configuration properties using their
477 refresh: function () {
481 for (prop in this.config) {
482 this.refireEvent(prop);
487 * Fires the normalized list of queued property change events
490 fireQueue: function () {
498 this.queueInProgress = true;
499 for (i = 0;i < this.eventQueue.length; i++) {
500 queueItem = this.eventQueue[i];
504 value = queueItem[1];
505 property = this.config[key];
507 property.value = value;
509 this.fireEvent(key,value);
513 this.queueInProgress = false;
514 this.eventQueue = [];
518 * Subscribes an external handler to the change event for any
520 * @method subscribeToConfigEvent
521 * @param {String} key The property name
522 * @param {Function} handler The handler function to use subscribe to
523 * the property's event
524 * @param {Object} obj The Object to use for scoping the event handler
525 * (see CustomEvent documentation)
526 * @param {Boolean} override Optional. If true, will override "this"
527 * within the handler to map to the scope Object passed into the method.
528 * @return {Boolean} True, if the subscription was successful,
531 subscribeToConfigEvent: function (key, handler, obj, override) {
533 var property = this.config[key.toLowerCase()];
535 if (property && property.event) {
537 if (!Config.alreadySubscribed(property.event, handler, obj)) {
539 property.event.subscribe(handler, obj, override);
554 * Unsubscribes an external handler from the change event for any
556 * @method unsubscribeFromConfigEvent
557 * @param {String} key The property name
558 * @param {Function} handler The handler function to use subscribe to
559 * the property's event
560 * @param {Object} obj The Object to use for scoping the event
561 * handler (see CustomEvent documentation)
562 * @return {Boolean} True, if the unsubscription was successful,
565 unsubscribeFromConfigEvent: function (key, handler, obj) {
566 var property = this.config[key.toLowerCase()];
567 if (property && property.event) {
568 return property.event.unsubscribe(handler, obj);
575 * Returns a string representation of the Config object
577 * @return {String} The Config object in string format.
579 toString: function () {
580 var output = "Config";
582 output += " [" + this.owner.toString() + "]";
588 * Returns a string representation of the Config object's current
590 * @method outputEventQueue
591 * @return {String} The string list of CustomEvents currently queued
594 outputEventQueue: function () {
599 nQueue = this.eventQueue.length;
601 for (q = 0; q < nQueue; q++) {
602 queueItem = this.eventQueue[q];
604 output += queueItem[0] + "=" + queueItem[1] + ", ";
611 * Sets all properties to null, unsubscribes all listeners from each
612 * property's change event and all listeners from the configChangedEvent.
615 destroy: function () {
617 var oConfig = this.config,
622 for (sProperty in oConfig) {
624 if (Lang.hasOwnProperty(oConfig, sProperty)) {
626 oProperty = oConfig[sProperty];
628 oProperty.event.unsubscribeAll();
629 oProperty.event = null;
635 this.configChangedEvent.unsubscribeAll();
637 this.configChangedEvent = null;
640 this.initialConfig = null;
641 this.eventQueue = null;
650 * Checks to determine if a particular function/Object pair are already
651 * subscribed to the specified CustomEvent
652 * @method YAHOO.util.Config.alreadySubscribed
654 * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check
656 * @param {Function} fn The function to look for in the subscribers list
657 * @param {Object} obj The execution scope Object for the subscription
658 * @return {Boolean} true, if the function/Object pair is already subscribed
659 * to the CustomEvent passed in
661 Config.alreadySubscribed = function (evt, fn, obj) {
663 var nSubscribers = evt.subscribers.length,
667 if (nSubscribers > 0) {
669 i = nSubscribers - 1;
673 subsc = evt.subscribers[i];
675 if (subsc && subsc.obj == obj && subsc.fn == fn) {
690 YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
695 * YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
696 * used for adding, subtracting, and comparing dates.
697 * @namespace YAHOO.widget
700 YAHOO.widget.DateMath = {
702 * Constant field representing Day
711 * Constant field representing Week
720 * Constant field representing Year
729 * Constant field representing Month
738 * Constant field representing one day, in milliseconds
739 * @property ONE_DAY_MS
744 ONE_DAY_MS : 1000*60*60*24,
747 * Adds the specified amount of time to the this instance.
749 * @param {Date} date The JavaScript Date object to perform addition on
750 * @param {String} field The field constant to be used for performing addition.
751 * @param {Number} amount The number of units (measured in the field constant) to add to the date.
752 * @return {Date} The resulting Date object
754 add : function(date, field, amount) {
755 var d = new Date(date.getTime());
758 var newMonth = date.getMonth() + amount;
763 while (newMonth < 0) {
767 } else if (newMonth > 11) {
768 while (newMonth > 11) {
774 d.setMonth(newMonth);
775 d.setFullYear(date.getFullYear() + years);
778 d.setDate(date.getDate() + amount);
781 d.setFullYear(date.getFullYear() + amount);
784 d.setDate(date.getDate() + (amount * 7));
791 * Subtracts the specified amount of time from the this instance.
793 * @param {Date} date The JavaScript Date object to perform subtraction on
794 * @param {Number} field The this field constant to be used for performing subtraction.
795 * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
796 * @return {Date} The resulting Date object
798 subtract : function(date, field, amount) {
799 return this.add(date, field, (amount*-1));
803 * Determines whether a given date is before another date on the calendar.
805 * @param {Date} date The Date object to compare with the compare argument
806 * @param {Date} compareTo The Date object to use for the comparison
807 * @return {Boolean} true if the date occurs before the compared date; false if not.
809 before : function(date, compareTo) {
810 var ms = compareTo.getTime();
811 if (date.getTime() < ms) {
819 * Determines whether a given date is after another date on the calendar.
821 * @param {Date} date The Date object to compare with the compare argument
822 * @param {Date} compareTo The Date object to use for the comparison
823 * @return {Boolean} true if the date occurs after the compared date; false if not.
825 after : function(date, compareTo) {
826 var ms = compareTo.getTime();
827 if (date.getTime() > ms) {
835 * Determines whether a given date is between two other dates on the calendar.
837 * @param {Date} date The date to check for
838 * @param {Date} dateBegin The start of the range
839 * @param {Date} dateEnd The end of the range
840 * @return {Boolean} true if the date occurs between the compared dates; false if not.
842 between : function(date, dateBegin, dateEnd) {
843 if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
851 * Retrieves a JavaScript Date object representing January 1 of any given year.
853 * @param {Number} calendarYear The calendar year for which to retrieve January 1
854 * @return {Date} January 1 of the calendar year specified.
856 getJan1 : function(calendarYear) {
857 return new Date(calendarYear,0,1);
861 * Calculates the number of days the specified date is from January 1 of the specified calendar year.
862 * Passing January 1 to this function would return an offset value of zero.
863 * @method getDayOffset
864 * @param {Date} date The JavaScript date for which to find the offset
865 * @param {Number} calendarYear The calendar year to use for determining the offset
866 * @return {Number} The number of days since January 1 of the given year
868 getDayOffset : function(date, calendarYear) {
869 var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
871 // Find the number of days the passed in date is away from the calendar year start
872 var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
877 * Calculates the week number for the given date. This function assumes that week 1 is the
878 * week in which January 1 appears, regardless of whether the week consists of a full 7 days.
879 * The calendar year can be specified to help find what a the week number would be for a given
880 * date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
881 * week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
883 * @method getWeekNumber
884 * @param {Date} date The JavaScript date for which to find the week number
885 * @param {Number} calendarYear OPTIONAL - The calendar year to use for determining the week number. Default is
886 * the calendar year of parameter "date".
887 * @return {Number} The week number of the given date.
889 getWeekNumber : function(date, calendarYear) {
890 date = this.clearTime(date);
891 var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
893 var jan1 = new Date(nearestThurs.getFullYear(),0,1);
894 var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
896 var weekNum = Math.ceil((dayOfYear)/ 7);
901 * Determines if a given week overlaps two different years.
902 * @method isYearOverlapWeek
903 * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
904 * @return {Boolean} true if the date overlaps two different years.
906 isYearOverlapWeek : function(weekBeginDate) {
907 var overlaps = false;
908 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
909 if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
916 * Determines if a given week overlaps two different months.
917 * @method isMonthOverlapWeek
918 * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
919 * @return {Boolean} true if the date overlaps two different months.
921 isMonthOverlapWeek : function(weekBeginDate) {
922 var overlaps = false;
923 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
924 if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
931 * Gets the first day of a month containing a given date.
932 * @method findMonthStart
933 * @param {Date} date The JavaScript Date used to calculate the month start
934 * @return {Date} The JavaScript Date representing the first day of the month
936 findMonthStart : function(date) {
937 var start = new Date(date.getFullYear(), date.getMonth(), 1);
942 * Gets the last day of a month containing a given date.
943 * @method findMonthEnd
944 * @param {Date} date The JavaScript Date used to calculate the month end
945 * @return {Date} The JavaScript Date representing the last day of the month
947 findMonthEnd : function(date) {
948 var start = this.findMonthStart(date);
949 var nextMonth = this.add(start, this.MONTH, 1);
950 var end = this.subtract(nextMonth, this.DAY, 1);
955 * Clears the time fields from a given date, effectively setting the time to 12 noon.
957 * @param {Date} date The JavaScript Date for which the time fields will be cleared
958 * @return {Date} The JavaScript Date cleared of all time fields
960 clearTime : function(date) {
961 date.setHours(12,0,0,0);
967 * 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.
970 * @namespace YAHOO.widget
971 * @requires yahoo,dom,event
975 * Calendar is the base class for the Calendar widget. In its most basic
976 * implementation, it has the ability to render a calendar widget on the page
977 * that can be manipulated to select a single date, move back and forth between
979 * <p>To construct the placeholder for the calendar widget, the code is as
982 * <div id="cal1Container"></div>
985 * @namespace YAHOO.widget
988 * @param {String} id The id of the table element that will represent the calendar widget
989 * @param {String} containerId The id of the container div element that will wrap the calendar table
990 * @param {Object} config The configuration object containing the Calendar's arguments
992 YAHOO.widget.Calendar = function(id, containerId, config) {
993 this.init(id, containerId, config);
997 * The path to be used for images loaded for the Calendar
998 * @property YAHOO.widget.Calendar.IMG_ROOT
1000 * @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
1003 YAHOO.widget.Calendar.IMG_ROOT = null;
1006 * Type constant used for renderers to represent an individual date (M/D/Y)
1007 * @property YAHOO.widget.Calendar.DATE
1012 YAHOO.widget.Calendar.DATE = "D";
1015 * Type constant used for renderers to represent an individual date across any year (M/D)
1016 * @property YAHOO.widget.Calendar.MONTH_DAY
1021 YAHOO.widget.Calendar.MONTH_DAY = "MD";
1024 * Type constant used for renderers to represent a weekday
1025 * @property YAHOO.widget.Calendar.WEEKDAY
1030 YAHOO.widget.Calendar.WEEKDAY = "WD";
1033 * Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
1034 * @property YAHOO.widget.Calendar.RANGE
1039 YAHOO.widget.Calendar.RANGE = "R";
1042 * Type constant used for renderers to represent a month across any year
1043 * @property YAHOO.widget.Calendar.MONTH
1048 YAHOO.widget.Calendar.MONTH = "M";
1051 * Constant that represents the total number of date cells that are displayed in a given month
1052 * @property YAHOO.widget.Calendar.DISPLAY_DAYS
1057 YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
1060 * Constant used for halting the execution of the remainder of the render stack
1061 * @property YAHOO.widget.Calendar.STOP_RENDER
1066 YAHOO.widget.Calendar.STOP_RENDER = "S";
1069 * Constant used to represent short date field string formats (e.g. Tu or Feb)
1070 * @property YAHOO.widget.Calendar.SHORT
1075 YAHOO.widget.Calendar.SHORT = "short";
1078 * Constant used to represent long date field string formats (e.g. Monday or February)
1079 * @property YAHOO.widget.Calendar.LONG
1084 YAHOO.widget.Calendar.LONG = "long";
1087 * Constant used to represent medium date field string formats (e.g. Mon)
1088 * @property YAHOO.widget.Calendar.MEDIUM
1093 YAHOO.widget.Calendar.MEDIUM = "medium";
1096 * Constant used to represent single character date field string formats (e.g. M, T, W)
1097 * @property YAHOO.widget.Calendar.ONE_CHAR
1102 YAHOO.widget.Calendar.ONE_CHAR = "1char";
1105 * The set of default Config property keys and values for the Calendar
1106 * @property YAHOO.widget.Calendar._DEFAULT_CONFIG
1112 YAHOO.widget.Calendar._DEFAULT_CONFIG = {
1113 // Default values for pagedate and selected are not class level constants - they are set during instance creation
1114 PAGEDATE : {key:"pagedate", value:null},
1115 SELECTED : {key:"selected", value:null},
1116 TITLE : {key:"title", value:""},
1117 CLOSE : {key:"close", value:false},
1118 IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
1119 MINDATE : {key:"mindate", value:null},
1120 MAXDATE : {key:"maxdate", value:null},
1121 MULTI_SELECT : {key:"multi_select", value:false},
1122 START_WEEKDAY : {key:"start_weekday", value:0},
1123 SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
1124 SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
1125 SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
1126 HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
1127 NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
1128 NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
1129 MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
1130 MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
1131 WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
1132 WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
1133 WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
1134 WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
1135 LOCALE_MONTHS:{key:"locale_months", value:"long"},
1136 LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
1137 DATE_DELIMITER:{key:"date_delimiter", value:","},
1138 DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
1139 DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
1140 MY_MONTH_POSITION:{key:"my_month_position", value:1},
1141 MY_YEAR_POSITION:{key:"my_year_position", value:2},
1142 MD_MONTH_POSITION:{key:"md_month_position", value:1},
1143 MD_DAY_POSITION:{key:"md_day_position", value:2},
1144 MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
1145 MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
1146 MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
1147 MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
1148 MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
1149 MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
1150 MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""}
1154 * The set of Custom Event types supported by the Calendar
1155 * @property YAHOO.widget.Calendar._EVENT_TYPES
1161 YAHOO.widget.Calendar._EVENT_TYPES = {
1162 BEFORE_SELECT : "beforeSelect",
1164 BEFORE_DESELECT : "beforeDeselect",
1165 DESELECT : "deselect",
1166 CHANGE_PAGE : "changePage",
1167 BEFORE_RENDER : "beforeRender",
1174 * The set of default style constants for the Calendar
1175 * @property YAHOO.widget.Calendar._STYLES
1181 YAHOO.widget.Calendar._STYLES = {
1182 CSS_ROW_HEADER: "calrowhead",
1183 CSS_ROW_FOOTER: "calrowfoot",
1184 CSS_CELL : "calcell",
1185 CSS_CELL_SELECTOR : "selector",
1186 CSS_CELL_SELECTED : "selected",
1187 CSS_CELL_SELECTABLE : "selectable",
1188 CSS_CELL_RESTRICTED : "restricted",
1189 CSS_CELL_TODAY : "today",
1190 CSS_CELL_OOM : "oom",
1191 CSS_CELL_OOB : "previous",
1192 CSS_HEADER : "calheader",
1193 CSS_HEADER_TEXT : "calhead",
1194 CSS_BODY : "calbody",
1195 CSS_WEEKDAY_CELL : "calweekdaycell",
1196 CSS_WEEKDAY_ROW : "calweekdayrow",
1197 CSS_FOOTER : "calfoot",
1198 CSS_CALENDAR : "yui-calendar",
1199 CSS_SINGLE : "single",
1200 CSS_CONTAINER : "yui-calcontainer",
1201 CSS_NAV_LEFT : "calnavleft",
1202 CSS_NAV_RIGHT : "calnavright",
1203 CSS_CLOSE : "calclose",
1204 CSS_CELL_TOP : "calcelltop",
1205 CSS_CELL_LEFT : "calcellleft",
1206 CSS_CELL_RIGHT : "calcellright",
1207 CSS_CELL_BOTTOM : "calcellbottom",
1208 CSS_CELL_HOVER : "calcellhover",
1209 CSS_CELL_HIGHLIGHT1 : "highlight1",
1210 CSS_CELL_HIGHLIGHT2 : "highlight2",
1211 CSS_CELL_HIGHLIGHT3 : "highlight3",
1212 CSS_CELL_HIGHLIGHT4 : "highlight4"
1215 YAHOO.widget.Calendar.prototype = {
1218 * The configuration object used to set up the calendars various locale and style options.
1221 * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
1227 * The parent CalendarGroup, only to be set explicitly by the parent group
1229 * @type CalendarGroup
1234 * The index of this item in the parent group
1241 * The collection of calendar table cells
1243 * @type HTMLTableCellElement[]
1248 * 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].
1249 * @property cellDates
1250 * @type Array[](Number[])
1255 * The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
1262 * 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.
1263 * @property oDomContainer
1266 oDomContainer : null,
1269 * A Date object representing today's date.
1276 * The list of render functions, along with required parameters, used to render cells.
1277 * @property renderStack
1283 * A copy of the initial render functions created before rendering.
1284 * @property _renderStack
1288 _renderStack : null,
1291 * The private list of initially selected dates.
1292 * @property _selectedDates
1296 _selectedDates : null,
1299 * A map of DOM event handlers to attach to cells associated with specific CSS class names
1300 * @property domEventMap
1309 * Initializes the Calendar widget.
1311 * @param {String} id The id of the table element that will represent the calendar widget
1312 * @param {String} containerId The id of the container div element that will wrap the calendar table
1313 * @param {Object} config The configuration object containing the Calendar's arguments
1315 YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
1317 this.today = new Date();
1318 YAHOO.widget.DateMath.clearTime(this.today);
1321 this.oDomContainer = document.getElementById(containerId);
1324 * The Config object used to hold the configuration variables for the Calendar
1326 * @type YAHOO.util.Config
1328 this.cfg = new YAHOO.util.Config(this);
1331 * The local object which contains the Calendar's options
1338 * The local object which contains the Calendar's locale settings
1346 YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
1347 YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
1349 this.cellDates = [];
1351 this.renderStack = [];
1352 this._renderStack = [];
1357 this.cfg.applyConfig(config, true);
1360 this.cfg.fireQueue();
1364 * Default Config listener for the iframe property. If the iframe config property is set to true,
1365 * renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
1367 * @method configIframe
1369 YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
1370 var useIframe = args[0];
1373 if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
1375 var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
1377 if (pos == "absolute" || pos == "relative") {
1379 if (!YAHOO.util.Dom.inDocument(this.iframe)) {
1380 this.iframe = document.createElement("iframe");
1381 this.iframe.src = "javascript:false;";
1383 YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
1385 if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
1386 YAHOO.util.Dom.addClass(this.iframe, "fixedsize");
1389 this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
1394 if (this.iframe.parentNode) {
1395 this.iframe.parentNode.removeChild(this.iframe);
1405 * Default handler for the "title" property
1406 * @method configTitle
1408 YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
1409 var title = args[0];
1410 var close = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.CLOSE.key);
1414 if (title && title !== "") {
1415 titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
1416 titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
1417 titleDiv.innerHTML = title;
1418 this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
1419 YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
1421 titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
1424 YAHOO.util.Event.purgeElement(titleDiv);
1425 this.oDomContainer.removeChild(titleDiv);
1428 YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
1434 * Default handler for the "close" property
1435 * @method configClose
1437 YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
1438 var close = args[0];
1439 var title = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.TITLE.key);
1441 var DEPR_CLOSE_PATH = "us/my/bn/x_d.gif";
1445 if (close === true) {
1446 linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
1447 linkClose.href = "#";
1448 linkClose.className = "link-close";
1449 YAHOO.util.Event.addListener(linkClose, "click", function(e, cal) {cal.hide(); YAHOO.util.Event.preventDefault(e); }, this);
1451 if (YAHOO.widget.Calendar.IMG_ROOT !== null) {
1452 var imgClose = document.createElement("img");
1453 imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
1454 imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
1455 linkClose.appendChild(imgClose);
1457 linkClose.innerHTML = '<span class="' + YAHOO.widget.CalendarGroup.CSS_2UPCLOSE + ' ' + this.Style.CSS_CLOSE + '"></span>';
1460 this.oDomContainer.appendChild(linkClose);
1461 YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
1463 linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
1465 YAHOO.util.Event.purgeElement(linkClose);
1466 this.oDomContainer.removeChild(linkClose);
1468 if (! title || title === "") {
1469 YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
1475 * Initializes Calendar's built-in CustomEvents
1476 * @method initEvents
1478 YAHOO.widget.Calendar.prototype.initEvents = function() {
1480 var defEvents = YAHOO.widget.Calendar._EVENT_TYPES;
1483 * Fired before a selection is made
1484 * @event beforeSelectEvent
1486 this.beforeSelectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_SELECT);
1489 * Fired when a selection is made
1490 * @event selectEvent
1491 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
1493 this.selectEvent = new YAHOO.util.CustomEvent(defEvents.SELECT);
1496 * Fired before a selection is made
1497 * @event beforeDeselectEvent
1499 this.beforeDeselectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_DESELECT);
1502 * Fired when a selection is made
1503 * @event deselectEvent
1504 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
1506 this.deselectEvent = new YAHOO.util.CustomEvent(defEvents.DESELECT);
1509 * Fired when the Calendar page is changed
1510 * @event changePageEvent
1512 this.changePageEvent = new YAHOO.util.CustomEvent(defEvents.CHANGE_PAGE);
1515 * Fired before the Calendar is rendered
1516 * @event beforeRenderEvent
1518 this.beforeRenderEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_RENDER);
1521 * Fired when the Calendar is rendered
1522 * @event renderEvent
1524 this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
1527 * Fired when the Calendar is reset
1530 this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET);
1533 * Fired when the Calendar is cleared
1536 this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
1538 this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
1539 this.selectEvent.subscribe(this.onSelect, this, true);
1540 this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
1541 this.deselectEvent.subscribe(this.onDeselect, this, true);
1542 this.changePageEvent.subscribe(this.onChangePage, this, true);
1543 this.renderEvent.subscribe(this.onRender, this, true);
1544 this.resetEvent.subscribe(this.onReset, this, true);
1545 this.clearEvent.subscribe(this.onClear, this, true);
1549 * The default event function that is attached to a date link within a calendar cell
1550 * when the calendar is rendered.
1551 * @method doSelectCell
1552 * @param {DOMEvent} e The event
1553 * @param {Calendar} cal A reference to the calendar passed by the Event utility
1555 YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
1556 var cell,index,d,date;
1558 var target = YAHOO.util.Event.getTarget(e);
1559 var tagName = target.tagName.toLowerCase();
1560 var defSelector = false;
1562 while (tagName != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1564 if (!defSelector && tagName == "a" && YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
1568 target = target.parentNode;
1569 tagName = target.tagName.toLowerCase();
1570 if (tagName == "html") {
1576 // Stop link href navigation for default renderer
1577 YAHOO.util.Event.preventDefault(e);
1582 if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
1583 index = cell.id.split("cell")[1];
1584 d = cal.cellDates[index];
1585 date = new Date(d[0],d[1]-1,d[2]);
1589 if (cal.Options.MULTI_SELECT) {
1590 link = cell.getElementsByTagName("a")[0];
1595 var cellDate = cal.cellDates[index];
1596 var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
1598 if (cellDateIndex > -1) {
1599 cal.deselectCell(index);
1601 cal.selectCell(index);
1605 link = cell.getElementsByTagName("a")[0];
1609 cal.selectCell(index);
1615 * The event that is executed when the user hovers over a cell
1616 * @method doCellMouseOver
1617 * @param {DOMEvent} e The event
1618 * @param {Calendar} cal A reference to the calendar passed by the Event utility
1620 YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
1623 target = YAHOO.util.Event.getTarget(e);
1628 while (target.tagName.toLowerCase() != "td") {
1629 target = target.parentNode;
1630 if (target.tagName.toLowerCase() == "html") {
1635 if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1636 YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
1641 * The event that is executed when the user moves the mouse out of a cell
1642 * @method doCellMouseOut
1643 * @param {DOMEvent} e The event
1644 * @param {Calendar} cal A reference to the calendar passed by the Event utility
1646 YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
1649 target = YAHOO.util.Event.getTarget(e);
1654 while (target.tagName.toLowerCase() != "td") {
1655 target = target.parentNode;
1656 if (target.tagName.toLowerCase() == "html") {
1661 if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1662 YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
1666 YAHOO.widget.Calendar.prototype.setupConfig = function() {
1668 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
1671 * The month/year representing the current visible Calendar date (mm/yyyy)
1674 * @default today's date
1676 this.cfg.addProperty(defCfg.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
1679 * The date or range of dates representing the current Calendar selection
1684 this.cfg.addProperty(defCfg.SELECTED.key, { value:[], handler:this.configSelected } );
1687 * The title to display above the Calendar's month header
1692 this.cfg.addProperty(defCfg.TITLE.key, { value:defCfg.TITLE.value, handler:this.configTitle } );
1695 * Whether or not a close button should be displayed for this Calendar
1700 this.cfg.addProperty(defCfg.CLOSE.key, { value:defCfg.CLOSE.value, handler:this.configClose } );
1703 * 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.
1704 * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
1705 * enabled if required.
1709 * @default true for IE6 and below, false for all other browsers
1711 this.cfg.addProperty(defCfg.IFRAME.key, { value:defCfg.IFRAME.value, handler:this.configIframe, validator:this.cfg.checkBoolean } );
1714 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
1719 this.cfg.addProperty(defCfg.MINDATE.key, { value:defCfg.MINDATE.value, handler:this.configMinDate } );
1722 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
1727 this.cfg.addProperty(defCfg.MAXDATE.key, { value:defCfg.MAXDATE.value, handler:this.configMaxDate } );
1730 // Options properties
1733 * True if the Calendar should allow multiple selections. False by default.
1734 * @config MULTI_SELECT
1738 this.cfg.addProperty(defCfg.MULTI_SELECT.key, { value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1741 * The weekday the week begins on. Default is 0 (Sunday).
1742 * @config START_WEEKDAY
1746 this.cfg.addProperty(defCfg.START_WEEKDAY.key, { value:defCfg.START_WEEKDAY.value, handler:this.configOptions, validator:this.cfg.checkNumber } );
1749 * True if the Calendar should show weekday labels. True by default.
1750 * @config SHOW_WEEKDAYS
1754 this.cfg.addProperty(defCfg.SHOW_WEEKDAYS.key, { value:defCfg.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1757 * True if the Calendar should show week row headers. False by default.
1758 * @config SHOW_WEEK_HEADER
1762 this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key, { value:defCfg.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1765 * True if the Calendar should show week row footers. False by default.
1766 * @config SHOW_WEEK_FOOTER
1770 this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1773 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
1774 * @config HIDE_BLANK_WEEKS
1778 this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key, { value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1781 * The image that should be used for the left navigation arrow.
1782 * @config NAV_ARROW_LEFT
1784 * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
1787 this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key, { value:defCfg.NAV_ARROW_LEFT.value, handler:this.configOptions } );
1790 * The image that should be used for the right navigation arrow.
1791 * @config NAV_ARROW_RIGHT
1793 * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
1796 this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key, { value:defCfg.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
1798 // Locale properties
1801 * The short month labels for the current locale.
1802 * @config MONTHS_SHORT
1804 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
1806 this.cfg.addProperty(defCfg.MONTHS_SHORT.key, { value:defCfg.MONTHS_SHORT.value, handler:this.configLocale } );
1809 * The long month labels for the current locale.
1810 * @config MONTHS_LONG
1812 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
1814 this.cfg.addProperty(defCfg.MONTHS_LONG.key, { value:defCfg.MONTHS_LONG.value, handler:this.configLocale } );
1817 * The 1-character weekday labels for the current locale.
1818 * @config WEEKDAYS_1CHAR
1820 * @default ["S", "M", "T", "W", "T", "F", "S"]
1822 this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key, { value:defCfg.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
1825 * The short weekday labels for the current locale.
1826 * @config WEEKDAYS_SHORT
1828 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
1830 this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key, { value:defCfg.WEEKDAYS_SHORT.value, handler:this.configLocale } );
1833 * The medium weekday labels for the current locale.
1834 * @config WEEKDAYS_MEDIUM
1836 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
1838 this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key, { value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.configLocale } );
1841 * The long weekday labels for the current locale.
1842 * @config WEEKDAYS_LONG
1844 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
1846 this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key, { value:defCfg.WEEKDAYS_LONG.value, handler:this.configLocale } );
1849 * Refreshes the locale values used to build the Calendar.
1850 * @method refreshLocale
1853 var refreshLocale = function() {
1854 this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
1855 this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
1858 this.cfg.subscribeToConfigEvent(defCfg.START_WEEKDAY.key, refreshLocale, this, true);
1859 this.cfg.subscribeToConfigEvent(defCfg.MONTHS_SHORT.key, refreshLocale, this, true);
1860 this.cfg.subscribeToConfigEvent(defCfg.MONTHS_LONG.key, refreshLocale, this, true);
1861 this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
1862 this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_SHORT.key, refreshLocale, this, true);
1863 this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
1864 this.cfg.subscribeToConfigEvent(defCfg.WEEKDAYS_LONG.key, refreshLocale, this, true);
1867 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
1868 * @config LOCALE_MONTHS
1872 this.cfg.addProperty(defCfg.LOCALE_MONTHS.key, { value:defCfg.LOCALE_MONTHS.value, handler:this.configLocaleValues } );
1875 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
1876 * @config LOCALE_WEEKDAYS
1880 this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key, { value:defCfg.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
1883 * The value used to delimit individual dates in a date string passed to various Calendar functions.
1884 * @config DATE_DELIMITER
1888 this.cfg.addProperty(defCfg.DATE_DELIMITER.key, { value:defCfg.DATE_DELIMITER.value, handler:this.configLocale } );
1891 * The value used to delimit date fields in a date string passed to various Calendar functions.
1892 * @config DATE_FIELD_DELIMITER
1896 this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key, { value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.configLocale } );
1899 * The value used to delimit date ranges in a date string passed to various Calendar functions.
1900 * @config DATE_RANGE_DELIMITER
1904 this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key, { value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
1907 * The position of the month in a month/year date string
1908 * @config MY_MONTH_POSITION
1912 this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key, { value:defCfg.MY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1915 * The position of the year in a month/year date string
1916 * @config MY_YEAR_POSITION
1920 this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key, { value:defCfg.MY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1923 * The position of the month in a month/day date string
1924 * @config MD_MONTH_POSITION
1928 this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key, { value:defCfg.MD_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1931 * The position of the day in a month/year date string
1932 * @config MD_DAY_POSITION
1936 this.cfg.addProperty(defCfg.MD_DAY_POSITION.key, { value:defCfg.MD_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1939 * The position of the month in a month/day/year date string
1940 * @config MDY_MONTH_POSITION
1944 this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key, { value:defCfg.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1947 * The position of the day in a month/day/year date string
1948 * @config MDY_DAY_POSITION
1952 this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key, { value:defCfg.MDY_DAY_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1955 * The position of the year in a month/day/year date string
1956 * @config MDY_YEAR_POSITION
1960 this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key, { value:defCfg.MDY_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1963 * The position of the month in the month year label string used as the Calendar header
1964 * @config MY_LABEL_MONTH_POSITION
1968 this.cfg.addProperty(defCfg.MY_LABEL_MONTH_POSITION.key, { value:defCfg.MY_LABEL_MONTH_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1971 * The position of the year in the month year label string used as the Calendar header
1972 * @config MY_LABEL_YEAR_POSITION
1976 this.cfg.addProperty(defCfg.MY_LABEL_YEAR_POSITION.key, { value:defCfg.MY_LABEL_YEAR_POSITION.value, handler:this.configLocale, validator:this.cfg.checkNumber } );
1979 * The suffix used after the month when rendering the Calendar header
1980 * @config MY_LABEL_MONTH_SUFFIX
1984 this.cfg.addProperty(defCfg.MY_LABEL_MONTH_SUFFIX.key, { value:defCfg.MY_LABEL_MONTH_SUFFIX.value, handler:this.configLocale } );
1987 * The suffix used after the year when rendering the Calendar header
1988 * @config MY_LABEL_YEAR_SUFFIX
1992 this.cfg.addProperty(defCfg.MY_LABEL_YEAR_SUFFIX.key, { value:defCfg.MY_LABEL_YEAR_SUFFIX.value, handler:this.configLocale } );
1996 * The default handler for the "pagedate" property
1997 * @method configPageDate
1999 YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
2000 this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key, this._parsePageDate(args[0]), true);
2004 * The default handler for the "mindate" property
2005 * @method configMinDate
2007 YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
2009 if (YAHOO.lang.isString(val)) {
2010 val = this._parseDate(val);
2011 this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MINDATE.key, new Date(val[0],(val[1]-1),val[2]));
2016 * The default handler for the "maxdate" property
2017 * @method configMaxDate
2019 YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
2021 if (YAHOO.lang.isString(val)) {
2022 val = this._parseDate(val);
2023 this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MAXDATE.key, new Date(val[0],(val[1]-1),val[2]));
2028 * The default handler for the "selected" property
2029 * @method configSelected
2031 YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
2032 var selected = args[0];
2033 var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
2036 if (YAHOO.lang.isString(selected)) {
2037 this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
2040 if (! this._selectedDates) {
2041 this._selectedDates = this.cfg.getProperty(cfgSelected);
2046 * The default handler for all configuration options properties
2047 * @method configOptions
2049 YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
2050 this.Options[type.toUpperCase()] = args[0];
2054 * The default handler for all configuration locale properties
2055 * @method configLocale
2057 YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
2058 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2059 this.Locale[type.toUpperCase()] = args[0];
2061 this.cfg.refireEvent(defCfg.LOCALE_MONTHS.key);
2062 this.cfg.refireEvent(defCfg.LOCALE_WEEKDAYS.key);
2066 * The default handler for all configuration locale field length properties
2067 * @method configLocaleValues
2069 YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
2070 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2072 type = type.toLowerCase();
2076 case defCfg.LOCALE_MONTHS.key:
2078 case YAHOO.widget.Calendar.SHORT:
2079 this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_SHORT.key).concat();
2081 case YAHOO.widget.Calendar.LONG:
2082 this.Locale.LOCALE_MONTHS = this.cfg.getProperty(defCfg.MONTHS_LONG.key).concat();
2086 case defCfg.LOCALE_WEEKDAYS.key:
2088 case YAHOO.widget.Calendar.ONE_CHAR:
2089 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_1CHAR.key).concat();
2091 case YAHOO.widget.Calendar.SHORT:
2092 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_SHORT.key).concat();
2094 case YAHOO.widget.Calendar.MEDIUM:
2095 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_MEDIUM.key).concat();
2097 case YAHOO.widget.Calendar.LONG:
2098 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty(defCfg.WEEKDAYS_LONG.key).concat();
2102 var START_WEEKDAY = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
2104 if (START_WEEKDAY > 0) {
2105 for (var w=0;w<START_WEEKDAY;++w) {
2106 this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
2114 * Defines the style constants for the Calendar
2115 * @method initStyles
2117 YAHOO.widget.Calendar.prototype.initStyles = function() {
2119 var defStyle = YAHOO.widget.Calendar._STYLES;
2123 * @property Style.CSS_ROW_HEADER
2125 CSS_ROW_HEADER: defStyle.CSS_ROW_HEADER,
2127 * @property Style.CSS_ROW_FOOTER
2129 CSS_ROW_FOOTER: defStyle.CSS_ROW_FOOTER,
2131 * @property Style.CSS_CELL
2133 CSS_CELL : defStyle.CSS_CELL,
2135 * @property Style.CSS_CELL_SELECTOR
2137 CSS_CELL_SELECTOR : defStyle.CSS_CELL_SELECTOR,
2139 * @property Style.CSS_CELL_SELECTED
2141 CSS_CELL_SELECTED : defStyle.CSS_CELL_SELECTED,
2143 * @property Style.CSS_CELL_SELECTABLE
2145 CSS_CELL_SELECTABLE : defStyle.CSS_CELL_SELECTABLE,
2147 * @property Style.CSS_CELL_RESTRICTED
2149 CSS_CELL_RESTRICTED : defStyle.CSS_CELL_RESTRICTED,
2151 * @property Style.CSS_CELL_TODAY
2153 CSS_CELL_TODAY : defStyle.CSS_CELL_TODAY,
2155 * @property Style.CSS_CELL_OOM
2157 CSS_CELL_OOM : defStyle.CSS_CELL_OOM,
2159 * @property Style.CSS_CELL_OOB
2161 CSS_CELL_OOB : defStyle.CSS_CELL_OOB,
2163 * @property Style.CSS_HEADER
2165 CSS_HEADER : defStyle.CSS_HEADER,
2167 * @property Style.CSS_HEADER_TEXT
2169 CSS_HEADER_TEXT : defStyle.CSS_HEADER_TEXT,
2171 * @property Style.CSS_BODY
2173 CSS_BODY : defStyle.CSS_BODY,
2175 * @property Style.CSS_WEEKDAY_CELL
2177 CSS_WEEKDAY_CELL : defStyle.CSS_WEEKDAY_CELL,
2179 * @property Style.CSS_WEEKDAY_ROW
2181 CSS_WEEKDAY_ROW : defStyle.CSS_WEEKDAY_ROW,
2183 * @property Style.CSS_FOOTER
2185 CSS_FOOTER : defStyle.CSS_FOOTER,
2187 * @property Style.CSS_CALENDAR
2189 CSS_CALENDAR : defStyle.CSS_CALENDAR,
2191 * @property Style.CSS_SINGLE
2193 CSS_SINGLE : defStyle.CSS_SINGLE,
2195 * @property Style.CSS_CONTAINER
2197 CSS_CONTAINER : defStyle.CSS_CONTAINER,
2199 * @property Style.CSS_NAV_LEFT
2201 CSS_NAV_LEFT : defStyle.CSS_NAV_LEFT,
2203 * @property Style.CSS_NAV_RIGHT
2205 CSS_NAV_RIGHT : defStyle.CSS_NAV_RIGHT,
2207 * @property Style.CSS_CLOSE
2209 CSS_CLOSE : defStyle.CSS_CLOSE,
2211 * @property Style.CSS_CELL_TOP
2213 CSS_CELL_TOP : defStyle.CSS_CELL_TOP,
2215 * @property Style.CSS_CELL_LEFT
2217 CSS_CELL_LEFT : defStyle.CSS_CELL_LEFT,
2219 * @property Style.CSS_CELL_RIGHT
2221 CSS_CELL_RIGHT : defStyle.CSS_CELL_RIGHT,
2223 * @property Style.CSS_CELL_BOTTOM
2225 CSS_CELL_BOTTOM : defStyle.CSS_CELL_BOTTOM,
2227 * @property Style.CSS_CELL_HOVER
2229 CSS_CELL_HOVER : defStyle.CSS_CELL_HOVER,
2231 * @property Style.CSS_CELL_HIGHLIGHT1
2233 CSS_CELL_HIGHLIGHT1 : defStyle.CSS_CELL_HIGHLIGHT1,
2235 * @property Style.CSS_CELL_HIGHLIGHT2
2237 CSS_CELL_HIGHLIGHT2 : defStyle.CSS_CELL_HIGHLIGHT2,
2239 * @property Style.CSS_CELL_HIGHLIGHT3
2241 CSS_CELL_HIGHLIGHT3 : defStyle.CSS_CELL_HIGHLIGHT3,
2243 * @property Style.CSS_CELL_HIGHLIGHT4
2245 CSS_CELL_HIGHLIGHT4 : defStyle.CSS_CELL_HIGHLIGHT4
2250 * Builds the date label that will be displayed in the calendar header or
2251 * footer, depending on configuration.
2252 * @method buildMonthLabel
2253 * @return {String} The formatted calendar month label
2255 YAHOO.widget.Calendar.prototype.buildMonthLabel = function() {
2256 var pageDate = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key);
2258 var monthLabel = this.Locale.LOCALE_MONTHS[pageDate.getMonth()] + this.Locale.MY_LABEL_MONTH_SUFFIX;
2259 var yearLabel = pageDate.getFullYear() + this.Locale.MY_LABEL_YEAR_SUFFIX;
2261 if (this.Locale.MY_LABEL_MONTH_POSITION == 2 || this.Locale.MY_LABEL_YEAR_POSITION == 1) {
2262 return yearLabel + monthLabel;
2264 return monthLabel + yearLabel;
2269 * Builds the date digit that will be displayed in calendar cells
2270 * @method buildDayLabel
2271 * @param {Date} workingDate The current working date
2272 * @return {String} The formatted day label
2274 YAHOO.widget.Calendar.prototype.buildDayLabel = function(workingDate) {
2275 return workingDate.getDate();
2279 * Renders the calendar header.
2280 * @method renderHeader
2281 * @param {Array} html The current working HTML array
2282 * @return {Array} The current working HTML array
2284 YAHOO.widget.Calendar.prototype.renderHeader = function(html) {
2287 var DEPR_NAV_LEFT = "us/tr/callt.gif";
2288 var DEPR_NAV_RIGHT = "us/tr/calrt.gif";
2289 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2291 if (this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key)) {
2295 if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
2299 html[html.length] = "<thead>";
2300 html[html.length] = "<tr>";
2301 html[html.length] = '<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
2302 html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
2304 var renderLeft, renderRight = false;
2307 if (this.index === 0) {
2310 if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
2318 var cal = this.parent || this;
2321 var leftArrow = this.cfg.getProperty(defCfg.NAV_ARROW_LEFT.key);
2322 // 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
2323 if (leftArrow === null && YAHOO.widget.Calendar.IMG_ROOT !== null) {
2324 leftArrow = YAHOO.widget.Calendar.IMG_ROOT + DEPR_NAV_LEFT;
2326 var leftStyle = (leftArrow === null) ? "" : ' style="background-image:url(' + leftArrow + ')"';
2327 html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '"' + leftStyle + ' > </a>';
2330 html[html.length] = this.buildMonthLabel();
2333 var rightArrow = this.cfg.getProperty(defCfg.NAV_ARROW_RIGHT.key);
2334 if (rightArrow === null && YAHOO.widget.Calendar.IMG_ROOT !== null) {
2335 rightArrow = YAHOO.widget.Calendar.IMG_ROOT + DEPR_NAV_RIGHT;
2337 var rightStyle = (rightArrow === null) ? "" : ' style="background-image:url(' + rightArrow + ')"';
2338 html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '"' + rightStyle + ' > </a>';
2341 html[html.length] = '</div>\n</th>\n</tr>';
2343 if (this.cfg.getProperty(defCfg.SHOW_WEEKDAYS.key)) {
2344 html = this.buildWeekdays(html);
2347 html[html.length] = '</thead>';
2353 * Renders the Calendar's weekday headers.
2354 * @method buildWeekdays
2355 * @param {Array} html The current working HTML array
2356 * @return {Array} The current working HTML array
2358 YAHOO.widget.Calendar.prototype.buildWeekdays = function(html) {
2360 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2362 html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
2364 if (this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key)) {
2365 html[html.length] = '<th> </th>';
2368 for(var i=0;i<this.Locale.LOCALE_WEEKDAYS.length;++i) {
2369 html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
2372 if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
2373 html[html.length] = '<th> </th>';
2376 html[html.length] = '</tr>';
2382 * Renders the calendar body.
2383 * @method renderBody
2384 * @param {Date} workingDate The current working Date being used for the render process
2385 * @param {Array} html The current working HTML array
2386 * @return {Array} The current working HTML array
2388 YAHOO.widget.Calendar.prototype.renderBody = function(workingDate, html) {
2389 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2391 var startDay = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
2393 this.preMonthDays = workingDate.getDay();
2395 this.preMonthDays -= startDay;
2397 if (this.preMonthDays < 0) {
2398 this.preMonthDays += 7;
2401 this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
2402 this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
2404 workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
2406 var weekNum,weekClass;
2407 var weekPrefix = "w";
2408 var cellPrefix = "_cell";
2409 var workingDayPrefix = "wd";
2410 var dayPrefix = "d";
2415 var todayYear = this.today.getFullYear();
2416 var todayMonth = this.today.getMonth();
2417 var todayDate = this.today.getDate();
2419 var useDate = this.cfg.getProperty(defCfg.PAGEDATE.key);
2420 var hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key);
2421 var showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key);
2422 var showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key);
2423 var mindate = this.cfg.getProperty(defCfg.MINDATE.key);
2424 var maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
2427 mindate = YAHOO.widget.DateMath.clearTime(mindate);
2430 maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
2433 html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
2437 var tempDiv = document.createElement("div");
2438 var cell = document.createElement("td");
2439 tempDiv.appendChild(cell);
2441 var jan1 = new Date(useDate.getFullYear(),0,1);
2443 var cal = this.parent || this;
2445 for (var r=0;r<6;r++) {
2447 weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
2448 weekClass = weekPrefix + weekNum;
2450 // Local OOM check for performance, since we already have pagedate
2451 if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
2455 html[html.length] = '<tr class="' + weekClass + '">';
2457 if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
2459 for (var d=0;d<7;d++){ // Render actual days
2464 this.clearElement(cell);
2465 cell.className = this.Style.CSS_CELL;
2466 cell.id = this.id + cellPrefix + i;
2468 if (workingDate.getDate() == todayDate &&
2469 workingDate.getMonth() == todayMonth &&
2470 workingDate.getFullYear() == todayYear) {
2471 cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
2474 var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
2475 this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
2477 // Local OOM check for performance, since we already have pagedate
2478 if (workingDate.getMonth() != useDate.getMonth()) {
2479 cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
2481 YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
2482 YAHOO.util.Dom.addClass(cell, dayPrefix + workingDate.getDate());
2484 for (var s=0;s<this.renderStack.length;++s) {
2486 var rArray = this.renderStack[s];
2487 var type = rArray[0];
2494 case YAHOO.widget.Calendar.DATE:
2495 month = rArray[1][1];
2497 year = rArray[1][0];
2499 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
2500 renderer = rArray[2];
2501 this.renderStack.splice(s,1);
2504 case YAHOO.widget.Calendar.MONTH_DAY:
2505 month = rArray[1][0];
2508 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
2509 renderer = rArray[2];
2510 this.renderStack.splice(s,1);
2513 case YAHOO.widget.Calendar.RANGE:
2514 var date1 = rArray[1][0];
2515 var date2 = rArray[1][1];
2517 var d1month = date1[1];
2518 var d1day = date1[2];
2519 var d1year = date1[0];
2521 var d1 = new Date(d1year, d1month-1, d1day);
2523 var d2month = date2[1];
2524 var d2day = date2[2];
2525 var d2year = date2[0];
2527 var d2 = new Date(d2year, d2month-1, d2day);
2529 if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
2530 renderer = rArray[2];
2532 if (workingDate.getTime()==d2.getTime()) {
2533 this.renderStack.splice(s,1);
2537 case YAHOO.widget.Calendar.WEEKDAY:
2539 var weekday = rArray[1][0];
2540 if (workingDate.getDay()+1 == weekday) {
2541 renderer = rArray[2];
2544 case YAHOO.widget.Calendar.MONTH:
2546 month = rArray[1][0];
2547 if (workingDate.getMonth()+1 == month) {
2548 renderer = rArray[2];
2554 cellRenderers[cellRenderers.length]=renderer;
2560 if (this._indexOfSelectedFieldArray(workingArray) > -1) {
2561 cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
2564 if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
2565 (maxdate && (workingDate.getTime() > maxdate.getTime()))
2567 cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
2569 cellRenderers[cellRenderers.length]=cal.styleCellDefault;
2570 cellRenderers[cellRenderers.length]=cal.renderCellDefault;
2573 for (var x=0; x < cellRenderers.length; ++x) {
2574 if (cellRenderers[x].call(cal, workingDate, cell) == YAHOO.widget.Calendar.STOP_RENDER) {
2579 workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
2581 if (i >= 0 && i <= 6) {
2582 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
2584 if ((i % 7) === 0) {
2585 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
2587 if (((i+1) % 7) === 0) {
2588 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
2591 var postDays = this.postMonthDays;
2592 if (hideBlankWeeks && postDays >= 7) {
2593 var blankWeeks = Math.floor(postDays/7);
2594 for (var p=0;p<blankWeeks;++p) {
2599 if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
2600 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
2603 html[html.length] = tempDiv.innerHTML;
2607 if (showWeekFooter) { html = this.renderRowFooter(weekNum, html); }
2609 html[html.length] = '</tr>';
2613 html[html.length] = '</tbody>';
2619 * Renders the calendar footer. In the default implementation, there is
2621 * @method renderFooter
2622 * @param {Array} html The current working HTML array
2623 * @return {Array} The current working HTML array
2625 YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };
2628 * Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
2629 * when the method is called: renderHeader, renderBody, renderFooter.
2630 * Refer to the documentation for those methods for information on
2631 * individual render tasks.
2634 YAHOO.widget.Calendar.prototype.render = function() {
2635 this.beforeRenderEvent.fire();
2637 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2639 // Find starting day of the current month
2640 var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty(defCfg.PAGEDATE.key));
2642 this.resetRenderers();
2643 this.cellDates.length = 0;
2645 YAHOO.util.Event.purgeElement(this.oDomContainer, true);
2649 html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
2650 html = this.renderHeader(html);
2651 html = this.renderBody(workingDate, html);
2652 html = this.renderFooter(html);
2653 html[html.length] = '</table>';
2655 this.oDomContainer.innerHTML = html.join("\n");
2657 this.applyListeners();
2658 this.cells = this.oDomContainer.getElementsByTagName("td");
2660 this.cfg.refireEvent(defCfg.TITLE.key);
2661 this.cfg.refireEvent(defCfg.CLOSE.key);
2662 this.cfg.refireEvent(defCfg.IFRAME.key);
2664 this.renderEvent.fire();
2668 * Applies the Calendar's DOM listeners to applicable elements.
2669 * @method applyListeners
2671 YAHOO.widget.Calendar.prototype.applyListeners = function() {
2673 var root = this.oDomContainer;
2674 var cal = this.parent || this;
2677 var mousedown = "mousedown";
2679 var linkLeft = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, anchor, root);
2680 var linkRight = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, anchor, root);
2682 if (linkLeft && linkLeft.length > 0) {
2683 this.linkLeft = linkLeft[0];
2684 YAHOO.util.Event.addListener(this.linkLeft, mousedown, cal.previousMonth, cal, true);
2687 if (linkRight && linkRight.length > 0) {
2688 this.linkRight = linkRight[0];
2689 YAHOO.util.Event.addListener(this.linkRight, mousedown, cal.nextMonth, cal, true);
2692 if (this.domEventMap) {
2694 for (var cls in this.domEventMap) {
2695 if (YAHOO.lang.hasOwnProperty(this.domEventMap, cls)) {
2696 var items = this.domEventMap[cls];
2698 if (! (items instanceof Array)) {
2702 for (var i=0;i<items.length;i++) {
2703 var item = items[i];
2704 elements = YAHOO.util.Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
2706 for (var c=0;c<elements.length;c++) {
2708 YAHOO.util.Event.addListener(el, item.event, item.handler, item.scope, item.correct );
2715 YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
2716 YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
2717 YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
2721 * Retrieves the Date object for the specified Calendar cell
2722 * @method getDateByCellId
2723 * @param {String} id The id of the cell
2724 * @return {Date} The Date object for the specified Calendar cell
2726 YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
2727 var date = this.getDateFieldsByCellId(id);
2728 return new Date(date[0],date[1]-1,date[2]);
2732 * Retrieves the Date object for the specified Calendar cell
2733 * @method getDateFieldsByCellId
2734 * @param {String} id The id of the cell
2735 * @return {Array} The array of Date fields for the specified Calendar cell
2737 YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
2738 id = id.toLowerCase().split("_cell")[1];
2739 id = parseInt(id, 10);
2740 return this.cellDates[id];
2743 // BEGIN BUILT-IN TABLE CELL RENDERERS
2746 * Renders a cell that falls before the minimum date or after the maximum date.
2748 * @method renderOutOfBoundsDate
2749 * @param {Date} workingDate The current working Date object being used to generate the calendar
2750 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2751 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2752 * should not be terminated
2754 YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
2755 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
2756 cell.innerHTML = workingDate.getDate();
2757 return YAHOO.widget.Calendar.STOP_RENDER;
2761 * Renders the row header for a week.
2762 * @method renderRowHeader
2763 * @param {Number} weekNum The week number of the current row
2764 * @param {Array} cell The current working HTML array
2766 YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
2767 html[html.length] = '<th class="calrowhead">' + weekNum + '</th>';
2772 * Renders the row footer for a week.
2773 * @method renderRowFooter
2774 * @param {Number} weekNum The week number of the current row
2775 * @param {Array} cell The current working HTML array
2777 YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
2778 html[html.length] = '<th class="calrowfoot">' + weekNum + '</th>';
2783 * Renders a single standard calendar cell in the calendar widget table.
2784 * All logic for determining how a standard default cell will be rendered is
2785 * encapsulated in this method, and must be accounted for when extending the
2787 * @method renderCellDefault
2788 * @param {Date} workingDate The current working Date object being used to generate the calendar
2789 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2791 YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
2792 cell.innerHTML = '<a href="#" class="' + this.Style.CSS_CELL_SELECTOR + '">' + this.buildDayLabel(workingDate) + "</a>";
2796 * Styles a selectable cell.
2797 * @method styleCellDefault
2798 * @param {Date} workingDate The current working Date object being used to generate the calendar
2799 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2801 YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
2802 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
2807 * Renders a single standard calendar cell using the CSS hightlight1 style
2808 * @method renderCellStyleHighlight1
2809 * @param {Date} workingDate The current working Date object being used to generate the calendar
2810 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2812 YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
2813 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
2817 * Renders a single standard calendar cell using the CSS hightlight2 style
2818 * @method renderCellStyleHighlight2
2819 * @param {Date} workingDate The current working Date object being used to generate the calendar
2820 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2822 YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
2823 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
2827 * Renders a single standard calendar cell using the CSS hightlight3 style
2828 * @method renderCellStyleHighlight3
2829 * @param {Date} workingDate The current working Date object being used to generate the calendar
2830 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2832 YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
2833 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
2837 * Renders a single standard calendar cell using the CSS hightlight4 style
2838 * @method renderCellStyleHighlight4
2839 * @param {Date} workingDate The current working Date object being used to generate the calendar
2840 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2842 YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
2843 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
2847 * Applies the default style used for rendering today's date to the current calendar cell
2848 * @method renderCellStyleToday
2849 * @param {Date} workingDate The current working Date object being used to generate the calendar
2850 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2852 YAHOO.widget.Calendar.prototype.renderCellStyleToday = function(workingDate, cell) {
2853 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
2857 * Applies the default style used for rendering selected dates to the current calendar cell
2858 * @method renderCellStyleSelected
2859 * @param {Date} workingDate The current working Date object being used to generate the calendar
2860 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2861 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2862 * should not be terminated
2864 YAHOO.widget.Calendar.prototype.renderCellStyleSelected = function(workingDate, cell) {
2865 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
2869 * Applies the default style used for rendering dates that are not a part of the current
2870 * month (preceding or trailing the cells for the current month)
2871 * @method renderCellNotThisMonth
2872 * @param {Date} workingDate The current working Date object being used to generate the calendar
2873 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2874 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2875 * should not be terminated
2877 YAHOO.widget.Calendar.prototype.renderCellNotThisMonth = function(workingDate, cell) {
2878 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
2879 cell.innerHTML=workingDate.getDate();
2880 return YAHOO.widget.Calendar.STOP_RENDER;
2884 * Renders the current calendar cell as a non-selectable "black-out" date using the default
2886 * @method renderBodyCellRestricted
2887 * @param {Date} workingDate The current working Date object being used to generate the calendar
2888 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2889 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2890 * should not be terminated
2892 YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
2893 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
2894 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
2895 cell.innerHTML=workingDate.getDate();
2896 return YAHOO.widget.Calendar.STOP_RENDER;
2899 // END BUILT-IN TABLE CELL RENDERERS
2901 // BEGIN MONTH NAVIGATION METHODS
2904 * Adds the designated number of months to the current calendar month, and sets the current
2905 * calendar page date to the new month.
2907 * @param {Number} count The number of months to add to the current calendar
2909 YAHOO.widget.Calendar.prototype.addMonths = function(count) {
2910 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
2911 this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
2912 this.resetRenderers();
2913 this.changePageEvent.fire();
2917 * Subtracts the designated number of months from the current calendar month, and sets the current
2918 * calendar page date to the new month.
2919 * @method subtractMonths
2920 * @param {Number} count The number of months to subtract from the current calendar
2922 YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
2923 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
2924 this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.MONTH, count));
2925 this.resetRenderers();
2926 this.changePageEvent.fire();
2930 * Adds the designated number of years to the current calendar, and sets the current
2931 * calendar page date to the new month.
2933 * @param {Number} count The number of years to add to the current calendar
2935 YAHOO.widget.Calendar.prototype.addYears = function(count) {
2936 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
2937 this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.add(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
2938 this.resetRenderers();
2939 this.changePageEvent.fire();
2943 * Subtcats the designated number of years from the current calendar, and sets the current
2944 * calendar page date to the new month.
2945 * @method subtractYears
2946 * @param {Number} count The number of years to subtract from the current calendar
2948 YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
2949 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
2950 this.cfg.setProperty(cfgPageDate, YAHOO.widget.DateMath.subtract(this.cfg.getProperty(cfgPageDate), YAHOO.widget.DateMath.YEAR, count));
2951 this.resetRenderers();
2952 this.changePageEvent.fire();
2956 * Navigates to the next month page in the calendar widget.
2959 YAHOO.widget.Calendar.prototype.nextMonth = function() {
2964 * Navigates to the previous month page in the calendar widget.
2965 * @method previousMonth
2967 YAHOO.widget.Calendar.prototype.previousMonth = function() {
2968 this.subtractMonths(1);
2972 * Navigates to the next year in the currently selected month in the calendar widget.
2975 YAHOO.widget.Calendar.prototype.nextYear = function() {
2980 * Navigates to the previous year in the currently selected month in the calendar widget.
2981 * @method previousYear
2983 YAHOO.widget.Calendar.prototype.previousYear = function() {
2984 this.subtractYears(1);
2987 // END MONTH NAVIGATION METHODS
2989 // BEGIN SELECTION METHODS
2992 * Resets the calendar widget to the originally selected month and year, and
2993 * sets the calendar to the initial selection(s).
2996 YAHOO.widget.Calendar.prototype.reset = function() {
2997 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
2998 this.cfg.resetProperty(defCfg.SELECTED.key);
2999 this.cfg.resetProperty(defCfg.PAGEDATE.key);
3000 this.resetEvent.fire();
3004 * Clears the selected dates in the current calendar widget and sets the calendar
3005 * to the current month and year.
3008 YAHOO.widget.Calendar.prototype.clear = function() {
3009 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
3010 this.cfg.setProperty(defCfg.SELECTED.key, []);
3011 this.cfg.setProperty(defCfg.PAGEDATE.key, new Date(this.today.getTime()));
3012 this.clearEvent.fire();
3016 * Selects a date or a collection of dates on the current calendar. This method, by default,
3017 * does not call the render method explicitly. Once selection has completed, render must be
3018 * called for the changes to be reflected visually.
3020 * Any dates which are OOB (out of bounds, not selectable) will not be selected and the array of
3021 * selected dates passed to the selectEvent will not contain OOB dates.
3023 * If all dates are OOB, the no state change will occur; beforeSelect and select events will not be fired.
3026 * @param {String/Date/Date[]} date The date string of dates to select in the current calendar. Valid formats are
3027 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
3028 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
3029 * This method can also take a JavaScript Date object or an array of Date objects.
3030 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3032 YAHOO.widget.Calendar.prototype.select = function(date) {
3034 var aToBeSelected = this._toFieldArray(date);
3036 // Filtered array of valid dates
3037 var validDates = [];
3039 var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
3041 for (var a=0; a < aToBeSelected.length; ++a) {
3042 var toSelect = aToBeSelected[a];
3044 if (!this.isDateOOB(this._toDate(toSelect))) {
3046 if (validDates.length === 0) {
3047 this.beforeSelectEvent.fire();
3048 selected = this.cfg.getProperty(cfgSelected);
3051 validDates.push(toSelect);
3053 if (this._indexOfSelectedFieldArray(toSelect) == -1) {
3054 selected[selected.length] = toSelect;
3060 if (validDates.length > 0) {
3062 this.parent.cfg.setProperty(cfgSelected, selected);
3064 this.cfg.setProperty(cfgSelected, selected);
3066 this.selectEvent.fire(validDates);
3069 return this.getSelectedDates();
3073 * Selects a date on the current calendar by referencing the index of the cell that should be selected.
3074 * This method is used to easily select a single cell (usually with a mouse click) without having to do
3075 * a full render. The selected style is applied to the cell directly.
3077 * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
3078 * or out of bounds cells), it will not be selected and in such a case beforeSelect and select events will not be fired.
3080 * @method selectCell
3081 * @param {Number} cellIndex The index of the cell to select in the current calendar.
3082 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3084 YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
3086 var cell = this.cells[cellIndex];
3087 var cellDate = this.cellDates[cellIndex];
3088 var dCellDate = this._toDate(cellDate);
3090 var selectable = YAHOO.util.Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
3094 this.beforeSelectEvent.fire();
3096 var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
3097 var selected = this.cfg.getProperty(cfgSelected);
3099 var selectDate = cellDate.concat();
3101 if (this._indexOfSelectedFieldArray(selectDate) == -1) {
3102 selected[selected.length] = selectDate;
3105 this.parent.cfg.setProperty(cfgSelected, selected);
3107 this.cfg.setProperty(cfgSelected, selected);
3109 this.renderCellStyleSelected(dCellDate,cell);
3110 this.selectEvent.fire([selectDate]);
3112 this.doCellMouseOut.call(cell, null, this);
3115 return this.getSelectedDates();
3119 * Deselects a date or a collection of dates on the current calendar. This method, by default,
3120 * does not call the render method explicitly. Once deselection has completed, render must be
3121 * called for the changes to be reflected visually.
3123 * The method will not attempt to deselect any dates which are OOB (out of bounds, and hence not selectable)
3124 * and the array of deselected dates passed to the deselectEvent will not contain any OOB dates.
3126 * If all dates are OOB, beforeDeselect and deselect events will not be fired.
3129 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
3130 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
3131 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
3132 * This method can also take a JavaScript Date object or an array of Date objects.
3133 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3135 YAHOO.widget.Calendar.prototype.deselect = function(date) {
3137 var aToBeDeselected = this._toFieldArray(date);
3139 var validDates = [];
3141 var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
3143 for (var a=0; a < aToBeDeselected.length; ++a) {
3144 var toDeselect = aToBeDeselected[a];
3146 if (!this.isDateOOB(this._toDate(toDeselect))) {
3148 if (validDates.length === 0) {
3149 this.beforeDeselectEvent.fire();
3150 selected = this.cfg.getProperty(cfgSelected);
3153 validDates.push(toDeselect);
3155 var index = this._indexOfSelectedFieldArray(toDeselect);
3157 selected.splice(index,1);
3163 if (validDates.length > 0) {
3165 this.parent.cfg.setProperty(cfgSelected, selected);
3167 this.cfg.setProperty(cfgSelected, selected);
3169 this.deselectEvent.fire(validDates);
3172 return this.getSelectedDates();
3176 * Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
3177 * This method is used to easily deselect a single cell (usually with a mouse click) without having to do
3178 * a full render. The selected style is removed from the cell directly.
3180 * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
3181 * or out of bounds cells), the method will not attempt to deselect it and in such a case, beforeDeselect and
3182 * deselect events will not be fired.
3184 * @method deselectCell
3185 * @param {Number} cellIndex The index of the cell to deselect in the current calendar.
3186 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3188 YAHOO.widget.Calendar.prototype.deselectCell = function(cellIndex) {
3189 var cell = this.cells[cellIndex];
3190 var cellDate = this.cellDates[cellIndex];
3191 var cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
3193 var selectable = YAHOO.util.Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
3197 this.beforeDeselectEvent.fire();
3199 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
3200 var selected = this.cfg.getProperty(defCfg.SELECTED.key);
3202 var dCellDate = this._toDate(cellDate);
3203 var selectDate = cellDate.concat();
3205 if (cellDateIndex > -1) {
3206 if (this.cfg.getProperty(defCfg.PAGEDATE.key).getMonth() == dCellDate.getMonth() &&
3207 this.cfg.getProperty(defCfg.PAGEDATE.key).getFullYear() == dCellDate.getFullYear()) {
3208 YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
3210 selected.splice(cellDateIndex, 1);
3214 this.parent.cfg.setProperty(defCfg.SELECTED.key, selected);
3216 this.cfg.setProperty(defCfg.SELECTED.key, selected);
3219 this.deselectEvent.fire(selectDate);
3222 return this.getSelectedDates();
3226 * Deselects all dates on the current calendar.
3227 * @method deselectAll
3228 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3229 * Assuming that this function executes properly, the return value should be an empty array.
3230 * However, the empty array is returned for the sake of being able to check the selection status
3233 YAHOO.widget.Calendar.prototype.deselectAll = function() {
3234 this.beforeDeselectEvent.fire();
3236 var cfgSelected = YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;
3238 var selected = this.cfg.getProperty(cfgSelected);
3239 var count = selected.length;
3240 var sel = selected.concat();
3243 this.parent.cfg.setProperty(cfgSelected, []);
3245 this.cfg.setProperty(cfgSelected, []);
3249 this.deselectEvent.fire(sel);
3252 return this.getSelectedDates();
3255 // END SELECTION METHODS
3257 // BEGIN TYPE CONVERSION METHODS
3260 * Converts a date (either a JavaScript Date object, or a date string) to the internal data structure
3261 * used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]].
3262 * @method _toFieldArray
3264 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
3265 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
3266 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
3267 * This method can also take a JavaScript Date object or an array of Date objects.
3268 * @return {Array[](Number[])} Array of date field arrays
3270 YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
3271 var returnDate = [];
3273 if (date instanceof Date) {
3274 returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
3275 } else if (YAHOO.lang.isString(date)) {
3276 returnDate = this._parseDates(date);
3277 } else if (YAHOO.lang.isArray(date)) {
3278 for (var i=0;i<date.length;++i) {
3280 returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
3288 * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
3291 * @param {Number[]} dateFieldArray The date field array to convert to a JavaScript Date.
3292 * @return {Date} JavaScript Date object representing the date field array
3294 YAHOO.widget.Calendar.prototype._toDate = function(dateFieldArray) {
3295 if (dateFieldArray instanceof Date) {
3296 return dateFieldArray;
3298 return new Date(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
3302 // END TYPE CONVERSION METHODS
3304 // BEGIN UTILITY METHODS
3307 * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
3308 * @method _fieldArraysAreEqual
3310 * @param {Number[]} array1 The first date field array to compare
3311 * @param {Number[]} array2 The first date field array to compare
3312 * @return {Boolean} The boolean that represents the equality of the two arrays
3314 YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
3317 if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
3325 * Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
3326 * @method _indexOfSelectedFieldArray
3328 * @param {Number[]} find The date field array to search for
3329 * @return {Number} The index of the date field array within the collection of selected dates.
3330 * -1 will be returned if the date is not found.
3332 YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
3334 var seldates = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);
3336 for (var s=0;s<seldates.length;++s) {
3337 var sArray = seldates[s];
3338 if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
3348 * Determines whether a given date is OOM (out of month).
3350 * @param {Date} date The JavaScript Date object for which to check the OOM status
3351 * @return {Boolean} true if the date is OOM
3353 YAHOO.widget.Calendar.prototype.isDateOOM = function(date) {
3354 return (date.getMonth() != this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key).getMonth());
3358 * Determines whether a given date is OOB (out of bounds - less than the mindate or more than the maxdate).
3361 * @param {Date} date The JavaScript Date object for which to check the OOB status
3362 * @return {Boolean} true if the date is OOB
3364 YAHOO.widget.Calendar.prototype.isDateOOB = function(date) {
3365 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
3367 var minDate = this.cfg.getProperty(defCfg.MINDATE.key);
3368 var maxDate = this.cfg.getProperty(defCfg.MAXDATE.key);
3369 var dm = YAHOO.widget.DateMath;
3372 minDate = dm.clearTime(minDate);
3375 maxDate = dm.clearTime(maxDate);
3378 var clearedDate = new Date(date.getTime());
3379 clearedDate = dm.clearTime(clearedDate);
3381 return ((minDate && clearedDate.getTime() < minDate.getTime()) || (maxDate && clearedDate.getTime() > maxDate.getTime()));
3385 * Parses a pagedate configuration property value. The value can either be specified as a string of form "mm/yyyy" or a Date object
3386 * 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
3387 * @method _parsePageDate
3389 * @param {Date|String} date Pagedate value which needs to be parsed
3390 * @return {Date} The Date object representing the pagedate
3392 YAHOO.widget.Calendar.prototype._parsePageDate = function(date) {
3395 var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
3398 if (date instanceof Date) {
3399 parsedDate = YAHOO.widget.DateMath.findMonthStart(date);
3401 var month, year, aMonthYear;
3402 aMonthYear = date.split(this.cfg.getProperty(defCfg.DATE_FIELD_DELIMITER.key));
3403 month = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_MONTH_POSITION.key)-1], 10)-1;
3404 year = parseInt(aMonthYear[this.cfg.getProperty(defCfg.MY_YEAR_POSITION.key)-1], 10);
3406 parsedDate = new Date(year, month, 1);
3409 parsedDate = new Date(this.today.getFullYear(), this.today.getMonth(), 1);
3414 // END UTILITY METHODS
3416 // BEGIN EVENT HANDLERS
3419 * Event executed before a date is selected in the calendar widget.
3420 * @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
3422 YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
3423 if (this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MULTI_SELECT.key) === false) {
3425 this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
3426 this.parent.deselectAll();
3428 this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
3435 * Event executed when a date is selected in the calendar widget.
3436 * @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] ]
3437 * @deprecated Event handlers for this event should be susbcribed to selectEvent.
3439 YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };
3442 * Event executed before a date is deselected in the calendar widget.
3443 * @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
3445 YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };
3448 * Event executed when a date is deselected in the calendar widget.
3449 * @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] ]
3450 * @deprecated Event handlers for this event should be susbcribed to deselectEvent.
3452 YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };
3455 * Event executed when the user navigates to a different calendar page.
3456 * @deprecated Event handlers for this event should be susbcribed to changePageEvent.
3458 YAHOO.widget.Calendar.prototype.onChangePage = function() {
3463 * Event executed when the calendar widget is rendered.
3464 * @deprecated Event handlers for this event should be susbcribed to renderEvent.
3466 YAHOO.widget.Calendar.prototype.onRender = function() { };
3469 * Event executed when the calendar widget is reset to its original state.
3470 * @deprecated Event handlers for this event should be susbcribed to resetEvemt.
3472 YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };
3475 * Event executed when the calendar widget is completely cleared to the current month with no selections.
3476 * @deprecated Event handlers for this event should be susbcribed to clearEvent.
3478 YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };
3481 * Validates the calendar widget. This method has no default implementation
3482 * and must be extended by subclassing the widget.
3483 * @return Should return true if the widget validates, and false if
3487 YAHOO.widget.Calendar.prototype.validate = function() { return true; };
3489 // END EVENT HANDLERS
3491 // BEGIN DATE PARSE METHODS
3494 * Converts a date string to a date field array
3496 * @param {String} sDate Date string. Valid formats are mm/dd and mm/dd/yyyy.
3497 * @return A date field array representing the string passed to the method
3498 * @type Array[](Number[])
3500 YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
3501 var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
3504 if (aDate.length == 2) {
3505 rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
3506 rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
3508 rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
3509 rArray.type = YAHOO.widget.Calendar.DATE;
3512 for (var i=0;i<rArray.length;i++) {
3513 rArray[i] = parseInt(rArray[i], 10);
3520 * Converts a multi or single-date string to an array of date field arrays
3522 * @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
3523 * @return An array of date field arrays
3524 * @type Array[](Number[])
3526 YAHOO.widget.Calendar.prototype._parseDates = function(sDates) {
3529 var aDates = sDates.split(this.Locale.DATE_DELIMITER);
3531 for (var d=0;d<aDates.length;++d) {
3532 var sDate = aDates[d];
3534 if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
3536 var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER);
3538 var dateStart = this._parseDate(aRange[0]);
3539 var dateEnd = this._parseDate(aRange[1]);
3541 var fullRange = this._parseRange(dateStart, dateEnd);
3542 aReturn = aReturn.concat(fullRange);
3544 // This is not a range
3545 var aDate = this._parseDate(sDate);
3546 aReturn.push(aDate);
3553 * Converts a date range to the full list of included dates
3555 * @param {Number[]} startDate Date field array representing the first date in the range
3556 * @param {Number[]} endDate Date field array representing the last date in the range
3557 * @return An array of date field arrays
3558 * @type Array[](Number[])
3560 YAHOO.widget.Calendar.prototype._parseRange = function(startDate, endDate) {
3561 var dStart = new Date(startDate[0],startDate[1]-1,startDate[2]);
3562 var dCurrent = YAHOO.widget.DateMath.add(new Date(startDate[0],startDate[1]-1,startDate[2]),YAHOO.widget.DateMath.DAY,1);
3563 var dEnd = new Date(endDate[0], endDate[1]-1, endDate[2]);
3566 results.push(startDate);
3567 while (dCurrent.getTime() <= dEnd.getTime()) {
3568 results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
3569 dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
3574 // END DATE PARSE METHODS
3576 // BEGIN RENDERER METHODS
3579 * Resets the render stack of the current calendar to its original pre-render value.
3581 YAHOO.widget.Calendar.prototype.resetRenderers = function() {
3582 this.renderStack = this._renderStack.concat();
3586 * Clears the inner HTML, CSS class and style information from the specified cell.
3587 * @method clearElement
3588 * @param {HTMLTableCellElement} The cell to clear
3590 YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
3591 cell.innerHTML = " ";
3596 * Adds a renderer to the render stack. The function reference passed to this method will be executed
3597 * when a date cell matches the conditions specified in the date string for this renderer.
3598 * @method addRenderer
3599 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
3600 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
3601 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
3603 YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
3604 var aDates = this._parseDates(sDates);
3605 for (var i=0;i<aDates.length;++i) {
3606 var aDate = aDates[i];
3608 if (aDate.length == 2) { // this is either a range or a month/day combo
3609 if (aDate[0] instanceof Array) { // this is a range
3610 this._addRenderer(YAHOO.widget.Calendar.RANGE,aDate,fnRender);
3611 } else { // this is a month/day combo
3612 this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,aDate,fnRender);
3614 } else if (aDate.length == 3) {
3615 this._addRenderer(YAHOO.widget.Calendar.DATE,aDate,fnRender);
3621 * The private method used for adding cell renderers to the local render stack.
3622 * This method is called by other methods that set the renderer type prior to the method call.
3623 * @method _addRenderer
3625 * @param {String} type The type string that indicates the type of date renderer being added.
3626 * Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
3627 * YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
3628 * @param {Array} aDates An array of dates used to construct the renderer. The format varies based
3629 * on the renderer type
3630 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
3632 YAHOO.widget.Calendar.prototype._addRenderer = function(type, aDates, fnRender) {
3633 var add = [type,aDates,fnRender];
3634 this.renderStack.unshift(add);
3635 this._renderStack = this.renderStack.concat();
3639 * Adds a month to the render stack. The function reference passed to this method will be executed
3640 * when a date cell matches the month passed to this method.
3641 * @method addMonthRenderer
3642 * @param {Number} month The month (1-12) to associate with this renderer
3643 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
3645 YAHOO.widget.Calendar.prototype.addMonthRenderer = function(month, fnRender) {
3646 this._addRenderer(YAHOO.widget.Calendar.MONTH,[month],fnRender);
3650 * Adds a weekday to the render stack. The function reference passed to this method will be executed
3651 * when a date cell matches the weekday passed to this method.
3652 * @method addWeekdayRenderer
3653 * @param {Number} weekday The weekday (0-6) to associate with this renderer
3654 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
3656 YAHOO.widget.Calendar.prototype.addWeekdayRenderer = function(weekday, fnRender) {
3657 this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
3660 // END RENDERER METHODS
3662 // BEGIN CSS METHODS
3665 * Removes all styles from all body cells in the current calendar table.
3666 * @method clearAllBodyCellStyles
3667 * @param {style} The CSS class name to remove from all calendar body cells
3669 YAHOO.widget.Calendar.prototype.clearAllBodyCellStyles = function(style) {
3670 for (var c=0;c<this.cells.length;++c) {
3671 YAHOO.util.Dom.removeClass(this.cells[c],style);
3677 // BEGIN GETTER/SETTER METHODS
3679 * Sets the calendar's month explicitly
3681 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
3683 YAHOO.widget.Calendar.prototype.setMonth = function(month) {
3684 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
3685 var current = this.cfg.getProperty(cfgPageDate);
3686 current.setMonth(parseInt(month, 10));
3687 this.cfg.setProperty(cfgPageDate, current);
3691 * Sets the calendar's year explicitly.
3693 * @param {Number} year The numeric 4-digit year
3695 YAHOO.widget.Calendar.prototype.setYear = function(year) {
3696 var cfgPageDate = YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;
3697 var current = this.cfg.getProperty(cfgPageDate);
3698 current.setFullYear(parseInt(year, 10));
3699 this.cfg.setProperty(cfgPageDate, current);
3703 * Gets the list of currently selected dates from the calendar.
3704 * @method getSelectedDates
3705 * @return {Date[]} An array of currently selected JavaScript Date objects.
3707 YAHOO.widget.Calendar.prototype.getSelectedDates = function() {
3708 var returnDates = [];
3709 var selected = this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);
3711 for (var d=0;d<selected.length;++d) {
3712 var dateArray = selected[d];
3714 var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
3715 returnDates.push(date);
3718 returnDates.sort( function(a,b) { return a-b; } );
3722 /// END GETTER/SETTER METHODS ///
3725 * Hides the Calendar's outer container from view.
3728 YAHOO.widget.Calendar.prototype.hide = function() {
3729 this.oDomContainer.style.display = "none";
3733 * Shows the Calendar's outer container.
3736 YAHOO.widget.Calendar.prototype.show = function() {
3737 this.oDomContainer.style.display = "block";
3741 * Returns a string representing the current browser.
3742 * @deprecated As of 2.3.0, environment information is available in YAHOO.env.ua
3747 YAHOO.widget.Calendar.prototype.browser = function() {
3748 var ua = navigator.userAgent.toLowerCase();
3749 if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
3751 } else if (ua.indexOf('msie 7')!=-1) { // IE7
3753 } else if (ua.indexOf('msie') !=-1) { // IE
3755 } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
3757 } else if (ua.indexOf('gecko') != -1) { // Gecko
3764 * Returns a string representation of the object.
3766 * @return {String} A string representation of the Calendar object.
3768 YAHOO.widget.Calendar.prototype.toString = function() {
3769 return "Calendar " + this.id;
3773 * @namespace YAHOO.widget
3774 * @class Calendar_Core
3775 * @extends YAHOO.widget.Calendar
3776 * @deprecated The old Calendar_Core class is no longer necessary.
3778 YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
3780 YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
3783 * YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. This class facilitates
3784 * the ability to have multi-page calendar views that share a single dataset and are
3785 * dependent on each other.
3787 * The calendar group instance will refer to each of its elements using a 0-based index.
3788 * For example, to construct the placeholder for a calendar group widget with id "cal1" and
3789 * containerId of "cal1Container", the markup would be as follows:
3791 * <div id="cal1Container_0"></div>
3792 * <div id="cal1Container_1"></div>
3794 * The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
3795 * @namespace YAHOO.widget
3796 * @class CalendarGroup
3798 * @param {String} id The id of the table element that will represent the calendar widget
3799 * @param {String} containerId The id of the container div element that will wrap the calendar table
3800 * @param {Object} config The configuration object containing the Calendar's arguments
3802 YAHOO.widget.CalendarGroup = function(id, containerId, config) {
3803 if (arguments.length > 0) {
3804 this.init(id, containerId, config);
3809 * Initializes the calendar group. All subclasses must call this method in order for the
3810 * group to be initialized properly.
3812 * @param {String} id The id of the table element that will represent the calendar widget
3813 * @param {String} containerId The id of the container div element that will wrap the calendar table
3814 * @param {Object} config The configuration object containing the Calendar's arguments
3816 YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
3821 * The collection of Calendar pages contained within the CalendarGroup
3823 * @type YAHOO.widget.Calendar[]
3828 * The unique id associated with the CalendarGroup
3835 * The unique id associated with the CalendarGroup container
3836 * @property containerId
3839 this.containerId = containerId;
3842 * The outer containing element for the CalendarGroup
3843 * @property oDomContainer
3846 this.oDomContainer = document.getElementById(containerId);
3848 YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_CONTAINER);
3849 YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_MULTI_UP);
3852 * The Config object used to hold the configuration variables for the CalendarGroup
3854 * @type YAHOO.util.Config
3856 this.cfg = new YAHOO.util.Config(this);
3859 * The local object which contains the CalendarGroup's options
3866 * The local object which contains the CalendarGroup's locale settings
3875 this.cfg.applyConfig(config, true);
3878 this.cfg.fireQueue();
3880 // OPERA HACK FOR MISWRAPPED FLOATS
3881 if (YAHOO.env.ua.opera){
3882 this.renderEvent.subscribe(this._fixWidth, this, true);
3887 YAHOO.widget.CalendarGroup.prototype.setupConfig = function() {
3889 var defCfg = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG;
3892 * The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
3897 this.cfg.addProperty(defCfg.PAGES.key, { value:defCfg.PAGES.value, validator:this.cfg.checkNumber, handler:this.configPages } );
3900 * The month/year representing the current visible Calendar date (mm/yyyy)
3903 * @default today's date
3905 this.cfg.addProperty(defCfg.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
3908 * The date or range of dates representing the current Calendar selection
3913 this.cfg.addProperty(defCfg.SELECTED.key, { value:[], handler:this.configSelected } );
3916 * The title to display above the CalendarGroup's month header
3921 this.cfg.addProperty(defCfg.TITLE.key, { value:defCfg.TITLE.value, handler:this.configTitle } );
3924 * Whether or not a close button should be displayed for this CalendarGroup
3929 this.cfg.addProperty(defCfg.CLOSE.key, { value:defCfg.CLOSE.value, handler:this.configClose } );
3932 * 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.
3933 * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
3934 * enabled if required.
3938 * @default true for IE6 and below, false for all other browsers
3940 this.cfg.addProperty(defCfg.IFRAME.key, { value:defCfg.IFRAME.value, handler:this.configIframe, validator:this.cfg.checkBoolean } );
3943 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
3948 this.cfg.addProperty(defCfg.MINDATE.key, { value:defCfg.MINDATE.value, handler:this.delegateConfig } );
3951 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
3956 this.cfg.addProperty(defCfg.MAXDATE.key, { value:defCfg.MAXDATE.value, handler:this.delegateConfig } );
3958 // Options properties
3961 * True if the Calendar should allow multiple selections. False by default.
3962 * @config MULTI_SELECT
3966 this.cfg.addProperty(defCfg.MULTI_SELECT.key, { value:defCfg.MULTI_SELECT.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3969 * The weekday the week begins on. Default is 0 (Sunday).
3970 * @config START_WEEKDAY
3974 this.cfg.addProperty(defCfg.START_WEEKDAY.key, { value:defCfg.START_WEEKDAY.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3977 * True if the Calendar should show weekday labels. True by default.
3978 * @config SHOW_WEEKDAYS
3982 this.cfg.addProperty(defCfg.SHOW_WEEKDAYS.key, { value:defCfg.SHOW_WEEKDAYS.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3985 * True if the Calendar should show week row headers. False by default.
3986 * @config SHOW_WEEK_HEADER
3990 this.cfg.addProperty(defCfg.SHOW_WEEK_HEADER.key,{ value:defCfg.SHOW_WEEK_HEADER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3993 * True if the Calendar should show week row footers. False by default.
3994 * @config SHOW_WEEK_FOOTER
3998 this.cfg.addProperty(defCfg.SHOW_WEEK_FOOTER.key,{ value:defCfg.SHOW_WEEK_FOOTER.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
4001 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
4002 * @config HIDE_BLANK_WEEKS
4006 this.cfg.addProperty(defCfg.HIDE_BLANK_WEEKS.key,{ value:defCfg.HIDE_BLANK_WEEKS.value, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
4009 * The image that should be used for the left navigation arrow.
4010 * @config NAV_ARROW_LEFT
4012 * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
4015 this.cfg.addProperty(defCfg.NAV_ARROW_LEFT.key, { value:defCfg.NAV_ARROW_LEFT.value, handler:this.delegateConfig } );
4018 * The image that should be used for the right navigation arrow.
4019 * @config NAV_ARROW_RIGHT
4021 * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
4024 this.cfg.addProperty(defCfg.NAV_ARROW_RIGHT.key, { value:defCfg.NAV_ARROW_RIGHT.value, handler:this.delegateConfig } );
4026 // Locale properties
4029 * The short month labels for the current locale.
4030 * @config MONTHS_SHORT
4032 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
4034 this.cfg.addProperty(defCfg.MONTHS_SHORT.key, { value:defCfg.MONTHS_SHORT.value, handler:this.delegateConfig } );
4037 * The long month labels for the current locale.
4038 * @config MONTHS_LONG
4040 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
4042 this.cfg.addProperty(defCfg.MONTHS_LONG.key, { value:defCfg.MONTHS_LONG.value, handler:this.delegateConfig } );
4045 * The 1-character weekday labels for the current locale.
4046 * @config WEEKDAYS_1CHAR
4048 * @default ["S", "M", "T", "W", "T", "F", "S"]
4050 this.cfg.addProperty(defCfg.WEEKDAYS_1CHAR.key, { value:defCfg.WEEKDAYS_1CHAR.value, handler:this.delegateConfig } );
4053 * The short weekday labels for the current locale.
4054 * @config WEEKDAYS_SHORT
4056 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
4058 this.cfg.addProperty(defCfg.WEEKDAYS_SHORT.key, { value:defCfg.WEEKDAYS_SHORT.value, handler:this.delegateConfig } );
4061 * The medium weekday labels for the current locale.
4062 * @config WEEKDAYS_MEDIUM
4064 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
4066 this.cfg.addProperty(defCfg.WEEKDAYS_MEDIUM.key, { value:defCfg.WEEKDAYS_MEDIUM.value, handler:this.delegateConfig } );
4069 * The long weekday labels for the current locale.
4070 * @config WEEKDAYS_LONG
4072 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
4074 this.cfg.addProperty(defCfg.WEEKDAYS_LONG.key, { value:defCfg.WEEKDAYS_LONG.value, handler:this.delegateConfig } );
4077 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
4078 * @config LOCALE_MONTHS
4082 this.cfg.addProperty(defCfg.LOCALE_MONTHS.key, { value:defCfg.LOCALE_MONTHS.value, handler:this.delegateConfig } );
4085 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
4086 * @config LOCALE_WEEKDAYS
4090 this.cfg.addProperty(defCfg.LOCALE_WEEKDAYS.key, { value:defCfg.LOCALE_WEEKDAYS.value, handler:this.delegateConfig } );
4093 * The value used to delimit individual dates in a date string passed to various Calendar functions.
4094 * @config DATE_DELIMITER
4098 this.cfg.addProperty(defCfg.DATE_DELIMITER.key, { value:defCfg.DATE_DELIMITER.value, handler:this.delegateConfig } );
4101 * The value used to delimit date fields in a date string passed to various Calendar functions.
4102 * @config DATE_FIELD_DELIMITER
4106 this.cfg.addProperty(defCfg.DATE_FIELD_DELIMITER.key,{ value:defCfg.DATE_FIELD_DELIMITER.value, handler:this.delegateConfig } );
4109 * The value used to delimit date ranges in a date string passed to various Calendar functions.
4110 * @config DATE_RANGE_DELIMITER
4114 this.cfg.addProperty(defCfg.DATE_RANGE_DELIMITER.key,{ value:defCfg.DATE_RANGE_DELIMITER.value, handler:this.delegateConfig } );
4117 * The position of the month in a month/year date string
4118 * @config MY_MONTH_POSITION
4122 this.cfg.addProperty(defCfg.MY_MONTH_POSITION.key, { value:defCfg.MY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4125 * The position of the year in a month/year date string
4126 * @config MY_YEAR_POSITION
4130 this.cfg.addProperty(defCfg.MY_YEAR_POSITION.key, { value:defCfg.MY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4133 * The position of the month in a month/day date string
4134 * @config MD_MONTH_POSITION
4138 this.cfg.addProperty(defCfg.MD_MONTH_POSITION.key, { value:defCfg.MD_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4141 * The position of the day in a month/year date string
4142 * @config MD_DAY_POSITION
4146 this.cfg.addProperty(defCfg.MD_DAY_POSITION.key, { value:defCfg.MD_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4149 * The position of the month in a month/day/year date string
4150 * @config MDY_MONTH_POSITION
4154 this.cfg.addProperty(defCfg.MDY_MONTH_POSITION.key, { value:defCfg.MDY_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4157 * The position of the day in a month/day/year date string
4158 * @config MDY_DAY_POSITION
4162 this.cfg.addProperty(defCfg.MDY_DAY_POSITION.key, { value:defCfg.MDY_DAY_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4165 * The position of the year in a month/day/year date string
4166 * @config MDY_YEAR_POSITION
4170 this.cfg.addProperty(defCfg.MDY_YEAR_POSITION.key, { value:defCfg.MDY_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4173 * The position of the month in the month year label string used as the Calendar header
4174 * @config MY_LABEL_MONTH_POSITION
4178 this.cfg.addProperty(defCfg.MY_LABEL_MONTH_POSITION.key, { value:defCfg.MY_LABEL_MONTH_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4181 * The position of the year in the month year label string used as the Calendar header
4182 * @config MY_LABEL_YEAR_POSITION
4186 this.cfg.addProperty(defCfg.MY_LABEL_YEAR_POSITION.key, { value:defCfg.MY_LABEL_YEAR_POSITION.value, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
4189 * The suffix used after the month when rendering the Calendar header
4190 * @config MY_LABEL_MONTH_SUFFIX
4194 this.cfg.addProperty(defCfg.MY_LABEL_MONTH_SUFFIX.key, { value:defCfg.MY_LABEL_MONTH_SUFFIX.value, handler:this.delegateConfig } );
4197 * The suffix used after the year when rendering the Calendar header
4198 * @config MY_LABEL_YEAR_SUFFIX
4202 this.cfg.addProperty(defCfg.MY_LABEL_YEAR_SUFFIX.key, { value:defCfg.MY_LABEL_YEAR_SUFFIX.value, handler:this.delegateConfig } );
4206 * Initializes CalendarGroup's built-in CustomEvents
4207 * @method initEvents
4209 YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
4211 var strEvent = "Event";
4214 * Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
4217 * @param {Function} fn The function to subscribe to this CustomEvent
4218 * @param {Object} obj The CustomEvent's scope object
4219 * @param {Boolean} bOverride Whether or not to apply scope correction
4221 var sub = function(fn, obj, bOverride) {
4222 for (var p=0;p<me.pages.length;++p) {
4223 var cal = me.pages[p];
4224 cal[this.type + strEvent].subscribe(fn, obj, bOverride);
4229 * Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
4232 * @param {Function} fn The function to subscribe to this CustomEvent
4233 * @param {Object} obj The CustomEvent's scope object
4235 var unsub = function(fn, obj) {
4236 for (var p=0;p<me.pages.length;++p) {
4237 var cal = me.pages[p];
4238 cal[this.type + strEvent].unsubscribe(fn, obj);
4242 var defEvents = YAHOO.widget.Calendar._EVENT_TYPES;
4245 * Fired before a selection is made
4246 * @event beforeSelectEvent
4248 this.beforeSelectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_SELECT);
4249 this.beforeSelectEvent.subscribe = sub; this.beforeSelectEvent.unsubscribe = unsub;
4252 * Fired when a selection is made
4253 * @event selectEvent
4254 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
4256 this.selectEvent = new YAHOO.util.CustomEvent(defEvents.SELECT);
4257 this.selectEvent.subscribe = sub; this.selectEvent.unsubscribe = unsub;
4260 * Fired before a selection is made
4261 * @event beforeDeselectEvent
4263 this.beforeDeselectEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_DESELECT);
4264 this.beforeDeselectEvent.subscribe = sub; this.beforeDeselectEvent.unsubscribe = unsub;
4267 * Fired when a selection is made
4268 * @event deselectEvent
4269 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
4271 this.deselectEvent = new YAHOO.util.CustomEvent(defEvents.DESELECT);
4272 this.deselectEvent.subscribe = sub; this.deselectEvent.unsubscribe = unsub;
4275 * Fired when the Calendar page is changed
4276 * @event changePageEvent
4278 this.changePageEvent = new YAHOO.util.CustomEvent(defEvents.CHANGE_PAGE);
4279 this.changePageEvent.subscribe = sub; this.changePageEvent.unsubscribe = unsub;
4282 * Fired before the Calendar is rendered
4283 * @event beforeRenderEvent
4285 this.beforeRenderEvent = new YAHOO.util.CustomEvent(defEvents.BEFORE_RENDER);
4286 this.beforeRenderEvent.subscribe = sub; this.beforeRenderEvent.unsubscribe = unsub;
4289 * Fired when the Calendar is rendered
4290 * @event renderEvent
4292 this.renderEvent = new YAHOO.util.CustomEvent(defEvents.RENDER);
4293 this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;
4296 * Fired when the Calendar is reset
4299 this.resetEvent = new YAHOO.util.CustomEvent(defEvents.RESET);
4300 this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;
4303 * Fired when the Calendar is cleared
4306 this.clearEvent = new YAHOO.util.CustomEvent(defEvents.CLEAR);
4307 this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;
4312 * The default Config handler for the "pages" property
4313 * @method configPages
4314 * @param {String} type The CustomEvent type (usually the property name)
4315 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
4316 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
4318 YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
4319 var pageCount = args[0];
4321 var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
4323 // Define literals outside loop
4325 var groupCalClass = "groupcal";
4327 var firstClass = "first-of-type";
4328 var lastClass = "last-of-type";
4330 for (var p=0;p<pageCount;++p) {
4331 var calId = this.id + sep + p;
4332 var calContainerId = this.containerId + sep + p;
4334 var childConfig = this.cfg.getConfig();
4335 childConfig.close = false;
4336 childConfig.title = false;
4338 var cal = this.constructChild(calId, calContainerId, childConfig);
4339 var caldate = cal.cfg.getProperty(cfgPageDate);
4340 this._setMonthOnDate(caldate, caldate.getMonth() + p);
4341 cal.cfg.setProperty(cfgPageDate, caldate);
4343 YAHOO.util.Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
4344 YAHOO.util.Dom.addClass(cal.oDomContainer, groupCalClass);
4347 YAHOO.util.Dom.addClass(cal.oDomContainer, firstClass);
4350 if (p==(pageCount-1)) {
4351 YAHOO.util.Dom.addClass(cal.oDomContainer, lastClass);
4357 this.pages[this.pages.length] = cal;
4362 * The default Config handler for the "pagedate" property
4363 * @method configPageDate
4364 * @param {String} type The CustomEvent type (usually the property name)
4365 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
4366 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
4368 YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
4372 var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
4374 for (var p=0;p<this.pages.length;++p) {
4375 var cal = this.pages[p];
4377 firstPageDate = cal._parsePageDate(val);
4378 cal.cfg.setProperty(cfgPageDate, firstPageDate);
4380 var pageDate = new Date(firstPageDate);
4381 this._setMonthOnDate(pageDate, pageDate.getMonth() + p);
4382 cal.cfg.setProperty(cfgPageDate, pageDate);
4388 * The default Config handler for the CalendarGroup "selected" property
4389 * @method configSelected
4390 * @param {String} type The CustomEvent type (usually the property name)
4391 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
4392 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
4394 YAHOO.widget.CalendarGroup.prototype.configSelected = function(type, args, obj) {
4395 var cfgSelected = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key;
4396 this.delegateConfig(type, args, obj);
4397 var selected = (this.pages.length > 0) ? this.pages[0].cfg.getProperty(cfgSelected) : [];
4398 this.cfg.setProperty(cfgSelected, selected, true);
4403 * Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
4404 * @method delegateConfig
4405 * @param {String} type The CustomEvent type (usually the property name)
4406 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
4407 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
4409 YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
4413 for (var p=0;p<this.pages.length;p++) {
4414 cal = this.pages[p];
4415 cal.cfg.setProperty(type, val);
4421 * Adds a function to all child Calendars within this CalendarGroup.
4422 * @method setChildFunction
4423 * @param {String} fnName The name of the function
4424 * @param {Function} fn The function to apply to each Calendar page object
4426 YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
4427 var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
4429 for (var p=0;p<pageCount;++p) {
4430 this.pages[p][fnName] = fn;
4435 * Calls a function within all child Calendars within this CalendarGroup.
4436 * @method callChildFunction
4437 * @param {String} fnName The name of the function
4438 * @param {Array} args The arguments to pass to the function
4440 YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
4441 var pageCount = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);
4443 for (var p=0;p<pageCount;++p) {
4444 var page = this.pages[p];
4446 var fn = page[fnName];
4447 fn.call(page, args);
4453 * Constructs a child calendar. This method can be overridden if a subclassed version of the default
4454 * calendar is to be used.
4455 * @method constructChild
4456 * @param {String} id The id of the table element that will represent the calendar widget
4457 * @param {String} containerId The id of the container div element that will wrap the calendar table
4458 * @param {Object} config The configuration object containing the Calendar's arguments
4459 * @return {YAHOO.widget.Calendar} The YAHOO.widget.Calendar instance that is constructed
4461 YAHOO.widget.CalendarGroup.prototype.constructChild = function(id,containerId,config) {
4462 var container = document.getElementById(containerId);
4464 container = document.createElement("div");
4465 container.id = containerId;
4466 this.oDomContainer.appendChild(container);
4468 return new YAHOO.widget.Calendar(id,containerId,config);
4473 * Sets the calendar group's month explicitly. This month will be set into the first
4474 * page of the multi-page calendar, and all other months will be iterated appropriately.
4476 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
4478 YAHOO.widget.CalendarGroup.prototype.setMonth = function(month) {
4479 month = parseInt(month, 10);
4482 var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
4484 for (var p=0; p<this.pages.length; ++p) {
4485 var cal = this.pages[p];
4486 var pageDate = cal.cfg.getProperty(cfgPageDate);
4488 currYear = pageDate.getFullYear();
4490 pageDate.setYear(currYear);
4492 this._setMonthOnDate(pageDate, month+p);
4493 cal.cfg.setProperty(cfgPageDate, pageDate);
4498 * Sets the calendar group's year explicitly. This year will be set into the first
4499 * page of the multi-page calendar, and all other months will be iterated appropriately.
4501 * @param {Number} year The numeric 4-digit year
4503 YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
4505 var cfgPageDate = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;
4507 year = parseInt(year, 10);
4508 for (var p=0;p<this.pages.length;++p) {
4509 var cal = this.pages[p];
4510 var pageDate = cal.cfg.getProperty(cfgPageDate);
4512 if ((pageDate.getMonth()+1) == 1 && p>0) {
4519 * Calls the render function of all child calendars within the group.
4522 YAHOO.widget.CalendarGroup.prototype.render = function() {
4523 this.renderHeader();
4524 for (var p=0;p<this.pages.length;++p) {
4525 var cal = this.pages[p];
4528 this.renderFooter();
4532 * Selects a date or a collection of dates on the current calendar. This method, by default,
4533 * does not call the render method explicitly. Once selection has completed, render must be
4534 * called for the changes to be reflected visually.
4536 * @param {String/Date/Date[]} date The date string of dates to select in the current calendar. Valid formats are
4537 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
4538 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
4539 * This method can also take a JavaScript Date object or an array of Date objects.
4540 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
4542 YAHOO.widget.CalendarGroup.prototype.select = function(date) {
4543 for (var p=0;p<this.pages.length;++p) {
4544 var cal = this.pages[p];
4547 return this.getSelectedDates();
4551 * 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.
4552 * The value of the MULTI_SELECT Configuration attribute will determine the set of dates which get selected.
4554 * <li>If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.</li>
4555 * <li>If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.</li>
4557 * @method selectCell
4558 * @param {Number} cellIndex The index of the cell to be selected.
4559 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
4561 YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
4562 for (var p=0;p<this.pages.length;++p) {
4563 var cal = this.pages[p];
4564 cal.selectCell(cellIndex);
4566 return this.getSelectedDates();
4570 * Deselects a date or a collection of dates on the current calendar. This method, by default,
4571 * does not call the render method explicitly. Once deselection has completed, render must be
4572 * called for the changes to be reflected visually.
4574 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
4575 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
4576 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
4577 * This method can also take a JavaScript Date object or an array of Date objects.
4578 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
4580 YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
4581 for (var p=0;p<this.pages.length;++p) {
4582 var cal = this.pages[p];
4585 return this.getSelectedDates();
4589 * Deselects all dates on the current calendar.
4590 * @method deselectAll
4591 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
4592 * Assuming that this function executes properly, the return value should be an empty array.
4593 * However, the empty array is returned for the sake of being able to check the selection status
4596 YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
4597 for (var p=0;p<this.pages.length;++p) {
4598 var cal = this.pages[p];
4601 return this.getSelectedDates();
4605 * 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.
4606 * deselectCell will deselect the cell at the specified index on each displayed Calendar page.
4608 * @method deselectCell
4609 * @param {Number} cellIndex The index of the cell to deselect.
4610 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
4612 YAHOO.widget.CalendarGroup.prototype.deselectCell = function(cellIndex) {
4613 for (var p=0;p<this.pages.length;++p) {
4614 var cal = this.pages[p];
4615 cal.deselectCell(cellIndex);
4617 return this.getSelectedDates();
4621 * Resets the calendar widget to the originally selected month and year, and
4622 * sets the calendar to the initial selection(s).
4625 YAHOO.widget.CalendarGroup.prototype.reset = function() {
4626 for (var p=0;p<this.pages.length;++p) {
4627 var cal = this.pages[p];
4633 * Clears the selected dates in the current calendar widget and sets the calendar
4634 * to the current month and year.
4637 YAHOO.widget.CalendarGroup.prototype.clear = function() {
4638 for (var p=0;p<this.pages.length;++p) {
4639 var cal = this.pages[p];
4645 * Navigates to the next month page in the calendar widget.
4648 YAHOO.widget.CalendarGroup.prototype.nextMonth = function() {
4649 for (var p=0;p<this.pages.length;++p) {
4650 var cal = this.pages[p];
4656 * Navigates to the previous month page in the calendar widget.
4657 * @method previousMonth
4659 YAHOO.widget.CalendarGroup.prototype.previousMonth = function() {
4660 for (var p=this.pages.length-1;p>=0;--p) {
4661 var cal = this.pages[p];
4662 cal.previousMonth();
4667 * Navigates to the next year in the currently selected month in the calendar widget.
4670 YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
4671 for (var p=0;p<this.pages.length;++p) {
4672 var cal = this.pages[p];
4678 * Navigates to the previous year in the currently selected month in the calendar widget.
4679 * @method previousYear
4681 YAHOO.widget.CalendarGroup.prototype.previousYear = function() {
4682 for (var p=0;p<this.pages.length;++p) {
4683 var cal = this.pages[p];
4690 * Gets the list of currently selected dates from the calendar.
4691 * @return An array of currently selected JavaScript Date objects.
4694 YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() {
4695 var returnDates = [];
4696 var selected = this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key);
4697 for (var d=0;d<selected.length;++d) {
4698 var dateArray = selected[d];
4700 var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
4701 returnDates.push(date);
4704 returnDates.sort( function(a,b) { return a-b; } );
4709 * Adds a renderer to the render stack. The function reference passed to this method will be executed
4710 * when a date cell matches the conditions specified in the date string for this renderer.
4711 * @method addRenderer
4712 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
4713 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
4714 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
4716 YAHOO.widget.CalendarGroup.prototype.addRenderer = function(sDates, fnRender) {
4717 for (var p=0;p<this.pages.length;++p) {
4718 var cal = this.pages[p];
4719 cal.addRenderer(sDates, fnRender);
4724 * Adds a month to the render stack. The function reference passed to this method will be executed
4725 * when a date cell matches the month passed to this method.
4726 * @method addMonthRenderer
4727 * @param {Number} month The month (1-12) to associate with this renderer
4728 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
4730 YAHOO.widget.CalendarGroup.prototype.addMonthRenderer = function(month, fnRender) {
4731 for (var p=0;p<this.pages.length;++p) {
4732 var cal = this.pages[p];
4733 cal.addMonthRenderer(month, fnRender);
4738 * Adds a weekday to the render stack. The function reference passed to this method will be executed
4739 * when a date cell matches the weekday passed to this method.
4740 * @method addWeekdayRenderer
4741 * @param {Number} weekday The weekday (1-7) to associate with this renderer. 1=Sunday, 2=Monday etc.
4742 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
4744 YAHOO.widget.CalendarGroup.prototype.addWeekdayRenderer = function(weekday, fnRender) {
4745 for (var p=0;p<this.pages.length;++p) {
4746 var cal = this.pages[p];
4747 cal.addWeekdayRenderer(weekday, fnRender);
4752 * Renders the header for the CalendarGroup.
4753 * @method renderHeader
4755 YAHOO.widget.CalendarGroup.prototype.renderHeader = function() {};
4758 * Renders a footer for the 2-up calendar container. By default, this method is
4760 * @method renderFooter
4762 YAHOO.widget.CalendarGroup.prototype.renderFooter = function() {};
4765 * Adds the designated number of months to the current calendar month, and sets the current
4766 * calendar page date to the new month.
4768 * @param {Number} count The number of months to add to the current calendar
4770 YAHOO.widget.CalendarGroup.prototype.addMonths = function(count) {
4771 this.callChildFunction("addMonths", count);
4776 * Subtracts the designated number of months from the current calendar month, and sets the current
4777 * calendar page date to the new month.
4778 * @method subtractMonths
4779 * @param {Number} count The number of months to subtract from the current calendar
4781 YAHOO.widget.CalendarGroup.prototype.subtractMonths = function(count) {
4782 this.callChildFunction("subtractMonths", count);
4786 * Adds the designated number of years to the current calendar, and sets the current
4787 * calendar page date to the new month.
4789 * @param {Number} count The number of years to add to the current calendar
4791 YAHOO.widget.CalendarGroup.prototype.addYears = function(count) {
4792 this.callChildFunction("addYears", count);
4796 * Subtcats the designated number of years from the current calendar, and sets the current
4797 * calendar page date to the new month.
4798 * @method subtractYears
4799 * @param {Number} count The number of years to subtract from the current calendar
4801 YAHOO.widget.CalendarGroup.prototype.subtractYears = function(count) {
4802 this.callChildFunction("subtractYears", count);
4806 * Shows the CalendarGroup's outer container.
4809 YAHOO.widget.CalendarGroup.prototype.show = function() {
4810 this.oDomContainer.style.display = "block";
4811 if (YAHOO.env.ua.opera) {
4817 * Sets the month on a Date object, taking into account year rollover if the month is less than 0 or greater than 11.
4818 * 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
4819 * @method _setMonthOnDate
4821 * @param {Date} date The Date object on which to set the month index
4822 * @param {Number} iMonth The month index to set
4824 YAHOO.widget.CalendarGroup.prototype._setMonthOnDate = function(date, iMonth) {
4825 // Bug in Safari 1.3, 2.0 (WebKit build < 420), Date.setMonth does not work consistently if iMonth is not 0-11
4826 if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420 && (iMonth < 0 || iMonth > 11)) {
4827 var DM = YAHOO.widget.DateMath;
4828 var newDate = DM.add(date, DM.MONTH, iMonth-date.getMonth());
4829 date.setTime(newDate.getTime());
4831 date.setMonth(iMonth);
4836 * Fixes the width of the CalendarGroup container element, to account for miswrapped floats
4840 YAHOO.widget.CalendarGroup.prototype._fixWidth = function() {
4841 var startW = this.oDomContainer.offsetWidth;
4843 for (var p=0;p<this.pages.length;++p) {
4844 var cal = this.pages[p];
4845 w += cal.oDomContainer.offsetWidth;
4848 this.oDomContainer.style.width = w + "px";
4854 * CSS class representing the container for the calendar
4855 * @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
4860 YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
4863 * CSS class representing the container for the calendar
4864 * @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
4869 YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";
4872 * CSS class representing the title for the 2-up calendar
4873 * @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
4878 YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";
4881 * CSS class representing the close icon for the 2-up calendar
4882 * @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
4885 * @deprecated Along with Calendar.IMG_ROOT and NAV_ARROW_LEFT, NAV_ARROW_RIGHT configuration properties.
4886 * 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
4889 YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";
4891 YAHOO.lang.augmentProto(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
4893 "renderOutOfBoundsDate",
4896 "renderCellDefault",
4898 "renderCellStyleHighlight1",
4899 "renderCellStyleHighlight2",
4900 "renderCellStyleHighlight3",
4901 "renderCellStyleHighlight4",
4902 "renderCellStyleToday",
4903 "renderCellStyleSelected",
4904 "renderCellNotThisMonth",
4905 "renderBodyCellRestricted",
4914 * The set of default Config property keys and values for the CalendarGroup
4915 * @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
4921 YAHOO.widget.CalendarGroup._DEFAULT_CONFIG = YAHOO.widget.Calendar._DEFAULT_CONFIG;
4922 YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
4925 * Returns a string representation of the object.
4927 * @return {String} A string representation of the CalendarGroup object.
4929 YAHOO.widget.CalendarGroup.prototype.toString = function() {
4930 return "CalendarGroup " + this.id;
4933 YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
4936 * @class YAHOO.widget.Calendar2up
4937 * @extends YAHOO.widget.CalendarGroup
4938 * @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
4940 YAHOO.widget.Calendar2up = function(id, containerId, config) {
4941 this.init(id, containerId, config);
4944 YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);
4947 * @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
4949 YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
4951 YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.3.0", build: "442"});