summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI/calendar.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI/calendar.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI/calendar.js4239
1 files changed, 4239 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI/calendar.js b/frontend/beta/js/YUI/calendar.js
new file mode 100644
index 0000000..3593551
--- a/dev/null
+++ b/frontend/beta/js/YUI/calendar.js
@@ -0,0 +1,4239 @@
1/*
2Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3Code licensed under the BSD License:
4http://developer.yahoo.net/yui/license.txt
5version 0.12.0
6*/
7
8/**
9* Config is a utility used within an Object to allow the implementer to maintain a list of local configuration properties and listen for changes to those properties dynamically using CustomEvent. The initial values are also maintained so that the configuration can be reset at any given point to its initial state.
10* @class YAHOO.util.Config
11* @constructor
12 * @param {Object} ownerThe owner Object to which this Config Object belongs
13*/
14YAHOO.util.Config = function(owner) {
15 if (owner) {
16 this.init(owner);
17 }
18};
19
20YAHOO.util.Config.prototype = {
21
22 /**
23 * Object reference to the owner of this Config Object
24 * @property owner
25 * @type Object
26 */
27 owner : null,
28
29 /**
30 * Boolean flag that specifies whether a queue is currently being executed
31 * @property queueInProgress
32 * @type Boolean
33 */
34 queueInProgress : false,
35
36
37 /**
38 * Validates that the value passed in is a Boolean.
39 * @method checkBoolean
40 * @param {Object} valThe value to validate
41 * @return {Boolean}true, if the value is valid
42 */
43 checkBoolean: function(val) {
44 if (typeof val == 'boolean') {
45 return true;
46 } else {
47 return false;
48 }
49 },
50
51 /**
52 * Validates that the value passed in is a number.
53 * @method checkNumber
54 * @param {Object} valThe value to validate
55 * @return {Boolean}true, if the value is valid
56 */
57 checkNumber: function(val) {
58 if (isNaN(val)) {
59 return false;
60 } else {
61 return true;
62 }
63 }
64};
65
66
67/**
68* Initializes the configuration Object and all of its local members.
69* @method init
70 * @param {Object} ownerThe owner Object to which this Config Object belongs
71*/
72YAHOO.util.Config.prototype.init = function(owner) {
73
74 this.owner = owner;
75
76 /**
77 * Object reference to the owner of this Config Object
78 * @event configChangedEvent
79 */
80 this.configChangedEvent = new YAHOO.util.CustomEvent("configChanged");
81
82 this.queueInProgress = false;
83
84 /* Private Members */
85
86 /**
87 * Maintains the local collection of configuration property objects and their specified values
88 * @property config
89 * @private
90 * @type Object
91 */
92 var config = {};
93
94 /**
95 * Maintains the local collection of configuration property objects as they were initially applied.
96 * This object is used when resetting a property.
97 * @property initialConfig
98 * @private
99 * @type Object
100 */
101 var initialConfig = {};
102
103 /**
104 * Maintains the local, normalized CustomEvent queue
105 * @property eventQueue
106 * @private
107 * @type Object
108 */
109 var eventQueue = [];
110
111 /**
112 * Fires a configuration property event using the specified value.
113 * @method fireEvent
114 * @private
115 * @param {String} key The configuration property's name
116 * @param {value} Object The value of the correct type for the property
117 */
118 var fireEvent = function( key, value ) {
119 key = key.toLowerCase();
120
121 var property = config[key];
122
123 if (typeof property != 'undefined' && property.event) {
124 property.event.fire(value);
125 }
126 };
127 /* End Private Members */
128
129 /**
130 * Adds a property to the Config Object's private config hash.
131 * @method addProperty
132 * @param {String} keyThe configuration property's name
133 * @param {Object} propertyObjectThe Object containing all of this property's arguments
134 */
135 this.addProperty = function( key, propertyObject ) {
136 key = key.toLowerCase();
137
138 config[key] = propertyObject;
139
140 propertyObject.event = new YAHOO.util.CustomEvent(key);
141 propertyObject.key = key;
142
143 if (propertyObject.handler) {
144 propertyObject.event.subscribe(propertyObject.handler, this.owner, true);
145 }
146
147 this.setProperty(key, propertyObject.value, true);
148
149 if (! propertyObject.suppressEvent) {
150 this.queueProperty(key, propertyObject.value);
151 }
152 };
153
154 /**
155 * Returns a key-value configuration map of the values currently set in the Config Object.
156 * @method getConfig
157 * @return {Object} The current config, represented in a key-value map
158 */
159 this.getConfig = function() {
160 var cfg = {};
161
162 for (var prop in config) {
163 var property = config[prop];
164 if (typeof property != 'undefined' && property.event) {
165 cfg[prop] = property.value;
166 }
167 }
168
169 return cfg;
170 };
171
172 /**
173 * Returns the value of specified property.
174 * @method getProperty
175 * @param {String} keyThe name of the property
176 * @return {Object} The value of the specified property
177 */
178 this.getProperty = function(key) {
179 key = key.toLowerCase();
180
181 var property = config[key];
182 if (typeof property != 'undefined' && property.event) {
183 return property.value;
184 } else {
185 return undefined;
186 }
187 };
188
189 /**
190 * Resets the specified property's value to its initial value.
191 * @method resetProperty
192 * @param {String} keyThe name of the property
193 * @return {Boolean} True is the property was reset, false if not
194 */
195 this.resetProperty = function(key) {
196 key = key.toLowerCase();
197
198 var property = config[key];
199 if (typeof property != 'undefined' && property.event) {
200 if (initialConfig[key] && initialConfig[key] != 'undefined'){
201 this.setProperty(key, initialConfig[key]);
202 }
203 return true;
204 } else {
205 return false;
206 }
207 };
208
209 /**
210 * Sets the value of a property. If the silent property is passed as true, the property's event will not be fired.
211 * @method setProperty
212 * @param {String} key The name of the property
213 * @param {String} value The value to set the property to
214 * @param {Boolean} silentWhether the value should be set silently, without firing the property event.
215 * @return {Boolean} True, if the set was successful, false if it failed.
216 */
217 this.setProperty = function(key, value, silent) {
218 key = key.toLowerCase();
219
220 if (this.queueInProgress && ! silent) {
221 this.queueProperty(key,value); // Currently running through a queue...
222 return true;
223 } else {
224 var property = config[key];
225 if (typeof property != 'undefined' && property.event) {
226 if (property.validator && ! property.validator(value)) { // validator
227 return false;
228 } else {
229 property.value = value;
230 if (! silent) {
231 fireEvent(key, value);
232 this.configChangedEvent.fire([key, value]);
233 }
234 return true;
235 }
236 } else {
237 return false;
238 }
239 }
240 };
241
242 /**
243 * Sets the value of a property and queues its event to execute. If the event is already scheduled to execute, it is
244 * moved from its current position to the end of the queue.
245 * @method queueProperty
246 * @param {String} keyThe name of the property
247 * @param {String} valueThe value to set the property to
248 * @return {Boolean} true, if the set was successful, false if it failed.
249 */
250 this.queueProperty = function(key, value) {
251 key = key.toLowerCase();
252
253 var property = config[key];
254
255 if (typeof property != 'undefined' && property.event) {
256 if (typeof value != 'undefined' && property.validator && ! property.validator(value)) { // validator
257 return false;
258 } else {
259
260 if (typeof value != 'undefined') {
261 property.value = value;
262 } else {
263 value = property.value;
264 }
265
266 var foundDuplicate = false;
267
268 for (var i=0;i<eventQueue.length;i++) {
269 var queueItem = eventQueue[i];
270
271 if (queueItem) {
272 var queueItemKey = queueItem[0];
273 var queueItemValue = queueItem[1];
274
275 if (queueItemKey.toLowerCase() == key) {
276 // found a dupe... push to end of queue, null current item, and break
277 eventQueue[i] = null;
278 eventQueue.push([key, (typeof value != 'undefined' ? value : queueItemValue)]);
279 foundDuplicate = true;
280 break;
281 }
282 }
283 }
284
285 if (! foundDuplicate && typeof value != 'undefined') { // this is a refire, or a new property in the queue
286 eventQueue.push([key, value]);
287 }
288 }
289
290 if (property.supercedes) {
291 for (var s=0;s<property.supercedes.length;s++) {
292 var supercedesCheck = property.supercedes[s];
293
294 for (var q=0;q<eventQueue.length;q++) {
295 var queueItemCheck = eventQueue[q];
296
297 if (queueItemCheck) {
298 var queueItemCheckKey = queueItemCheck[0];
299 var queueItemCheckValue = queueItemCheck[1];
300
301 if ( queueItemCheckKey.toLowerCase() == supercedesCheck.toLowerCase() ) {
302 eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
303 eventQueue[q] = null;
304 break;
305 }
306 }
307 }
308 }
309 }
310
311 return true;
312 } else {
313 return false;
314 }
315 };
316
317 /**
318 * Fires the event for a property using the property's current value.
319 * @method refireEvent
320 * @param {String} keyThe name of the property
321 */
322 this.refireEvent = function(key) {
323 key = key.toLowerCase();
324
325 var property = config[key];
326 if (typeof property != 'undefined' && property.event && typeof property.value != 'undefined') {
327 if (this.queueInProgress) {
328 this.queueProperty(key);
329 } else {
330 fireEvent(key, property.value);
331 }
332 }
333 };
334
335 /**
336 * Applies a key-value Object literal to the configuration, replacing any existing values, and queueing the property events.
337 * Although the values will be set, fireQueue() must be called for their associated events to execute.
338 * @method applyConfig
339 * @param {Object} userConfigThe configuration Object literal
340 * @param {Boolean} init When set to true, the initialConfig will be set to the userConfig passed in, so that calling a reset will reset the properties to the passed values.
341 */
342 this.applyConfig = function(userConfig, init) {
343 if (init) {
344 initialConfig = userConfig;
345 }
346 for (var prop in userConfig) {
347 this.queueProperty(prop, userConfig[prop]);
348 }
349 };
350
351 /**
352 * Refires the events for all configuration properties using their current values.
353 * @method refresh
354 */
355 this.refresh = function() {
356 for (var prop in config) {
357 this.refireEvent(prop);
358 }
359 };
360
361 /**
362 * Fires the normalized list of queued property change events
363 * @method fireQueue
364 */
365 this.fireQueue = function() {
366 this.queueInProgress = true;
367 for (var i=0;i<eventQueue.length;i++) {
368 var queueItem = eventQueue[i];
369 if (queueItem) {
370 var key = queueItem[0];
371 var value = queueItem[1];
372
373 var property = config[key];
374 property.value = value;
375
376 fireEvent(key,value);
377 }
378 }
379
380 this.queueInProgress = false;
381 eventQueue = [];
382 };
383
384 /**
385 * Subscribes an external handler to the change event for any given property.
386 * @method subscribeToConfigEvent
387 * @param {String} key The property name
388 * @param {Function} handler The handler function to use subscribe to the property's event
389 * @param {Object} obj The Object to use for scoping the event handler (see CustomEvent documentation)
390 * @param {Boolean} overrideOptional. If true, will override "this" within the handler to map to the scope Object passed into the method.
391 * @return {Boolean} True, if the subscription was successful, otherwise false.
392 */
393 this.subscribeToConfigEvent = function(key, handler, obj, override) {
394 key = key.toLowerCase();
395
396 var property = config[key];
397 if (typeof property != 'undefined' && property.event) {
398 if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
399 property.event.subscribe(handler, obj, override);
400 }
401 return true;
402 } else {
403 return false;
404 }
405 };
406
407 /**
408 * Unsubscribes an external handler from the change event for any given property.
409 * @method unsubscribeFromConfigEvent
410 * @param {String} key The property name
411 * @param {Function} handler The handler function to use subscribe to the property's event
412 * @param {Object} obj The Object to use for scoping the event handler (see CustomEvent documentation)
413 * @return {Boolean} True, if the unsubscription was successful, otherwise false.
414 */
415 this.unsubscribeFromConfigEvent = function(key, handler, obj) {
416 key = key.toLowerCase();
417
418 var property = config[key];
419 if (typeof property != 'undefined' && property.event) {
420 return property.event.unsubscribe(handler, obj);
421 } else {
422 return false;
423 }
424 };
425
426 /**
427 * Returns a string representation of the Config object
428 * @method toString
429 * @return {String}The Config object in string format.
430 */
431 this.toString = function() {
432 var output = "Config";
433 if (this.owner) {
434 output += " [" + this.owner.toString() + "]";
435 }
436 return output;
437 };
438
439 /**
440 * Returns a string representation of the Config object's current CustomEvent queue
441 * @method outputEventQueue
442 * @return {String}The string list of CustomEvents currently queued for execution
443 */
444 this.outputEventQueue = function() {
445 var output = "";
446 for (var q=0;q<eventQueue.length;q++) {
447 var queueItem = eventQueue[q];
448 if (queueItem) {
449 output += queueItem[0] + "=" + queueItem[1] + ", ";
450 }
451 }
452 return output;
453 };
454};
455
456/**
457* Checks to determine if a particular function/Object pair are already subscribed to the specified CustomEvent
458* @method YAHOO.util.Config.alreadySubscribed
459* @static
460 * @param {YAHOO.util.CustomEvent} evtThe CustomEvent for which to check the subscriptions
461 * @param {Function} fnThe function to look for in the subscribers list
462 * @param {Object} objThe execution scope Object for the subscription
463 * @return {Boolean}true, if the function/Object pair is already subscribed to the CustomEvent passed in
464*/
465YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
466 for (var e=0;e<evt.subscribers.length;e++) {
467 var subsc = evt.subscribers[e];
468 if (subsc && subsc.obj == obj && subsc.fn == fn) {
469 return true;
470 }
471 }
472 return false;
473};
474
475/**
476* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
477* used for adding, subtracting, and comparing dates.
478* @class YAHOO.widget.DateMath
479*/
480YAHOO.widget.DateMath = {
481 /**
482 * Constant field representing Day
483 * @property DAY
484 * @static
485 * @final
486 * @type String
487 */
488 DAY : "D",
489
490 /**
491 * Constant field representing Week
492 * @property WEEK
493 * @static
494 * @final
495 * @type String
496 */
497 WEEK : "W",
498
499 /**
500 * Constant field representing Year
501 * @property YEAR
502 * @static
503 * @final
504 * @type String
505 */
506 YEAR : "Y",
507
508 /**
509 * Constant field representing Month
510 * @property MONTH
511 * @static
512 * @final
513 * @type String
514 */
515 MONTH : "M",
516
517 /**
518 * Constant field representing one day, in milliseconds
519 * @property ONE_DAY_MS
520 * @static
521 * @final
522 * @type Number
523 */
524 ONE_DAY_MS : 1000*60*60*24,
525
526 /**
527 * Adds the specified amount of time to the this instance.
528 * @method add
529 * @param {Date} dateThe JavaScript Date object to perform addition on
530 * @param {String} fieldThe field constant to be used for performing addition.
531 * @param {Number} amountThe number of units (measured in the field constant) to add to the date.
532 * @return {Date} The resulting Date object
533 */
534 add : function(date, field, amount) {
535 var d = new Date(date.getTime());
536 switch (field) {
537 case this.MONTH:
538 var newMonth = date.getMonth() + amount;
539 var years = 0;
540
541
542 if (newMonth < 0) {
543 while (newMonth < 0) {
544 newMonth += 12;
545 years -= 1;
546 }
547 } else if (newMonth > 11) {
548 while (newMonth > 11) {
549 newMonth -= 12;
550 years += 1;
551 }
552 }
553
554 d.setMonth(newMonth);
555 d.setFullYear(date.getFullYear() + years);
556 break;
557 case this.DAY:
558 d.setDate(date.getDate() + amount);
559 break;
560 case this.YEAR:
561 d.setFullYear(date.getFullYear() + amount);
562 break;
563 case this.WEEK:
564 d.setDate(date.getDate() + (amount * 7));
565 break;
566 }
567 return d;
568 },
569
570 /**
571 * Subtracts the specified amount of time from the this instance.
572 * @method subtract
573 * @param {Date} dateThe JavaScript Date object to perform subtraction on
574 * @param {Number} fieldThe this field constant to be used for performing subtraction.
575 * @param {Number} amountThe number of units (measured in the field constant) to subtract from the date.
576 * @return {Date} The resulting Date object
577 */
578 subtract : function(date, field, amount) {
579 return this.add(date, field, (amount*-1));
580 },
581
582 /**
583 * Determines whether a given date is before another date on the calendar.
584 * @method before
585 * @param {Date} date The Date object to compare with the compare argument
586 * @param {Date} compareToThe Date object to use for the comparison
587 * @return {Boolean} true if the date occurs before the compared date; false if not.
588 */
589 before : function(date, compareTo) {
590 var ms = compareTo.getTime();
591 if (date.getTime() < ms) {
592 return true;
593 } else {
594 return false;
595 }
596 },
597
598 /**
599 * Determines whether a given date is after another date on the calendar.
600 * @method after
601 * @param {Date} date The Date object to compare with the compare argument
602 * @param {Date} compareToThe Date object to use for the comparison
603 * @return {Boolean} true if the date occurs after the compared date; false if not.
604 */
605 after : function(date, compareTo) {
606 var ms = compareTo.getTime();
607 if (date.getTime() > ms) {
608 return true;
609 } else {
610 return false;
611 }
612 },
613
614 /**
615 * Determines whether a given date is between two other dates on the calendar.
616 * @method between
617 * @param {Date} date The date to check for
618 * @param {Date} dateBeginThe start of the range
619 * @param {Date} dateEnd The end of the range
620 * @return {Boolean} true if the date occurs between the compared dates; false if not.
621 */
622 between : function(date, dateBegin, dateEnd) {
623 if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
624 return true;
625 } else {
626 return false;
627 }
628 },
629
630 /**
631 * Retrieves a JavaScript Date object representing January 1 of any given year.
632 * @method getJan1
633 * @param {Number} calendarYear The calendar year for which to retrieve January 1
634 * @return {Date}January 1 of the calendar year specified.
635 */
636 getJan1 : function(calendarYear) {
637 return new Date(calendarYear,0,1);
638 },
639
640 /**
641 * Calculates the number of days the specified date is from January 1 of the specified calendar year.
642 * Passing January 1 to this function would return an offset value of zero.
643 * @method getDayOffset
644 * @param {Date} dateThe JavaScript date for which to find the offset
645 * @param {Number} calendarYearThe calendar year to use for determining the offset
646 * @return {Number}The number of days since January 1 of the given year
647 */
648 getDayOffset : function(date, calendarYear) {
649 var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
650
651 // Find the number of days the passed in date is away from the calendar year start
652 var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
653 return dayOffset;
654 },
655
656 /**
657 * Calculates the week number for the given date. This function assumes that week 1 is the
658 * week in which January 1 appears, regardless of whether the week consists of a full 7 days.
659 * The calendar year can be specified to help find what a the week number would be for a given
660 * date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
661 * week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
662 * easily.
663 * @method getWeekNumber
664 * @param {Date} dateThe JavaScript date for which to find the week number
665 * @param {Number} calendarYearOPTIONAL - The calendar year to use for determining the week number. Default is
666 * the calendar year of parameter "date".
667 * @param {Number} weekStartsOnOPTIONAL - The integer (0-6) representing which day a week begins on. Default is 0 (for Sunday).
668 * @return {Number}The week number of the given date.
669 */
670 getWeekNumber : function(date, calendarYear) {
671 date = this.clearTime(date);
672 var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
673
674 var jan1 = new Date(nearestThurs.getFullYear(),0,1);
675 var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
676
677 var weekNum = Math.ceil((dayOfYear)/ 7);
678 return weekNum;
679 },
680
681 /**
682 * Determines if a given week overlaps two different years.
683 * @method isYearOverlapWeek
684 * @param {Date} weekBeginDateThe JavaScript Date representing the first day of the week.
685 * @return {Boolean}true if the date overlaps two different years.
686 */
687 isYearOverlapWeek : function(weekBeginDate) {
688 var overlaps = false;
689 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
690 if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
691 overlaps = true;
692 }
693 return overlaps;
694 },
695
696 /**
697 * Determines if a given week overlaps two different months.
698 * @method isMonthOverlapWeek
699 * @param {Date} weekBeginDateThe JavaScript Date representing the first day of the week.
700 * @return {Boolean}true if the date overlaps two different months.
701 */
702 isMonthOverlapWeek : function(weekBeginDate) {
703 var overlaps = false;
704 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
705 if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
706 overlaps = true;
707 }
708 return overlaps;
709 },
710
711 /**
712 * Gets the first day of a month containing a given date.
713 * @method findMonthStart
714 * @param {Date} dateThe JavaScript Date used to calculate the month start
715 * @return {Date} The JavaScript Date representing the first day of the month
716 */
717 findMonthStart : function(date) {
718 var start = new Date(date.getFullYear(), date.getMonth(), 1);
719 return start;
720 },
721
722 /**
723 * Gets the last day of a month containing a given date.
724 * @method findMonthEnd
725 * @param {Date} dateThe JavaScript Date used to calculate the month end
726 * @return {Date} The JavaScript Date representing the last day of the month
727 */
728 findMonthEnd : function(date) {
729 var start = this.findMonthStart(date);
730 var nextMonth = this.add(start, this.MONTH, 1);
731 var end = this.subtract(nextMonth, this.DAY, 1);
732 return end;
733 },
734
735 /**
736 * Clears the time fields from a given date, effectively setting the time to midnight.
737 * @method clearTime
738 * @param {Date} dateThe JavaScript Date for which the time fields will be cleared
739 * @return {Date} The JavaScript Date cleared of all time fields
740 */
741 clearTime : function(date) {
742 date.setHours(12,0,0,0);
743 return date;
744 }
745};
746
747/**
748* 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 ("one-up") or two-month ("two-up") interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
749* @module Calendar
750* @title Calendar Widget
751* @namespace YAHOO.widget
752* @requires yahoo,dom,event
753*/
754
755/**
756* Calendar is the base class for the Calendar widget. In its most basic
757* implementation, it has the ability to render a calendar widget on the page
758* that can be manipulated to select a single date, move back and forth between
759* months and years.
760* <p>To construct the placeholder for the calendar widget, the code is as
761* follows:
762 *<xmp>
763 * <div id="cal1Container"></div>
764 *</xmp>
765* Note that the table can be replaced with any kind of element.
766* </p>
767* @namespace YAHOO.widget
768* @class Calendar
769* @constructor
770 * @param {String} id The id of the table element that will represent the calendar widget
771 * @param {String} containerIdThe id of the container div element that will wrap the calendar table
772 * @param {Object} config The configuration object containing the Calendar's arguments
773*/
774YAHOO.widget.Calendar = function(id, containerId, config) {
775 this.init(id, containerId, config);
776};
777
778/**
779* The path to be used for images loaded for the Calendar
780* @property YAHOO.widget.Calendar.IMG_ROOT
781* @static
782* @type String
783*/
784YAHOO.widget.Calendar.IMG_ROOT = (window.location.href.toLowerCase().indexOf("https") === 0 ? "https://a248.e.akamai.net/sec.yimg.com/i/" : "http://us.i1.yimg.com/us.yimg.com/i/");
785
786/**
787* Type constant used for renderers to represent an individual date (M/D/Y)
788* @property YAHOO.widget.Calendar.DATE
789* @static
790* @final
791* @type String
792*/
793YAHOO.widget.Calendar.DATE = "D";
794
795/**
796* Type constant used for renderers to represent an individual date across any year (M/D)
797* @property YAHOO.widget.Calendar.MONTH_DAY
798* @static
799* @final
800* @type String
801*/
802YAHOO.widget.Calendar.MONTH_DAY = "MD";
803
804/**
805* Type constant used for renderers to represent a weekday
806* @property YAHOO.widget.Calendar.WEEKDAY
807* @static
808* @final
809* @type String
810*/
811YAHOO.widget.Calendar.WEEKDAY = "WD";
812
813/**
814* Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
815* @property YAHOO.widget.Calendar.RANGE
816* @static
817* @final
818* @type String
819*/
820YAHOO.widget.Calendar.RANGE = "R";
821
822/**
823* Type constant used for renderers to represent a month across any year
824* @property YAHOO.widget.Calendar.MONTH
825* @static
826* @final
827* @type String
828*/
829YAHOO.widget.Calendar.MONTH = "M";
830
831/**
832* Constant that represents the total number of date cells that are displayed in a given month
833* @property YAHOO.widget.Calendar.DISPLAY_DAYS
834* @static
835* @final
836* @type Number
837*/
838YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
839
840/**
841* Constant used for halting the execution of the remainder of the render stack
842* @property YAHOO.widget.Calendar.STOP_RENDER
843* @static
844* @final
845* @type String
846*/
847YAHOO.widget.Calendar.STOP_RENDER = "S";
848
849YAHOO.widget.Calendar.prototype = {
850
851 /**
852 * The configuration object used to set up the calendars various locale and style options.
853 * @property Config
854 * @private
855 * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
856 * @type Object
857 */
858 Config : null,
859
860 /**
861 * The parent CalendarGroup, only to be set explicitly by the parent group
862 * @property parent
863 * @type CalendarGroup
864 */
865 parent : null,
866
867 /**
868 * The index of this item in the parent group
869 * @property index
870 * @type Number
871 */
872 index : -1,
873
874 /**
875 * The collection of calendar table cells
876 * @property cells
877 * @type HTMLTableCellElement[]
878 */
879 cells : null,
880
881 /**
882 * 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].
883 * @property cellDates
884 * @type Array[](Number[])
885 */
886 cellDates : null,
887
888 /**
889 * The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
890 * @property id
891 * @type String
892 */
893 id : null,
894
895 /**
896 * 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.
897 * @property oDomContainer
898 * @type HTMLElement
899 */
900 oDomContainer : null,
901
902 /**
903 * A Date object representing today's date.
904 * @property today
905 * @type Date
906 */
907 today : null,
908
909 /**
910 * The list of render functions, along with required parameters, used to render cells.
911 * @property renderStack
912 * @type Array[]
913 */
914 renderStack : null,
915
916 /**
917 * A copy of the initial render functions created before rendering.
918 * @property _renderStack
919 * @private
920 * @type Array
921 */
922 _renderStack : null,
923
924 /**
925 * A Date object representing the month/year that the calendar is initially set to
926 * @property _pageDate
927 * @private
928 * @type Date
929 */
930 _pageDate : null,
931
932 /**
933 * The private list of initially selected dates.
934 * @property _selectedDates
935 * @private
936 * @type Array
937 */
938 _selectedDates : null,
939
940 /**
941 * A map of DOM event handlers to attach to cells associated with specific CSS class names
942 * @property domEventMap
943 * @type Object
944 */
945 domEventMap : null
946};
947
948
949
950/**
951* Initializes the Calendar widget.
952* @method init
953 * @param {String} id The id of the table element that will represent the calendar widget
954 * @param {String} containerIdThe id of the container div element that will wrap the calendar table
955 * @param {Object} config The configuration object containing the Calendar's arguments
956*/
957YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
958 this.initEvents();
959 this.today = new Date();
960 YAHOO.widget.DateMath.clearTime(this.today);
961
962 this.id = id;
963 this.oDomContainer = document.getElementById(containerId);
964
965 /**
966 * The Config object used to hold the configuration variables for the Calendar
967 * @property cfg
968 * @type YAHOO.util.Config
969 */
970 this.cfg = new YAHOO.util.Config(this);
971
972 /**
973 * The local object which contains the Calendar's options
974 * @property Options
975 * @type Object
976 */
977 this.Options = {};
978
979 /**
980 * The local object which contains the Calendar's locale settings
981 * @property Locale
982 * @type Object
983 */
984 this.Locale = {};
985
986 this.initStyles();
987
988 YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
989 YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
990
991 this.cellDates = [];
992 this.cells = [];
993 this.renderStack = [];
994 this._renderStack = [];
995
996 this.setupConfig();
997
998 if (config) {
999 this.cfg.applyConfig(config, true);
1000 }
1001
1002 this.cfg.fireQueue();
1003};
1004
1005/**
1006* Renders the built-in IFRAME shim for the IE6 and below
1007* @method configIframe
1008*/
1009YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
1010 var useIframe = args[0];
1011
1012 if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
1013 if (useIframe) {
1014 var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
1015
1016 if (this.browser == "ie" && (pos == "absolute" || pos == "relative")) {
1017 if (! YAHOO.util.Dom.inDocument(this.iframe)) {
1018 this.iframe = document.createElement("iframe");
1019 this.iframe.src = "javascript:false;";
1020 YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
1021 this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
1022 }
1023 }
1024 } else {
1025 if (this.iframe) {
1026 if (this.iframe.parentNode) {
1027 this.iframe.parentNode.removeChild(this.iframe);
1028 }
1029 this.iframe = null;
1030 }
1031 }
1032 }
1033};
1034
1035/**
1036* Default handler for the "title" property
1037* @method configTitle
1038*/
1039YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
1040 var title = args[0];
1041 var close = this.cfg.getProperty("close");
1042
1043 var titleDiv;
1044
1045 if (title && title !== "") {
1046 titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
1047 titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
1048 titleDiv.innerHTML = title;
1049 this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
1050 YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
1051 } else {
1052 titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
1053
1054 if (titleDiv) {
1055 YAHOO.util.Event.purgeElement(titleDiv);
1056 this.oDomContainer.removeChild(titleDiv);
1057 }
1058 if (! close) {
1059 YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
1060 }
1061 }
1062};
1063
1064/**
1065* Default handler for the "close" property
1066* @method configClose
1067*/
1068YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
1069 var close = args[0];
1070 var title = this.cfg.getProperty("title");
1071
1072 var linkClose;
1073
1074 if (close === true) {
1075 linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
1076 linkClose.href = "javascript:void(null);";
1077 linkClose.className = "link-close";
1078 YAHOO.util.Event.addListener(linkClose, "click", this.hide, this, true);
1079 var imgClose = document.createElement("img");
1080 imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + "us/my/bn/x_d.gif";
1081 imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
1082 linkClose.appendChild(imgClose);
1083 this.oDomContainer.appendChild(linkClose);
1084 YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
1085 } else {
1086 linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
1087
1088 if (linkClose) {
1089 YAHOO.util.Event.purgeElement(linkClose);
1090 this.oDomContainer.removeChild(linkClose);
1091 }
1092 if (! title || title === "") {
1093 YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
1094 }
1095 }
1096};
1097
1098/**
1099* Initializes Calendar's built-in CustomEvents
1100* @method initEvents
1101*/
1102YAHOO.widget.Calendar.prototype.initEvents = function() {
1103
1104 /**
1105 * Fired before a selection is made
1106 * @event beforeSelectEvent
1107 */
1108 this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
1109
1110 /**
1111 * Fired when a selection is made
1112 * @event selectEvent
1113 * @param {Array}Array of Date field arrays in the format [YYYY, MM, DD].
1114 */
1115 this.selectEvent = new YAHOO.util.CustomEvent("select");
1116
1117 /**
1118 * Fired before a selection is made
1119 * @event beforeDeselectEvent
1120 */
1121 this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
1122
1123 /**
1124 * Fired when a selection is made
1125 * @event deselectEvent
1126 * @param {Array}Array of Date field arrays in the format [YYYY, MM, DD].
1127 */
1128 this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
1129
1130 /**
1131 * Fired when the Calendar page is changed
1132 * @event changePageEvent
1133 */
1134 this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
1135
1136 /**
1137 * Fired before the Calendar is rendered
1138 * @event beforeRenderEvent
1139 */
1140 this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
1141
1142 /**
1143 * Fired when the Calendar is rendered
1144 * @event renderEvent
1145 */
1146 this.renderEvent = new YAHOO.util.CustomEvent("render");
1147
1148 /**
1149 * Fired when the Calendar is reset
1150 * @event resetEvent
1151 */
1152 this.resetEvent = new YAHOO.util.CustomEvent("reset");
1153
1154 /**
1155 * Fired when the Calendar is cleared
1156 * @event clearEvent
1157 */
1158 this.clearEvent = new YAHOO.util.CustomEvent("clear");
1159
1160 this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
1161 this.selectEvent.subscribe(this.onSelect, this, true);
1162 this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
1163 this.deselectEvent.subscribe(this.onDeselect, this, true);
1164 this.changePageEvent.subscribe(this.onChangePage, this, true);
1165 this.renderEvent.subscribe(this.onRender, this, true);
1166 this.resetEvent.subscribe(this.onReset, this, true);
1167 this.clearEvent.subscribe(this.onClear, this, true);
1168};
1169
1170
1171/**
1172* The default event function that is attached to a date link within a calendar cell
1173* when the calendar is rendered.
1174* @method doSelectCell
1175 * @param {DOMEvent} eThe event
1176 * @param {Calendar} calA reference to the calendar passed by the Event utility
1177*/
1178YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
1179 var target = YAHOO.util.Event.getTarget(e);
1180
1181 var cell,index,d,date;
1182
1183 while (target.tagName.toLowerCase() != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1184 target = target.parentNode;
1185 if (target.tagName.toLowerCase() == "html") {
1186 return;
1187 }
1188 }
1189
1190 cell = target;
1191
1192 if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
1193 index = cell.id.split("cell")[1];
1194 d = cal.cellDates[index];
1195 date = new Date(d[0],d[1]-1,d[2]);
1196
1197 var link;
1198
1199 if (cal.Options.MULTI_SELECT) {
1200 link = cell.getElementsByTagName("a")[0];
1201 if (link) {
1202 link.blur();
1203 }
1204
1205 var cellDate = cal.cellDates[index];
1206 var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
1207
1208 if (cellDateIndex > -1) {
1209 cal.deselectCell(index);
1210 } else {
1211 cal.selectCell(index);
1212 }
1213
1214 } else {
1215 link = cell.getElementsByTagName("a")[0];
1216 if (link) {
1217 link.blur();
1218 }
1219 cal.selectCell(index);
1220 }
1221 }
1222};
1223
1224/**
1225* The event that is executed when the user hovers over a cell
1226* @method doCellMouseOver
1227 * @param {DOMEvent} eThe event
1228 * @param {Calendar} calA reference to the calendar passed by the Event utility
1229*/
1230YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
1231 var target;
1232 if (e) {
1233 target = YAHOO.util.Event.getTarget(e);
1234 } else {
1235 target = this;
1236 }
1237
1238 while (target.tagName.toLowerCase() != "td") {
1239 target = target.parentNode;
1240 if (target.tagName.toLowerCase() == "html") {
1241 return;
1242 }
1243 }
1244
1245 if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1246 YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
1247 }
1248};
1249
1250/**
1251* The event that is executed when the user moves the mouse out of a cell
1252* @method doCellMouseOut
1253 * @param {DOMEvent} eThe event
1254 * @param {Calendar} calA reference to the calendar passed by the Event utility
1255*/
1256YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
1257 var target;
1258 if (e) {
1259 target = YAHOO.util.Event.getTarget(e);
1260 } else {
1261 target = this;
1262 }
1263
1264 while (target.tagName.toLowerCase() != "td") {
1265 target = target.parentNode;
1266 if (target.tagName.toLowerCase() == "html") {
1267 return;
1268 }
1269 }
1270
1271 if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
1272 YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
1273 }
1274};
1275
1276YAHOO.widget.Calendar.prototype.setupConfig = function() {
1277
1278 /**
1279 * The month/year representing the current visible Calendar date (mm/yyyy)
1280 * @config pagedate
1281 * @type String
1282 * @default today's date
1283 */
1284 this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );
1285
1286 /**
1287 * The date or range of dates representing the current Calendar selection
1288 * @config selected
1289 * @type String
1290 * @default []
1291 */
1292 this.cfg.addProperty("selected", { value:[], handler:this.configSelected } );
1293
1294 /**
1295 * The title to display above the Calendar's month header
1296 * @config title
1297 * @type String
1298 * @default ""
1299 */
1300 this.cfg.addProperty("title", { value:"", handler:this.configTitle } );
1301
1302 /**
1303 * Whether or not a close button should be displayed for this Calendar
1304 * @config close
1305 * @type Boolean
1306 * @default false
1307 */
1308 this.cfg.addProperty("close", { value:false, handler:this.configClose } );
1309
1310 /**
1311 * 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.
1312 * @config iframe
1313 * @type Boolean
1314 * @default true
1315 */
1316 this.cfg.addProperty("iframe", { value:true, handler:this.configIframe, validator:this.cfg.checkBoolean } );
1317
1318 /**
1319 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
1320 * @config mindate
1321 * @type String
1322 * @default null
1323 */
1324 this.cfg.addProperty("mindate", { value:null, handler:this.configMinDate } );
1325
1326 /**
1327 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
1328 * @config maxdate
1329 * @type String
1330 * @default null
1331 */
1332 this.cfg.addProperty("maxdate", { value:null, handler:this.configMaxDate } );
1333
1334
1335 // Options properties
1336
1337 /**
1338 * True if the Calendar should allow multiple selections. False by default.
1339 * @config MULTI_SELECT
1340 * @type Boolean
1341 * @default false
1342 */
1343 this.cfg.addProperty("MULTI_SELECT",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1344
1345 /**
1346 * The weekday the week begins on. Default is 0 (Sunday).
1347 * @config START_WEEKDAY
1348 * @type number
1349 * @default 0
1350 */
1351 this.cfg.addProperty("START_WEEKDAY",{ value:0, handler:this.configOptions, validator:this.cfg.checkNumber } );
1352
1353 /**
1354 * True if the Calendar should show weekday labels. True by default.
1355 * @config SHOW_WEEKDAYS
1356 * @type Boolean
1357 * @default true
1358 */
1359 this.cfg.addProperty("SHOW_WEEKDAYS",{ value:true, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1360
1361 /**
1362 * True if the Calendar should show week row headers. False by default.
1363 * @config SHOW_WEEK_HEADER
1364 * @type Boolean
1365 * @default false
1366 */
1367 this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1368
1369 /**
1370 * True if the Calendar should show week row footers. False by default.
1371 * @config SHOW_WEEK_FOOTER
1372 * @type Boolean
1373 * @default false
1374 */
1375 this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1376
1377 /**
1378 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
1379 * @config HIDE_BLANK_WEEKS
1380 * @type Boolean
1381 * @default false
1382 */
1383 this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
1384
1385 /**
1386 * The image that should be used for the left navigation arrow.
1387 * @config NAV_ARROW_LEFT
1388 * @type String
1389 * @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif"
1390 */
1391 this.cfg.addProperty("NAV_ARROW_LEFT",{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.configOptions } );
1392
1393 /**
1394 * The image that should be used for the left navigation arrow.
1395 * @config NAV_ARROW_RIGHT
1396 * @type String
1397 * @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif"
1398 */
1399 this.cfg.addProperty("NAV_ARROW_RIGHT",{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.configOptions } );
1400
1401 // Locale properties
1402
1403 /**
1404 * The short month labels for the current locale.
1405 * @config MONTHS_SHORT
1406 * @type String[]
1407 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
1408 */
1409 this.cfg.addProperty("MONTHS_SHORT",{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.configLocale } );
1410
1411 /**
1412 * The long month labels for the current locale.
1413 * @config MONTHS_LONG
1414 * @type String[]
1415 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
1416 */
1417 this.cfg.addProperty("MONTHS_LONG", { value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.configLocale } );
1418
1419 /**
1420 * The 1-character weekday labels for the current locale.
1421 * @config WEEKDAYS_1CHAR
1422 * @type String[]
1423 * @default ["S", "M", "T", "W", "T", "F", "S"]
1424 */
1425 this.cfg.addProperty("WEEKDAYS_1CHAR",{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.configLocale } );
1426
1427 /**
1428 * The short weekday labels for the current locale.
1429 * @config WEEKDAYS_SHORT
1430 * @type String[]
1431 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
1432 */
1433 this.cfg.addProperty("WEEKDAYS_SHORT",{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.configLocale } );
1434
1435 /**
1436 * The medium weekday labels for the current locale.
1437 * @config WEEKDAYS_MEDIUM
1438 * @type String[]
1439 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
1440 */
1441 this.cfg.addProperty("WEEKDAYS_MEDIUM",{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.configLocale } );
1442
1443 /**
1444 * The long weekday labels for the current locale.
1445 * @config WEEKDAYS_LONG
1446 * @type String[]
1447 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
1448 */
1449 this.cfg.addProperty("WEEKDAYS_LONG",{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.configLocale } );
1450
1451 /**
1452 * Refreshes the locale values used to build the Calendar.
1453 * @method refreshLocale
1454 * @private
1455 */
1456 var refreshLocale = function() {
1457 this.cfg.refireEvent("LOCALE_MONTHS");
1458 this.cfg.refireEvent("LOCALE_WEEKDAYS");
1459 };
1460
1461 this.cfg.subscribeToConfigEvent("START_WEEKDAY", refreshLocale, this, true);
1462 this.cfg.subscribeToConfigEvent("MONTHS_SHORT", refreshLocale, this, true);
1463 this.cfg.subscribeToConfigEvent("MONTHS_LONG", refreshLocale, this, true);
1464 this.cfg.subscribeToConfigEvent("WEEKDAYS_1CHAR", refreshLocale, this, true);
1465 this.cfg.subscribeToConfigEvent("WEEKDAYS_SHORT", refreshLocale, this, true);
1466 this.cfg.subscribeToConfigEvent("WEEKDAYS_MEDIUM", refreshLocale, this, true);
1467 this.cfg.subscribeToConfigEvent("WEEKDAYS_LONG", refreshLocale, this, true);
1468
1469 /**
1470 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
1471 * @config LOCALE_MONTHS
1472 * @type String
1473 * @default "long"
1474 */
1475 this.cfg.addProperty("LOCALE_MONTHS",{ value:"long", handler:this.configLocaleValues } );
1476
1477 /**
1478 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
1479 * @config LOCALE_WEEKDAYS
1480 * @type String
1481 * @default "short"
1482 */
1483 this.cfg.addProperty("LOCALE_WEEKDAYS",{ value:"short", handler:this.configLocaleValues } );
1484
1485 /**
1486 * The value used to delimit individual dates in a date string passed to various Calendar functions.
1487 * @config DATE_DELIMITER
1488 * @type String
1489 * @default ","
1490 */
1491 this.cfg.addProperty("DATE_DELIMITER", { value:",", handler:this.configLocale } );
1492
1493 /**
1494 * The value used to delimit date fields in a date string passed to various Calendar functions.
1495 * @config DATE_FIELD_DELIMITER
1496 * @type String
1497 * @default "/"
1498 */
1499 this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.configLocale } );
1500
1501 /**
1502 * The value used to delimit date ranges in a date string passed to various Calendar functions.
1503 * @config DATE_RANGE_DELIMITER
1504 * @type String
1505 * @default "-"
1506 */
1507 this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.configLocale } );
1508
1509 /**
1510 * The position of the month in a month/year date string
1511 * @config MY_MONTH_POSITION
1512 * @type Number
1513 * @default 1
1514 */
1515 this.cfg.addProperty("MY_MONTH_POSITION",{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
1516
1517 /**
1518 * The position of the year in a month/year date string
1519 * @config MY_YEAR_POSITION
1520 * @type Number
1521 * @default 2
1522 */
1523 this.cfg.addProperty("MY_YEAR_POSITION",{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
1524
1525 /**
1526 * The position of the month in a month/day date string
1527 * @config MD_MONTH_POSITION
1528 * @type Number
1529 * @default 1
1530 */
1531 this.cfg.addProperty("MD_MONTH_POSITION",{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
1532
1533 /**
1534 * The position of the day in a month/year date string
1535 * @config MD_DAY_POSITION
1536 * @type Number
1537 * @default 2
1538 */
1539 this.cfg.addProperty("MD_DAY_POSITION", { value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
1540
1541 /**
1542 * The position of the month in a month/day/year date string
1543 * @config MDY_MONTH_POSITION
1544 * @type Number
1545 * @default 1
1546 */
1547 this.cfg.addProperty("MDY_MONTH_POSITION",{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
1548
1549 /**
1550 * The position of the day in a month/day/year date string
1551 * @config MDY_DAY_POSITION
1552 * @type Number
1553 * @default 2
1554 */
1555 this.cfg.addProperty("MDY_DAY_POSITION",{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
1556
1557 /**
1558 * The position of the year in a month/day/year date string
1559 * @config MDY_YEAR_POSITION
1560 * @type Number
1561 * @default 3
1562 */
1563 this.cfg.addProperty("MDY_YEAR_POSITION",{ value:3, handler:this.configLocale, validator:this.cfg.checkNumber } );
1564};
1565
1566/**
1567* The default handler for the "pagedate" property
1568* @method configPageDate
1569*/
1570YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
1571 var val = args[0];
1572 var month, year, aMonthYear;
1573
1574 if (val) {
1575 if (val instanceof Date) {
1576 val = YAHOO.widget.DateMath.findMonthStart(val);
1577 this.cfg.setProperty("pagedate", val, true);
1578 if (! this._pageDate) {
1579 this._pageDate = this.cfg.getProperty("pagedate");
1580 }
1581 return;
1582 } else {
1583 aMonthYear = val.split(this.cfg.getProperty("DATE_FIELD_DELIMITER"));
1584 month = parseInt(aMonthYear[this.cfg.getProperty("MY_MONTH_POSITION")-1], 10)-1;
1585 year = parseInt(aMonthYear[this.cfg.getProperty("MY_YEAR_POSITION")-1], 10);
1586 }
1587 } else {
1588 month = this.today.getMonth();
1589 year = this.today.getFullYear();
1590 }
1591
1592 this.cfg.setProperty("pagedate", new Date(year, month, 1), true);
1593 if (! this._pageDate) {
1594 this._pageDate = this.cfg.getProperty("pagedate");
1595 }
1596};
1597
1598/**
1599* The default handler for the "mindate" property
1600* @method configMinDate
1601*/
1602YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
1603 var val = args[0];
1604 if (typeof val == 'string') {
1605 val = this._parseDate(val);
1606 this.cfg.setProperty("mindate", new Date(val[0],(val[1]-1),val[2]));
1607 }
1608};
1609
1610/**
1611* The default handler for the "maxdate" property
1612* @method configMaxDate
1613*/
1614YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
1615 var val = args[0];
1616 if (typeof val == 'string') {
1617 val = this._parseDate(val);
1618 this.cfg.setProperty("maxdate", new Date(val[0],(val[1]-1),val[2]));
1619 }
1620};
1621
1622/**
1623* The default handler for the "selected" property
1624* @method configSelected
1625*/
1626YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
1627 var selected = args[0];
1628
1629 if (selected) {
1630 if (typeof selected == 'string') {
1631 this.cfg.setProperty("selected", this._parseDates(selected), true);
1632 }
1633 }
1634 if (! this._selectedDates) {
1635 this._selectedDates = this.cfg.getProperty("selected");
1636 }
1637};
1638
1639/**
1640* The default handler for all configuration options properties
1641* @method configOptions
1642*/
1643YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
1644 type = type.toUpperCase();
1645 var val = args[0];
1646 this.Options[type] = val;
1647};
1648
1649/**
1650* The default handler for all configuration locale properties
1651* @method configLocale
1652*/
1653YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
1654 type = type.toUpperCase();
1655 var val = args[0];
1656 this.Locale[type] = val;
1657
1658 this.cfg.refireEvent("LOCALE_MONTHS");
1659 this.cfg.refireEvent("LOCALE_WEEKDAYS");
1660
1661};
1662
1663/**
1664* The default handler for all configuration locale field length properties
1665* @method configLocaleValues
1666*/
1667YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
1668 type = type.toUpperCase();
1669 var val = args[0];
1670
1671 switch (type) {
1672 case "LOCALE_MONTHS":
1673 switch (val) {
1674 case "short":
1675 this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_SHORT").concat();
1676 break;
1677 case "long":
1678 this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_LONG").concat();
1679 break;
1680 }
1681 break;
1682 case "LOCALE_WEEKDAYS":
1683 switch (val) {
1684 case "1char":
1685 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_1CHAR").concat();
1686 break;
1687 case "short":
1688 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_SHORT").concat();
1689 break;
1690 case "medium":
1691 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_MEDIUM").concat();
1692 break;
1693 case "long":
1694 this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_LONG").concat();
1695 break;
1696 }
1697
1698 var START_WEEKDAY = this.cfg.getProperty("START_WEEKDAY");
1699
1700 if (START_WEEKDAY > 0) {
1701 for (var w=0;w<START_WEEKDAY;++w) {
1702 this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
1703 }
1704 }
1705 break;
1706 }
1707};
1708
1709/**
1710* Defines the style constants for the Calendar
1711* @method initStyles
1712*/
1713YAHOO.widget.Calendar.prototype.initStyles = function() {
1714
1715 /**
1716 * Collection of Style constants for the Calendar
1717 * @property Style
1718 */
1719 this.Style = {
1720 /**
1721 * @property Style.CSS_ROW_HEADER
1722 */
1723 CSS_ROW_HEADER: "calrowhead",
1724 /**
1725 * @property Style.CSS_ROW_FOOTER
1726 */
1727 CSS_ROW_FOOTER: "calrowfoot",
1728 /**
1729 * @property Style.CSS_CELL
1730 */
1731 CSS_CELL : "calcell",
1732 /**
1733 * @property Style.CSS_CELL_SELECTED
1734 */
1735 CSS_CELL_SELECTED : "selected",
1736 /**
1737 * @property Style.CSS_CELL_SELECTABLE
1738 */
1739 CSS_CELL_SELECTABLE : "selectable",
1740 /**
1741 * @property Style.CSS_CELL_RESTRICTED
1742 */
1743 CSS_CELL_RESTRICTED : "restricted",
1744 /**
1745 * @property Style.CSS_CELL_TODAY
1746 */
1747 CSS_CELL_TODAY : "today",
1748 /**
1749 * @property Style.CSS_CELL_OOM
1750 */
1751 CSS_CELL_OOM : "oom",
1752 /**
1753 * @property Style.CSS_CELL_OOB
1754 */
1755 CSS_CELL_OOB : "previous",
1756 /**
1757 * @property Style.CSS_HEADER
1758 */
1759 CSS_HEADER : "calheader",
1760 /**
1761 * @property Style.CSS_HEADER_TEXT
1762 */
1763 CSS_HEADER_TEXT : "calhead",
1764 /**
1765 * @property Style.CSS_WEEKDAY_CELL
1766 */
1767 CSS_WEEKDAY_CELL : "calweekdaycell",
1768 /**
1769 * @property Style.CSS_WEEKDAY_ROW
1770 */
1771 CSS_WEEKDAY_ROW : "calweekdayrow",
1772 /**
1773 * @property Style.CSS_FOOTER
1774 */
1775 CSS_FOOTER : "calfoot",
1776 /**
1777 * @property Style.CSS_CALENDAR
1778 */
1779 CSS_CALENDAR : "yui-calendar",
1780 /**
1781 * @property Style.CSS_SINGLE
1782 */
1783 CSS_SINGLE : "single",
1784 /**
1785 * @property Style.CSS_CONTAINER
1786 */
1787 CSS_CONTAINER : "yui-calcontainer",
1788 /**
1789 * @property Style.CSS_NAV_LEFT
1790 */
1791 CSS_NAV_LEFT : "calnavleft",
1792 /**
1793 * @property Style.CSS_NAV_RIGHT
1794 */
1795 CSS_NAV_RIGHT : "calnavright",
1796 /**
1797 * @property Style.CSS_CELL_TOP
1798 */
1799 CSS_CELL_TOP : "calcelltop",
1800 /**
1801 * @property Style.CSS_CELL_LEFT
1802 */
1803 CSS_CELL_LEFT : "calcellleft",
1804 /**
1805 * @property Style.CSS_CELL_RIGHT
1806 */
1807 CSS_CELL_RIGHT : "calcellright",
1808 /**
1809 * @property Style.CSS_CELL_BOTTOM
1810 */
1811 CSS_CELL_BOTTOM : "calcellbottom",
1812 /**
1813 * @property Style.CSS_CELL_HOVER
1814 */
1815 CSS_CELL_HOVER : "calcellhover",
1816 /**
1817 * @property Style.CSS_CELL_HIGHLIGHT1
1818 */
1819 CSS_CELL_HIGHLIGHT1 : "highlight1",
1820 /**
1821 * @property Style.CSS_CELL_HIGHLIGHT2
1822 */
1823 CSS_CELL_HIGHLIGHT2 : "highlight2",
1824 /**
1825 * @property Style.CSS_CELL_HIGHLIGHT3
1826 */
1827 CSS_CELL_HIGHLIGHT3 : "highlight3",
1828 /**
1829 * @property Style.CSS_CELL_HIGHLIGHT4
1830 */
1831 CSS_CELL_HIGHLIGHT4 : "highlight4"
1832 };
1833};
1834
1835/**
1836* Builds the date label that will be displayed in the calendar header or
1837* footer, depending on configuration.
1838* @method buildMonthLabel
1839 * @return {String}The formatted calendar month label
1840*/
1841YAHOO.widget.Calendar.prototype.buildMonthLabel = function() {
1842 var text = this.Locale.LOCALE_MONTHS[this.cfg.getProperty("pagedate").getMonth()] + " " + this.cfg.getProperty("pagedate").getFullYear();
1843 return text;
1844};
1845
1846/**
1847* Builds the date digit that will be displayed in calendar cells
1848* @method buildDayLabel
1849 * @param {Date} workingDateThe current working date
1850 * @return {String}The formatted day label
1851*/
1852YAHOO.widget.Calendar.prototype.buildDayLabel = function(workingDate) {
1853 var day = workingDate.getDate();
1854 return day;
1855};
1856
1857/**
1858* Renders the calendar header.
1859* @method renderHeader
1860 * @param {Array} htmlThe current working HTML array
1861* @return {Array} The current working HTML array
1862*/
1863YAHOO.widget.Calendar.prototype.renderHeader = function(html) {
1864 var colSpan = 7;
1865
1866 if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
1867 colSpan += 1;
1868 }
1869
1870 if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
1871 colSpan += 1;
1872 }
1873
1874 html[html.length] = "<thead>";
1875 html[html.length] = "<tr>";
1876 html[html.length] = '<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
1877 html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
1878
1879 var renderLeft, renderRight = false;
1880
1881 if (this.parent) {
1882 if (this.index === 0) {
1883 renderLeft = true;
1884 }
1885 if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
1886 renderRight = true;
1887 }
1888 } else {
1889 renderLeft = true;
1890 renderRight = true;
1891 }
1892
1893 var cal = this.parent || this;
1894
1895 if (renderLeft) {
1896 html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_LEFT") + ')">&#160;</a>';
1897 }
1898
1899 html[html.length] = this.buildMonthLabel();
1900
1901 if (renderRight) {
1902 html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_RIGHT") + ')">&#160;</a>';
1903 }
1904
1905
1906 html[html.length] = '</div>';
1907 html[html.length] = '</th>';
1908 html[html.length] = '</tr>';
1909
1910 if (this.cfg.getProperty("SHOW_WEEKDAYS")) {
1911 html = this.buildWeekdays(html);
1912 }
1913
1914 html[html.length] = '</thead>';
1915
1916 return html;
1917};
1918
1919/**
1920* Renders the Calendar's weekday headers.
1921* @method buildWeekdays
1922 * @param {Array} htmlThe current working HTML array
1923* @return {Array} The current working HTML array
1924*/
1925YAHOO.widget.Calendar.prototype.buildWeekdays = function(html) {
1926
1927 html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
1928
1929 if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
1930 html[html.length] = '<th>&#160;</th>';
1931 }
1932
1933 for(var i=0;i<this.Locale.LOCALE_WEEKDAYS.length;++i) {
1934 html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
1935 }
1936
1937 if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
1938 html[html.length] = '<th>&#160;</th>';
1939 }
1940
1941 html[html.length] = '</tr>';
1942
1943 return html;
1944};
1945
1946/**
1947* Renders the calendar body.
1948* @method renderBody
1949 * @param {Date} workingDateThe current working Date being used for the render process
1950 * @param {Array} htmlThe current working HTML array
1951* @return {Array} The current working HTML array
1952*/
1953YAHOO.widget.Calendar.prototype.renderBody = function(workingDate, html) {
1954
1955 var startDay = this.cfg.getProperty("START_WEEKDAY");
1956
1957 this.preMonthDays = workingDate.getDay();
1958 if (startDay > 0) {
1959 this.preMonthDays -= startDay;
1960 }
1961 if (this.preMonthDays < 0) {
1962 this.preMonthDays += 7;
1963 }
1964
1965 this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
1966 this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
1967
1968 workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
1969
1970 var useDate,weekNum,weekClass;
1971 useDate = this.cfg.getProperty("pagedate");
1972
1973 html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + '">';
1974
1975 var i = 0;
1976
1977 var tempDiv = document.createElement("div");
1978 var cell = document.createElement("td");
1979 tempDiv.appendChild(cell);
1980
1981 var jan1 = new Date(useDate.getFullYear(),0,1);
1982
1983 var cal = this.parent || this;
1984
1985 for (var r=0;r<6;r++) {
1986
1987 weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
1988
1989 weekClass = "w" + weekNum;
1990
1991 if (r !== 0 && this.isDateOOM(workingDate) && this.cfg.getProperty("HIDE_BLANK_WEEKS") === true) {
1992 break;
1993 } else {
1994
1995 html[html.length] = '<tr class="' + weekClass + '">';
1996
1997 if (this.cfg.getProperty("SHOW_WEEK_HEADER")) { html = this.renderRowHeader(weekNum, html); }
1998
1999 for (var d=0;d<7;d++){ // Render actual days
2000
2001 var cellRenderers = [];
2002
2003 this.clearElement(cell);
2004
2005 YAHOO.util.Dom.addClass(cell, "calcell");
2006
2007 cell.id = this.id + "_cell" + i;
2008
2009 cell.innerHTML = i;
2010
2011 var renderer = null;
2012
2013 if (workingDate.getFullYear()== this.today.getFullYear() &&
2014 workingDate.getMonth() == this.today.getMonth() &&
2015 workingDate.getDate() == this.today.getDate()) {
2016 cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
2017 }
2018
2019 this.cellDates[this.cellDates.length]=[workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]; // Add this date to cellDates
2020
2021 if (this.isDateOOM(workingDate)) {
2022 cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
2023 } else {
2024
2025 YAHOO.util.Dom.addClass(cell, "wd" + workingDate.getDay());
2026 YAHOO.util.Dom.addClass(cell, "d" + workingDate.getDate());
2027
2028 for (var s=0;s<this.renderStack.length;++s) {
2029
2030 var rArray = this.renderStack[s];
2031 var type = rArray[0];
2032
2033 var month;
2034 var day;
2035 var year;
2036
2037 switch (type) {
2038 case YAHOO.widget.Calendar.DATE:
2039 month = rArray[1][1];
2040 day = rArray[1][2];
2041 year = rArray[1][0];
2042
2043 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
2044 renderer = rArray[2];
2045 this.renderStack.splice(s,1);
2046 }
2047 break;
2048 case YAHOO.widget.Calendar.MONTH_DAY:
2049 month = rArray[1][0];
2050 day = rArray[1][1];
2051
2052 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
2053 renderer = rArray[2];
2054 this.renderStack.splice(s,1);
2055 }
2056 break;
2057 case YAHOO.widget.Calendar.RANGE:
2058 var date1 = rArray[1][0];
2059 var date2 = rArray[1][1];
2060
2061 var d1month = date1[1];
2062 var d1day = date1[2];
2063 var d1year = date1[0];
2064
2065 var d1 = new Date(d1year, d1month-1, d1day);
2066
2067 var d2month = date2[1];
2068 var d2day = date2[2];
2069 var d2year = date2[0];
2070
2071 var d2 = new Date(d2year, d2month-1, d2day);
2072
2073 if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
2074 renderer = rArray[2];
2075
2076 if (workingDate.getTime()==d2.getTime()) {
2077 this.renderStack.splice(s,1);
2078 }
2079 }
2080 break;
2081 case YAHOO.widget.Calendar.WEEKDAY:
2082
2083 var weekday = rArray[1][0];
2084 if (workingDate.getDay()+1 == weekday) {
2085 renderer = rArray[2];
2086 }
2087 break;
2088 case YAHOO.widget.Calendar.MONTH:
2089
2090 month = rArray[1][0];
2091 if (workingDate.getMonth()+1 == month) {
2092 renderer = rArray[2];
2093 }
2094 break;
2095 }
2096
2097 if (renderer) {
2098 cellRenderers[cellRenderers.length]=renderer;
2099 }
2100 }
2101
2102 }
2103
2104 if (this._indexOfSelectedFieldArray([workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]) > -1) {
2105 cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
2106 }
2107
2108 var mindate = this.cfg.getProperty("mindate");
2109 var maxdate = this.cfg.getProperty("maxdate");
2110
2111 if (mindate) {
2112 mindate = YAHOO.widget.DateMath.clearTime(mindate);
2113 }
2114 if (maxdate) {
2115 maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
2116 }
2117
2118 if (
2119 (mindate && (workingDate.getTime() < mindate.getTime())) ||
2120 (maxdate && (workingDate.getTime() > maxdate.getTime()))
2121 ) {
2122 cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
2123 } else {
2124 cellRenderers[cellRenderers.length]=cal.styleCellDefault;
2125 cellRenderers[cellRenderers.length]=cal.renderCellDefault;
2126 }
2127
2128
2129
2130 for (var x=0;x<cellRenderers.length;++x) {
2131 var ren = cellRenderers[x];
2132 if (ren.call((this.parent || this),workingDate,cell) == YAHOO.widget.Calendar.STOP_RENDER) {
2133 break;
2134 }
2135 }
2136
2137 workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
2138
2139 if (i >= 0 && i <= 6) {
2140 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
2141 }
2142 if ((i % 7) === 0) {
2143 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
2144 }
2145 if (((i+1) % 7) === 0) {
2146 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
2147 }
2148
2149 var postDays = this.postMonthDays;
2150 if (postDays >= 7 && this.cfg.getProperty("HIDE_BLANK_WEEKS")) {
2151 var blankWeeks = Math.floor(postDays/7);
2152 for (var p=0;p<blankWeeks;++p) {
2153 postDays -= 7;
2154 }
2155 }
2156
2157 if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
2158 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
2159 }
2160
2161 html[html.length] = tempDiv.innerHTML;
2162
2163 i++;
2164 }
2165
2166 if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) { html = this.renderRowFooter(weekNum, html); }
2167
2168 html[html.length] = '</tr>';
2169 }
2170 }
2171
2172 html[html.length] = '</tbody>';
2173
2174 return html;
2175};
2176
2177/**
2178* Renders the calendar footer. In the default implementation, there is
2179* no footer.
2180* @method renderFooter
2181 * @param {Array} htmlThe current working HTML array
2182* @return {Array} The current working HTML array
2183*/
2184YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };
2185
2186/**
2187* Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
2188* when the method is called: renderHeader, renderBody, renderFooter.
2189* Refer to the documentation for those methods for information on
2190* individual render tasks.
2191* @method render
2192*/
2193YAHOO.widget.Calendar.prototype.render = function() {
2194 this.beforeRenderEvent.fire();
2195
2196 // Find starting day of the current month
2197 var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty("pagedate"));
2198
2199 this.resetRenderers();
2200 this.cellDates.length = 0;
2201
2202 YAHOO.util.Event.purgeElement(this.oDomContainer, true);
2203
2204 var html = [];
2205
2206 html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
2207 html = this.renderHeader(html);
2208 html = this.renderBody(workingDate, html);
2209 html = this.renderFooter(html);
2210 html[html.length] = '</table>';
2211
2212 this.oDomContainer.innerHTML = html.join("\n");
2213
2214 this.applyListeners();
2215 this.cells = this.oDomContainer.getElementsByTagName("td");
2216
2217 this.cfg.refireEvent("title");
2218 this.cfg.refireEvent("close");
2219 this.cfg.refireEvent("iframe");
2220
2221 this.renderEvent.fire();
2222};
2223
2224/**
2225* Applies the Calendar's DOM listeners to applicable elements.
2226* @method applyListeners
2227*/
2228YAHOO.widget.Calendar.prototype.applyListeners = function() {
2229
2230 var root = this.oDomContainer;
2231 var cal = this.parent || this;
2232
2233 var linkLeft, linkRight;
2234
2235 linkLeft = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, "a", root);
2236 linkRight = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, "a", root);
2237
2238 if (linkLeft) {
2239 this.linkLeft = linkLeft[0];
2240 YAHOO.util.Event.addListener(this.linkLeft, "mousedown", cal.previousMonth, cal, true);
2241 }
2242
2243 if (linkRight) {
2244 this.linkRight = linkRight[0];
2245 YAHOO.util.Event.addListener(this.linkRight, "mousedown", cal.nextMonth, cal, true);
2246 }
2247
2248 if (this.domEventMap) {
2249 var el,elements;
2250 for (var cls in this.domEventMap) {
2251 if (this.domEventMap.hasOwnProperty(cls)) {
2252 var items = this.domEventMap[cls];
2253
2254 if (! (items instanceof Array)) {
2255 items = [items];
2256 }
2257
2258 for (var i=0;i<items.length;i++){
2259 var item = items[i];
2260 elements = YAHOO.util.Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
2261
2262 for (var c=0;c<elements.length;c++) {
2263 el = elements[c];
2264 YAHOO.util.Event.addListener(el, item.event, item.handler, item.scope, item.correct );
2265 }
2266 }
2267 }
2268 }
2269 }
2270
2271 YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
2272 YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
2273 YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
2274};
2275
2276/**
2277* Retrieves the Date object for the specified Calendar cell
2278* @method getDateByCellId
2279 * @param {String} idThe id of the cell
2280* @return {Date} The Date object for the specified Calendar cell
2281*/
2282YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
2283 var date = this.getDateFieldsByCellId(id);
2284 return new Date(date[0],date[1]-1,date[2]);
2285};
2286
2287/**
2288* Retrieves the Date object for the specified Calendar cell
2289* @method getDateFieldsByCellId
2290 * @param {String} idThe id of the cell
2291 * @return {Array}The array of Date fields for the specified Calendar cell
2292*/
2293YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
2294 id = id.toLowerCase().split("_cell")[1];
2295 id = parseInt(id, 10);
2296 return this.cellDates[id];
2297};
2298
2299// BEGIN BUILT-IN TABLE CELL RENDERERS
2300
2301/**
2302* Renders a cell that falls before the minimum date or after the maximum date.
2303* widget class.
2304* @method renderOutOfBoundsDate
2305 * @param {Date} workingDate The current working Date object being used to generate the calendar
2306 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2307* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2308 * should not be terminated
2309*/
2310YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
2311 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
2312 cell.innerHTML = workingDate.getDate();
2313 return YAHOO.widget.Calendar.STOP_RENDER;
2314};
2315
2316/**
2317* Renders the row header for a week.
2318* @method renderRowHeader
2319 * @param {Number} weekNumThe week number of the current row
2320 * @param {Array} cellThe current working HTML array
2321*/
2322YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
2323 html[html.length] = '<th class="calrowhead">' + weekNum + '</th>';
2324 return html;
2325};
2326
2327/**
2328* Renders the row footer for a week.
2329* @method renderRowFooter
2330 * @param {Number} weekNumThe week number of the current row
2331 * @param {Array} cellThe current working HTML array
2332*/
2333YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
2334 html[html.length] = '<th class="calrowfoot">' + weekNum + '</th>';
2335 return html;
2336};
2337
2338/**
2339* Renders a single standard calendar cell in the calendar widget table.
2340* All logic for determining how a standard default cell will be rendered is
2341* encapsulated in this method, and must be accounted for when extending the
2342* widget class.
2343* @method renderCellDefault
2344 * @param {Date} workingDate The current working Date object being used to generate the calendar
2345 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2346*/
2347YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
2348 cell.innerHTML = '<a href="javascript:void(null);" >' + this.buildDayLabel(workingDate) + "</a>";
2349};
2350
2351/**
2352* Styles a selectable cell.
2353* @method styleCellDefault
2354 * @param {Date} workingDate The current working Date object being used to generate the calendar
2355 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2356*/
2357YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
2358 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
2359};
2360
2361
2362/**
2363* Renders a single standard calendar cell using the CSS hightlight1 style
2364* @method renderCellStyleHighlight1
2365 * @param {Date} workingDate The current working Date object being used to generate the calendar
2366 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2367*/
2368YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
2369 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
2370};
2371
2372/**
2373* Renders a single standard calendar cell using the CSS hightlight2 style
2374* @method renderCellStyleHighlight2
2375 * @param {Date} workingDate The current working Date object being used to generate the calendar
2376 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2377*/
2378YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
2379 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
2380};
2381
2382/**
2383* Renders a single standard calendar cell using the CSS hightlight3 style
2384* @method renderCellStyleHighlight3
2385 * @param {Date} workingDate The current working Date object being used to generate the calendar
2386 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2387*/
2388YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
2389 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
2390};
2391
2392/**
2393* Renders a single standard calendar cell using the CSS hightlight4 style
2394* @method renderCellStyleHighlight4
2395 * @param {Date} workingDate The current working Date object being used to generate the calendar
2396 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2397*/
2398YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
2399 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
2400};
2401
2402/**
2403* Applies the default style used for rendering today's date to the current calendar cell
2404* @method renderCellStyleToday
2405 * @param {Date} workingDate The current working Date object being used to generate the calendar
2406 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2407*/
2408YAHOO.widget.Calendar.prototype.renderCellStyleToday = function(workingDate, cell) {
2409 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
2410};
2411
2412/**
2413* Applies the default style used for rendering selected dates to the current calendar cell
2414* @method renderCellStyleSelected
2415 * @param {Date} workingDate The current working Date object being used to generate the calendar
2416 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2417* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2418 * should not be terminated
2419*/
2420YAHOO.widget.Calendar.prototype.renderCellStyleSelected = function(workingDate, cell) {
2421 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
2422};
2423
2424/**
2425* Applies the default style used for rendering dates that are not a part of the current
2426* month (preceding or trailing the cells for the current month)
2427* @method renderCellNotThisMonth
2428 * @param {Date} workingDate The current working Date object being used to generate the calendar
2429 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2430* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2431 * should not be terminated
2432*/
2433YAHOO.widget.Calendar.prototype.renderCellNotThisMonth = function(workingDate, cell) {
2434 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
2435 cell.innerHTML=workingDate.getDate();
2436 return YAHOO.widget.Calendar.STOP_RENDER;
2437};
2438
2439/**
2440* Renders the current calendar cell as a non-selectable "black-out" date using the default
2441* restricted style.
2442* @method renderBodyCellRestricted
2443 * @param {Date} workingDate The current working Date object being used to generate the calendar
2444 * @param {HTMLTableCellElement} cell The current working cell in the calendar
2445* @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
2446 * should not be terminated
2447*/
2448YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
2449 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
2450 YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
2451 cell.innerHTML=workingDate.getDate();
2452 return YAHOO.widget.Calendar.STOP_RENDER;
2453};
2454
2455// END BUILT-IN TABLE CELL RENDERERS
2456
2457// BEGIN MONTH NAVIGATION METHODS
2458
2459/**
2460* Adds the designated number of months to the current calendar month, and sets the current
2461* calendar page date to the new month.
2462* @method addMonths
2463 * @param {Number} countThe number of months to add to the current calendar
2464*/
2465YAHOO.widget.Calendar.prototype.addMonths = function(count) {
2466 this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
2467 this.resetRenderers();
2468 this.changePageEvent.fire();
2469};
2470
2471/**
2472* Subtracts the designated number of months from the current calendar month, and sets the current
2473* calendar page date to the new month.
2474* @method subtractMonths
2475 * @param {Number} countThe number of months to subtract from the current calendar
2476*/
2477YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
2478 this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
2479 this.resetRenderers();
2480 this.changePageEvent.fire();
2481};
2482
2483/**
2484* Adds the designated number of years to the current calendar, and sets the current
2485* calendar page date to the new month.
2486* @method addYears
2487 * @param {Number} countThe number of years to add to the current calendar
2488*/
2489YAHOO.widget.Calendar.prototype.addYears = function(count) {
2490 this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
2491 this.resetRenderers();
2492 this.changePageEvent.fire();
2493};
2494
2495/**
2496* Subtcats the designated number of years from the current calendar, and sets the current
2497* calendar page date to the new month.
2498* @method subtractYears
2499 * @param {Number} countThe number of years to subtract from the current calendar
2500*/
2501YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
2502 this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
2503 this.resetRenderers();
2504 this.changePageEvent.fire();
2505};
2506
2507/**
2508* Navigates to the next month page in the calendar widget.
2509* @method nextMonth
2510*/
2511YAHOO.widget.Calendar.prototype.nextMonth = function() {
2512 this.addMonths(1);
2513};
2514
2515/**
2516* Navigates to the previous month page in the calendar widget.
2517* @method previousMonth
2518*/
2519YAHOO.widget.Calendar.prototype.previousMonth = function() {
2520 this.subtractMonths(1);
2521};
2522
2523/**
2524* Navigates to the next year in the currently selected month in the calendar widget.
2525* @method nextYear
2526*/
2527YAHOO.widget.Calendar.prototype.nextYear = function() {
2528 this.addYears(1);
2529};
2530
2531/**
2532* Navigates to the previous year in the currently selected month in the calendar widget.
2533* @method previousYear
2534*/
2535YAHOO.widget.Calendar.prototype.previousYear = function() {
2536 this.subtractYears(1);
2537};
2538
2539// END MONTH NAVIGATION METHODS
2540
2541// BEGIN SELECTION METHODS
2542
2543/**
2544* Resets the calendar widget to the originally selected month and year, and
2545* sets the calendar to the initial selection(s).
2546* @method reset
2547*/
2548YAHOO.widget.Calendar.prototype.reset = function() {
2549 this.cfg.resetProperty("selected");
2550 this.cfg.resetProperty("pagedate");
2551 this.resetEvent.fire();
2552};
2553
2554/**
2555* Clears the selected dates in the current calendar widget and sets the calendar
2556* to the current month and year.
2557* @method clear
2558*/
2559YAHOO.widget.Calendar.prototype.clear = function() {
2560 this.cfg.setProperty("selected", []);
2561 this.cfg.setProperty("pagedate", new Date(this.today.getTime()));
2562 this.clearEvent.fire();
2563};
2564
2565/**
2566* Selects a date or a collection of dates on the current calendar. This method, by default,
2567* does not call the render method explicitly. Once selection has completed, render must be
2568* called for the changes to be reflected visually.
2569* @method select
2570 * @param {String/Date/Date[]} dateThe date string of dates to select in the current calendar. Valid formats are
2571 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
2572 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
2573 * This method can also take a JavaScript Date object or an array of Date objects.
2574 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
2575*/
2576YAHOO.widget.Calendar.prototype.select = function(date) {
2577 this.beforeSelectEvent.fire();
2578
2579 var selected = this.cfg.getProperty("selected");
2580 var aToBeSelected = this._toFieldArray(date);
2581
2582 for (var a=0;a<aToBeSelected.length;++a) {
2583 var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
2584 if (this._indexOfSelectedFieldArray(toSelect) == -1) { // not already selected?
2585 selected[selected.length]=toSelect;
2586 }
2587 }
2588
2589 if (this.parent) {
2590 this.parent.cfg.setProperty("selected", selected);
2591 } else {
2592 this.cfg.setProperty("selected", selected);
2593 }
2594
2595 this.selectEvent.fire(aToBeSelected);
2596
2597 return this.getSelectedDates();
2598};
2599
2600/**
2601* Selects a date on the current calendar by referencing the index of the cell that should be selected.
2602* This method is used to easily select a single cell (usually with a mouse click) without having to do
2603* a full render. The selected style is applied to the cell directly.
2604* @method selectCell
2605 * @param {Number} cellIndexThe index of the cell to select in the current calendar.
2606 * @return {Date[]}Array of JavaScript Date objects representing all individual dates that are currently selected.
2607*/
2608YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
2609 this.beforeSelectEvent.fire();
2610
2611 var selected = this.cfg.getProperty("selected");
2612
2613 var cell = this.cells[cellIndex];
2614 var cellDate = this.cellDates[cellIndex];
2615
2616 var dCellDate = this._toDate(cellDate);
2617
2618 var selectDate = cellDate.concat();
2619
2620 selected[selected.length] = selectDate;
2621
2622 if (this.parent) {
2623 this.parent.cfg.setProperty("selected", selected);
2624 } else {
2625 this.cfg.setProperty("selected", selected);
2626 }
2627
2628 this.renderCellStyleSelected(dCellDate,cell);
2629
2630 this.selectEvent.fire([selectDate]);
2631
2632 this.doCellMouseOut.call(cell, null, this);
2633
2634 return this.getSelectedDates();
2635};
2636
2637/**
2638* Deselects a date or a collection of dates on the current calendar. This method, by default,
2639* does not call the render method explicitly. Once deselection has completed, render must be
2640* called for the changes to be reflected visually.
2641* @method deselect
2642 * @param {String/Date/Date[]} dateThe date string of dates to deselect in the current calendar. Valid formats are
2643 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
2644 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
2645 * This method can also take a JavaScript Date object or an array of Date objects.
2646 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
2647*/
2648YAHOO.widget.Calendar.prototype.deselect = function(date) {
2649 this.beforeDeselectEvent.fire();
2650
2651 var selected = this.cfg.getProperty("selected");
2652
2653 var aToBeSelected = this._toFieldArray(date);
2654
2655 for (var a=0;a<aToBeSelected.length;++a) {
2656 var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
2657 var index = this._indexOfSelectedFieldArray(toSelect);
2658
2659 if (index != -1) {
2660 selected.splice(index,1);
2661 }
2662 }
2663
2664 if (this.parent) {
2665 this.parent.cfg.setProperty("selected", selected);
2666 } else {
2667 this.cfg.setProperty("selected", selected);
2668 }
2669
2670 this.deselectEvent.fire(aToBeSelected);
2671
2672 return this.getSelectedDates();
2673};
2674
2675/**
2676* Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
2677* This method is used to easily deselect a single cell (usually with a mouse click) without having to do
2678* a full render. The selected style is removed from the cell directly.
2679* @method deselectCell
2680 * @param {Number} cellIndexThe index of the cell to deselect in the current calendar.
2681 * @return {Date[]}Array of JavaScript Date objects representing all individual dates that are currently selected.
2682*/
2683YAHOO.widget.Calendar.prototype.deselectCell = function(i) {
2684 this.beforeDeselectEvent.fire();
2685
2686 var selected = this.cfg.getProperty("selected");
2687
2688 var cell = this.cells[i];
2689 var cellDate = this.cellDates[i];
2690 var cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
2691
2692 var dCellDate = this._toDate(cellDate);
2693
2694 var selectDate = cellDate.concat();
2695
2696 if (cellDateIndex > -1) {
2697 if (this.cfg.getProperty("pagedate").getMonth() == dCellDate.getMonth() &&
2698 this.cfg.getProperty("pagedate").getFullYear() == dCellDate.getFullYear()) {
2699 YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
2700 }
2701
2702 selected.splice(cellDateIndex, 1);
2703 }
2704
2705
2706 if (this.parent) {
2707 this.parent.cfg.setProperty("selected", selected);
2708 } else {
2709 this.cfg.setProperty("selected", selected);
2710 }
2711
2712 this.deselectEvent.fire(selectDate);
2713 return this.getSelectedDates();
2714};
2715
2716/**
2717* Deselects all dates on the current calendar.
2718* @method deselectAll
2719 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
2720 * Assuming that this function executes properly, the return value should be an empty array.
2721 * However, the empty array is returned for the sake of being able to check the selection status
2722 * of the calendar.
2723*/
2724YAHOO.widget.Calendar.prototype.deselectAll = function() {
2725 this.beforeDeselectEvent.fire();
2726
2727 var selected = this.cfg.getProperty("selected");
2728 var count = selected.length;
2729 var sel = selected.concat();
2730
2731 if (this.parent) {
2732 this.parent.cfg.setProperty("selected", []);
2733 } else {
2734 this.cfg.setProperty("selected", []);
2735 }
2736
2737 if (count > 0) {
2738 this.deselectEvent.fire(sel);
2739 }
2740
2741 return this.getSelectedDates();
2742};
2743
2744// END SELECTION METHODS
2745
2746// BEGIN TYPE CONVERSION METHODS
2747
2748/**
2749* Converts a date (either a JavaScript Date object, or a date string) to the internal data structure
2750* used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]].
2751* @method _toFieldArray
2752* @private
2753 * @param {String/Date/Date[]} dateThe date string of dates to deselect in the current calendar. Valid formats are
2754 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
2755 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
2756 * This method can also take a JavaScript Date object or an array of Date objects.
2757 * @return {Array[](Number[])}Array of date field arrays
2758*/
2759YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
2760 var returnDate = [];
2761
2762 if (date instanceof Date) {
2763 returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
2764 } else if (typeof date == 'string') {
2765 returnDate = this._parseDates(date);
2766 } else if (date instanceof Array) {
2767 for (var i=0;i<date.length;++i) {
2768 var d = date[i];
2769 returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
2770 }
2771 }
2772
2773 return returnDate;
2774};
2775
2776/**
2777* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
2778* @method _toDate
2779* @private
2780 * @param {Number[]} dateFieldArrayThe date field array to convert to a JavaScript Date.
2781 * @return {Date}JavaScript Date object representing the date field array
2782*/
2783YAHOO.widget.Calendar.prototype._toDate = function(dateFieldArray) {
2784 if (dateFieldArray instanceof Date) {
2785 return dateFieldArray;
2786 } else {
2787 return new Date(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
2788 }
2789};
2790
2791// END TYPE CONVERSION METHODS
2792
2793// BEGIN UTILITY METHODS
2794
2795/**
2796* Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
2797* @method _fieldArraysAreEqual
2798* @private
2799 * @param {Number[]} array1The first date field array to compare
2800 * @param {Number[]} array2The first date field array to compare
2801 * @return {Boolean}The boolean that represents the equality of the two arrays
2802*/
2803YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
2804 var match = false;
2805
2806 if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
2807 match=true;
2808 }
2809
2810 return match;
2811};
2812
2813/**
2814* Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
2815 * @method_indexOfSelectedFieldArray
2816* @private
2817 * @param {Number[]} findThe date field array to search for
2818 * @return {Number} The index of the date field array within the collection of selected dates.
2819 * -1 will be returned if the date is not found.
2820*/
2821YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
2822 var selected = -1;
2823 var seldates = this.cfg.getProperty("selected");
2824
2825 for (var s=0;s<seldates.length;++s) {
2826 var sArray = seldates[s];
2827 if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
2828 selected = s;
2829 break;
2830 }
2831 }
2832
2833 return selected;
2834};
2835
2836/**
2837* Determines whether a given date is OOM (out of month).
2838 * @methodisDateOOM
2839 * @param {Date} dateThe JavaScript Date object for which to check the OOM status
2840 * @return {Boolean}true if the date is OOM
2841*/
2842YAHOO.widget.Calendar.prototype.isDateOOM = function(date) {
2843 var isOOM = false;
2844 if (date.getMonth() != this.cfg.getProperty("pagedate").getMonth()) {
2845 isOOM = true;
2846 }
2847 return isOOM;
2848};
2849
2850// END UTILITY METHODS
2851
2852// BEGIN EVENT HANDLERS
2853
2854/**
2855* Event executed before a date is selected in the calendar widget.
2856* @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
2857*/
2858YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
2859 if (this.cfg.getProperty("MULTI_SELECT") === false) {
2860 if (this.parent) {
2861 this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
2862 this.parent.deselectAll();
2863 } else {
2864 this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
2865 this.deselectAll();
2866 }
2867 }
2868};
2869
2870/**
2871* Event executed when a date is selected in the calendar widget.
2872 * @param {Array} selectedAn array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
2873* @deprecated Event handlers for this event should be susbcribed to selectEvent.
2874*/
2875YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };
2876
2877/**
2878* Event executed before a date is deselected in the calendar widget.
2879* @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
2880*/
2881YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };
2882
2883/**
2884* Event executed when a date is deselected in the calendar widget.
2885 * @param {Array} selectedAn array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
2886* @deprecated Event handlers for this event should be susbcribed to deselectEvent.
2887*/
2888YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };
2889
2890/**
2891* Event executed when the user navigates to a different calendar page.
2892* @deprecated Event handlers for this event should be susbcribed to changePageEvent.
2893*/
2894YAHOO.widget.Calendar.prototype.onChangePage = function() {
2895 this.render();
2896};
2897
2898/**
2899* Event executed when the calendar widget is rendered.
2900* @deprecated Event handlers for this event should be susbcribed to renderEvent.
2901*/
2902YAHOO.widget.Calendar.prototype.onRender = function() { };
2903
2904/**
2905* Event executed when the calendar widget is reset to its original state.
2906* @deprecated Event handlers for this event should be susbcribed to resetEvemt.
2907*/
2908YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };
2909
2910/**
2911* Event executed when the calendar widget is completely cleared to the current month with no selections.
2912* @deprecated Event handlers for this event should be susbcribed to clearEvent.
2913*/
2914YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };
2915
2916/**
2917* Validates the calendar widget. This method has no default implementation
2918* and must be extended by subclassing the widget.
2919 * @returnShould return true if the widget validates, and false if
2920* it doesn't.
2921* @type Boolean
2922*/
2923YAHOO.widget.Calendar.prototype.validate = function() { return true; };
2924
2925// END EVENT HANDLERS
2926
2927// BEGIN DATE PARSE METHODS
2928
2929/**
2930* Converts a date string to a date field array
2931* @private
2932 * @param {String} sDate Date string. Valid formats are mm/dd and mm/dd/yyyy.
2933 * @return A date field array representing the string passed to the method
2934* @type Array[](Number[])
2935*/
2936YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
2937 var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
2938 var rArray;
2939
2940 if (aDate.length == 2) {
2941 rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
2942 rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
2943 } else {
2944 rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
2945 rArray.type = YAHOO.widget.Calendar.DATE;
2946 }
2947
2948 for (var i=0;i<rArray.length;i++) {
2949 rArray[i] = parseInt(rArray[i], 10);
2950 }
2951
2952 return rArray;
2953};
2954
2955/**
2956* Converts a multi or single-date string to an array of date field arrays
2957* @private
2958 * @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
2959 * @return An array of date field arrays
2960* @type Array[](Number[])
2961*/
2962YAHOO.widget.Calendar.prototype._parseDates = function(sDates) {
2963 var aReturn = [];
2964
2965 var aDates = sDates.split(this.Locale.DATE_DELIMITER);
2966
2967 for (var d=0;d<aDates.length;++d) {
2968 var sDate = aDates[d];
2969
2970 if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
2971 // This is a range
2972 var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER);
2973
2974 var dateStart = this._parseDate(aRange[0]);
2975 var dateEnd = this._parseDate(aRange[1]);
2976
2977 var fullRange = this._parseRange(dateStart, dateEnd);
2978 aReturn = aReturn.concat(fullRange);
2979 } else {
2980 // This is not a range
2981 var aDate = this._parseDate(sDate);
2982 aReturn.push(aDate);
2983 }
2984 }
2985 return aReturn;
2986};
2987
2988/**
2989* Converts a date range to the full list of included dates
2990* @private
2991 * @param {Number[]} startDateDate field array representing the first date in the range
2992 * @param {Number[]} endDate Date field array representing the last date in the range
2993 * @return An array of date field arrays
2994* @type Array[](Number[])
2995*/
2996YAHOO.widget.Calendar.prototype._parseRange = function(startDate, endDate) {
2997 var dStart = new Date(startDate[0],startDate[1]-1,startDate[2]);
2998 var dCurrent = YAHOO.widget.DateMath.add(new Date(startDate[0],startDate[1]-1,startDate[2]),YAHOO.widget.DateMath.DAY,1);
2999 var dEnd = new Date(endDate[0], endDate[1]-1, endDate[2]);
3000
3001 var results = [];
3002 results.push(startDate);
3003 while (dCurrent.getTime() <= dEnd.getTime()) {
3004 results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
3005 dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
3006 }
3007 return results;
3008};
3009
3010// END DATE PARSE METHODS
3011
3012// BEGIN RENDERER METHODS
3013
3014/**
3015* Resets the render stack of the current calendar to its original pre-render value.
3016*/
3017YAHOO.widget.Calendar.prototype.resetRenderers = function() {
3018 this.renderStack = this._renderStack.concat();
3019};
3020
3021/**
3022* Clears the inner HTML, CSS class and style information from the specified cell.
3023* @method clearElement
3024 * @param {HTMLTableCellElement}The cell to clear
3025*/
3026YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
3027 cell.innerHTML = "&#160;";
3028 cell.className="";
3029};
3030
3031/**
3032* Adds a renderer to the render stack. The function reference passed to this method will be executed
3033* when a date cell matches the conditions specified in the date string for this renderer.
3034* @method addRenderer
3035 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
3036 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
3037 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
3038*/
3039YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
3040 var aDates = this._parseDates(sDates);
3041 for (var i=0;i<aDates.length;++i) {
3042 var aDate = aDates[i];
3043
3044 if (aDate.length == 2) { // this is either a range or a month/day combo
3045 if (aDate[0] instanceof Array) { // this is a range
3046 this._addRenderer(YAHOO.widget.Calendar.RANGE,aDate,fnRender);
3047 } else { // this is a month/day combo
3048 this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,aDate,fnRender);
3049 }
3050 } else if (aDate.length == 3) {
3051 this._addRenderer(YAHOO.widget.Calendar.DATE,aDate,fnRender);
3052 }
3053 }
3054};
3055
3056/**
3057* The private method used for adding cell renderers to the local render stack.
3058* This method is called by other methods that set the renderer type prior to the method call.
3059* @method _addRenderer
3060* @private
3061 * @param {String} type The type string that indicates the type of date renderer being added.
3062 * Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
3063 * YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
3064 * @param {Array} aDates An array of dates used to construct the renderer. The format varies based
3065 * on the renderer type
3066 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
3067*/
3068YAHOO.widget.Calendar.prototype._addRenderer = function(type, aDates, fnRender) {
3069 var add = [type,aDates,fnRender];
3070 this.renderStack.unshift(add);
3071 this._renderStack = this.renderStack.concat();
3072};
3073
3074/**
3075* Adds a month to the render stack. The function reference passed to this method will be executed
3076* when a date cell matches the month passed to this method.
3077* @method addMonthRenderer
3078 * @param {Number} month The month (1-12) to associate with this renderer
3079 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
3080*/
3081YAHOO.widget.Calendar.prototype.addMonthRenderer = function(month, fnRender) {
3082 this._addRenderer(YAHOO.widget.Calendar.MONTH,[month],fnRender);
3083};
3084
3085/**
3086* Adds a weekday to the render stack. The function reference passed to this method will be executed
3087* when a date cell matches the weekday passed to this method.
3088* @method addWeekdayRenderer
3089 * @param {Number} weekday The weekday (0-6) to associate with this renderer
3090 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
3091*/
3092YAHOO.widget.Calendar.prototype.addWeekdayRenderer = function(weekday, fnRender) {
3093 this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
3094};
3095
3096// END RENDERER METHODS
3097
3098// BEGIN CSS METHODS
3099
3100/**
3101* Removes all styles from all body cells in the current calendar table.
3102* @method clearAllBodyCellStyles
3103 * @param {style} The CSS class name to remove from all calendar body cells
3104*/
3105YAHOO.widget.Calendar.prototype.clearAllBodyCellStyles = function(style) {
3106 for (var c=0;c<this.cells.length;++c) {
3107 YAHOO.util.Dom.removeClass(this.cells[c],style);
3108 }
3109};
3110
3111// END CSS METHODS
3112
3113// BEGIN GETTER/SETTER METHODS
3114/**
3115* Sets the calendar's month explicitly
3116* @method setMonth
3117 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
3118*/
3119YAHOO.widget.Calendar.prototype.setMonth = function(month) {
3120 var current = this.cfg.getProperty("pagedate");
3121 current.setMonth(month);
3122 this.cfg.setProperty("pagedate", current);
3123};
3124
3125/**
3126* Sets the calendar's year explicitly.
3127* @method setYear
3128 * @param {Number} year The numeric 4-digit year
3129*/
3130YAHOO.widget.Calendar.prototype.setYear = function(year) {
3131 var current = this.cfg.getProperty("pagedate");
3132 current.setFullYear(year);
3133 this.cfg.setProperty("pagedate", current);
3134};
3135
3136/**
3137* Gets the list of currently selected dates from the calendar.
3138* @method getSelectedDates
3139* @return {Date[]} An array of currently selected JavaScript Date objects.
3140*/
3141YAHOO.widget.Calendar.prototype.getSelectedDates = function() {
3142 var returnDates = [];
3143 var selected = this.cfg.getProperty("selected");
3144
3145 for (var d=0;d<selected.length;++d) {
3146 var dateArray = selected[d];
3147
3148 var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
3149 returnDates.push(date);
3150 }
3151
3152 returnDates.sort( function(a,b) { return a-b; } );
3153 return returnDates;
3154};
3155
3156/// END GETTER/SETTER METHODS ///
3157
3158/**
3159* Hides the Calendar's outer container from view.
3160* @method hide
3161*/
3162YAHOO.widget.Calendar.prototype.hide = function() {
3163 this.oDomContainer.style.display = "none";
3164};
3165
3166/**
3167* Shows the Calendar's outer container.
3168* @method show
3169*/
3170YAHOO.widget.Calendar.prototype.show = function() {
3171 this.oDomContainer.style.display = "block";
3172};
3173
3174/**
3175* Returns a string representing the current browser.
3176* @property browser
3177* @type String
3178*/
3179YAHOO.widget.Calendar.prototype.browser = function() {
3180 var ua = navigator.userAgent.toLowerCase();
3181 if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
3182 return 'opera';
3183 } else if (ua.indexOf('msie 7')!=-1) { // IE7
3184 return 'ie7';
3185 } else if (ua.indexOf('msie') !=-1) { // IE
3186 return 'ie';
3187 } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
3188 return 'safari';
3189 } else if (ua.indexOf('gecko') != -1) { // Gecko
3190 return 'gecko';
3191 } else {
3192 return false;
3193 }
3194 }();
3195/**
3196* Returns a string representation of the object.
3197* @method toString
3198 * @return {String}A string representation of the Calendar object.
3199*/
3200YAHOO.widget.Calendar.prototype.toString = function() {
3201 return "Calendar " + this.id;
3202};
3203
3204/**
3205* @namespace YAHOO.widget
3206* @class Calendar_Core
3207* @extends YAHOO.widget.Calendar
3208* @deprecated The old Calendar_Core class is no longer necessary.
3209*/
3210YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
3211
3212YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
3213
3214/**
3215* YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. This class facilitates
3216* the ability to have multi-page calendar views that share a single dataset and are
3217* dependent on each other.
3218*
3219* The calendar group instance will refer to each of its elements using a 0-based index.
3220* For example, to construct the placeholder for a calendar group widget with id "cal1" and
3221* containerId of "cal1Container", the markup would be as follows:
3222 *<xmp>
3223 * <div id="cal1Container_0"></div>
3224 * <div id="cal1Container_1"></div>
3225 *</xmp>
3226* The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
3227* @namespace YAHOO.widget
3228* @class CalendarGroup
3229* @constructor
3230 * @param {String} id The id of the table element that will represent the calendar widget
3231 * @param {String} containerIdThe id of the container div element that will wrap the calendar table
3232 * @param {Object} config The configuration object containing the Calendar's arguments
3233*/
3234YAHOO.widget.CalendarGroup = function(id, containerId, config) {
3235 if (arguments.length > 0) {
3236 this.init(id, containerId, config);
3237 }
3238};
3239
3240/**
3241* Initializes the calendar group. All subclasses must call this method in order for the
3242* group to be initialized properly.
3243* @method init
3244 * @param {String} id The id of the table element that will represent the calendar widget
3245 * @param {String} containerIdThe id of the container div element that will wrap the calendar table
3246 * @param {Object} config The configuration object containing the Calendar's arguments
3247*/
3248YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
3249 this.initEvents();
3250 this.initStyles();
3251
3252 /**
3253 * The collection of Calendar pages contained within the CalendarGroup
3254 * @property pages
3255 * @type YAHOO.widget.Calendar[]
3256 */
3257 this.pages = [];
3258
3259 /**
3260 * The unique id associated with the CalendarGroup
3261 * @property id
3262 * @type String
3263 */
3264 this.id = id;
3265
3266 /**
3267 * The unique id associated with the CalendarGroup container
3268 * @property containerId
3269 * @type String
3270 */
3271 this.containerId = containerId;
3272
3273 /**
3274 * The outer containing element for the CalendarGroup
3275 * @property oDomContainer
3276 * @type HTMLElement
3277 */
3278 this.oDomContainer = document.getElementById(containerId);
3279
3280 YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_CONTAINER);
3281 YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_MULTI_UP);
3282
3283 /**
3284 * The Config object used to hold the configuration variables for the CalendarGroup
3285 * @property cfg
3286 * @type YAHOO.util.Config
3287 */
3288 this.cfg = new YAHOO.util.Config(this);
3289
3290 /**
3291 * The local object which contains the CalendarGroup's options
3292 * @property Options
3293 * @type Object
3294 */
3295 this.Options = {};
3296
3297 /**
3298 * The local object which contains the CalendarGroup's locale settings
3299 * @property Locale
3300 * @type Object
3301 */
3302 this.Locale = {};
3303
3304 this.setupConfig();
3305
3306 if (config) {
3307 this.cfg.applyConfig(config, true);
3308 }
3309
3310 this.cfg.fireQueue();
3311
3312 // OPERA HACK FOR MISWRAPPED FLOATS
3313 if (this.browser == "opera"){
3314 var fixWidth = function() {
3315 var startW = this.oDomContainer.offsetWidth;
3316 var w = 0;
3317 for (var p=0;p<this.pages.length;++p) {
3318 var cal = this.pages[p];
3319 w += cal.oDomContainer.offsetWidth;
3320 }
3321 if (w > 0) {
3322 this.oDomContainer.style.width = w + "px";
3323 }
3324 };
3325 this.renderEvent.subscribe(fixWidth,this,true);
3326 }
3327};
3328
3329
3330YAHOO.widget.CalendarGroup.prototype.setupConfig = function() {
3331 /**
3332 * The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
3333 * @config pages
3334 * @type Number
3335 * @default 2
3336 */
3337 this.cfg.addProperty("pages", { value:2, validator:this.cfg.checkNumber, handler:this.configPages } );
3338
3339 /**
3340 * The month/year representing the current visible Calendar date (mm/yyyy)
3341 * @config pagedate
3342 * @type String
3343 * @default today's date
3344 */
3345 this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );
3346
3347 /**
3348 * The date or range of dates representing the current Calendar selection
3349 * @config selected
3350 * @type String
3351 * @default []
3352 */
3353 this.cfg.addProperty("selected", { value:[], handler:this.delegateConfig } );
3354
3355 /**
3356 * The title to display above the CalendarGroup's month header
3357 * @config title
3358 * @type String
3359 * @default ""
3360 */
3361 this.cfg.addProperty("title", { value:"", handler:this.configTitle } );
3362
3363 /**
3364 * Whether or not a close button should be displayed for this CalendarGroup
3365 * @config close
3366 * @type Boolean
3367 * @default false
3368 */
3369 this.cfg.addProperty("close", { value:false, handler:this.configClose } );
3370
3371 /**
3372 * 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.
3373 * @config iframe
3374 * @type Boolean
3375 * @default true
3376 */
3377 this.cfg.addProperty("iframe", { value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3378
3379 /**
3380 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
3381 * @config mindate
3382 * @type String
3383 * @default null
3384 */
3385 this.cfg.addProperty("mindate", { value:null, handler:this.delegateConfig } );
3386
3387 /**
3388 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
3389 * @config maxdate
3390 * @type String
3391 * @default null
3392 */
3393 this.cfg.addProperty("maxdate", { value:null, handler:this.delegateConfig } );
3394
3395 // Options properties
3396
3397 /**
3398 * True if the Calendar should allow multiple selections. False by default.
3399 * @config MULTI_SELECT
3400 * @type Boolean
3401 * @default false
3402 */
3403 this.cfg.addProperty("MULTI_SELECT",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3404
3405 /**
3406 * The weekday the week begins on. Default is 0 (Sunday).
3407 * @config START_WEEKDAY
3408 * @type number
3409 * @default 0
3410 */
3411 this.cfg.addProperty("START_WEEKDAY",{ value:0, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3412
3413 /**
3414 * True if the Calendar should show weekday labels. True by default.
3415 * @config SHOW_WEEKDAYS
3416 * @type Boolean
3417 * @default true
3418 */
3419 this.cfg.addProperty("SHOW_WEEKDAYS",{ value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3420
3421 /**
3422 * True if the Calendar should show week row headers. False by default.
3423 * @config SHOW_WEEK_HEADER
3424 * @type Boolean
3425 * @default false
3426 */
3427 this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3428
3429 /**
3430 * True if the Calendar should show week row footers. False by default.
3431 * @config SHOW_WEEK_FOOTER
3432 * @type Boolean
3433 * @default false
3434 */
3435 this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3436
3437 /**
3438 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
3439 * @config HIDE_BLANK_WEEKS
3440 * @type Boolean
3441 * @default false
3442 */
3443 this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );
3444
3445 /**
3446 * The image that should be used for the left navigation arrow.
3447 * @config NAV_ARROW_LEFT
3448 * @type String
3449 * @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif"
3450 */
3451 this.cfg.addProperty("NAV_ARROW_LEFT",{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.delegateConfig } );
3452
3453 /**
3454 * The image that should be used for the left navigation arrow.
3455 * @config NAV_ARROW_RIGHT
3456 * @type String
3457 * @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif"
3458 */
3459 this.cfg.addProperty("NAV_ARROW_RIGHT",{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.delegateConfig } );
3460
3461 // Locale properties
3462
3463 /**
3464 * The short month labels for the current locale.
3465 * @config MONTHS_SHORT
3466 * @type String[]
3467 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
3468 */
3469 this.cfg.addProperty("MONTHS_SHORT",{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.delegateConfig } );
3470
3471 /**
3472 * The long month labels for the current locale.
3473 * @config MONTHS_LONG
3474 * @type String[]
3475 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
3476 */
3477 this.cfg.addProperty("MONTHS_LONG", { value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.delegateConfig } );
3478
3479 /**
3480 * The 1-character weekday labels for the current locale.
3481 * @config WEEKDAYS_1CHAR
3482 * @type String[]
3483 * @default ["S", "M", "T", "W", "T", "F", "S"]
3484 */
3485 this.cfg.addProperty("WEEKDAYS_1CHAR",{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.delegateConfig } );
3486
3487 /**
3488 * The short weekday labels for the current locale.
3489 * @config WEEKDAYS_SHORT
3490 * @type String[]
3491 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
3492 */
3493 this.cfg.addProperty("WEEKDAYS_SHORT",{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.delegateConfig } );
3494
3495 /**
3496 * The medium weekday labels for the current locale.
3497 * @config WEEKDAYS_MEDIUM
3498 * @type String[]
3499 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
3500 */
3501 this.cfg.addProperty("WEEKDAYS_MEDIUM",{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.delegateConfig } );
3502
3503 /**
3504 * The long weekday labels for the current locale.
3505 * @config WEEKDAYS_LONG
3506 * @type String[]
3507 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
3508 */
3509 this.cfg.addProperty("WEEKDAYS_LONG",{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.delegateConfig } );
3510
3511 /**
3512 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
3513 * @config LOCALE_MONTHS
3514 * @type String
3515 * @default "long"
3516 */
3517 this.cfg.addProperty("LOCALE_MONTHS",{ value:"long", handler:this.delegateConfig } );
3518
3519 /**
3520 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
3521 * @config LOCALE_WEEKDAYS
3522 * @type String
3523 * @default "short"
3524 */
3525 this.cfg.addProperty("LOCALE_WEEKDAYS",{ value:"short", handler:this.delegateConfig } );
3526
3527 /**
3528 * The value used to delimit individual dates in a date string passed to various Calendar functions.
3529 * @config DATE_DELIMITER
3530 * @type String
3531 * @default ","
3532 */
3533 this.cfg.addProperty("DATE_DELIMITER", { value:",", handler:this.delegateConfig } );
3534
3535 /**
3536 * The value used to delimit date fields in a date string passed to various Calendar functions.
3537 * @config DATE_FIELD_DELIMITER
3538 * @type String
3539 * @default "/"
3540 */
3541 this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.delegateConfig } );
3542
3543 /**
3544 * The value used to delimit date ranges in a date string passed to various Calendar functions.
3545 * @config DATE_RANGE_DELIMITER
3546 * @type String
3547 * @default "-"
3548 */
3549 this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.delegateConfig } );
3550
3551 /**
3552 * The position of the month in a month/year date string
3553 * @config MY_MONTH_POSITION
3554 * @type Number
3555 * @default 1
3556 */
3557 this.cfg.addProperty("MY_MONTH_POSITION",{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3558
3559 /**
3560 * The position of the year in a month/year date string
3561 * @config MY_YEAR_POSITION
3562 * @type Number
3563 * @default 2
3564 */
3565 this.cfg.addProperty("MY_YEAR_POSITION",{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3566
3567 /**
3568 * The position of the month in a month/day date string
3569 * @config MD_MONTH_POSITION
3570 * @type Number
3571 * @default 1
3572 */
3573 this.cfg.addProperty("MD_MONTH_POSITION",{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3574
3575 /**
3576 * The position of the day in a month/year date string
3577 * @config MD_DAY_POSITION
3578 * @type Number
3579 * @default 2
3580 */
3581 this.cfg.addProperty("MD_DAY_POSITION", { value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3582
3583 /**
3584 * The position of the month in a month/day/year date string
3585 * @config MDY_MONTH_POSITION
3586 * @type Number
3587 * @default 1
3588 */
3589 this.cfg.addProperty("MDY_MONTH_POSITION",{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3590
3591 /**
3592 * The position of the day in a month/day/year date string
3593 * @config MDY_DAY_POSITION
3594 * @type Number
3595 * @default 2
3596 */
3597 this.cfg.addProperty("MDY_DAY_POSITION",{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3598
3599 /**
3600 * The position of the year in a month/day/year date string
3601 * @config MDY_YEAR_POSITION
3602 * @type Number
3603 * @default 3
3604 */
3605 this.cfg.addProperty("MDY_YEAR_POSITION",{ value:3, handler:this.delegateConfig, validator:this.cfg.checkNumber } );
3606
3607};
3608
3609/**
3610* Initializes CalendarGroup's built-in CustomEvents
3611* @method initEvents
3612*/
3613YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
3614 var me = this;
3615
3616 /**
3617 * Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
3618 * @method sub
3619 * @private
3620 * @param {Function} fnThe function to subscribe to this CustomEvent
3621 * @param {Object} objThe CustomEvent's scope object
3622 * @param {Boolean} bOverrideWhether or not to apply scope correction
3623 */
3624 var sub = function(fn, obj, bOverride) {
3625 for (var p=0;p<me.pages.length;++p) {
3626 var cal = me.pages[p];
3627 cal[this.type + "Event"].subscribe(fn, obj, bOverride);
3628 }
3629 };
3630
3631 /**
3632 * Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
3633 * @method unsub
3634 * @private
3635 * @param {Function} fnThe function to subscribe to this CustomEvent
3636 * @param {Object} objThe CustomEvent's scope object
3637 */
3638 var unsub = function(fn, obj) {
3639 for (var p=0;p<me.pages.length;++p) {
3640 var cal = me.pages[p];
3641 cal[this.type + "Event"].unsubscribe(fn, obj);
3642 }
3643 };
3644
3645 /**
3646 * Fired before a selection is made
3647 * @event beforeSelectEvent
3648 */
3649 this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
3650 this.beforeSelectEvent.subscribe = sub; this.beforeSelectEvent.unsubscribe = unsub;
3651
3652 /**
3653 * Fired when a selection is made
3654 * @event selectEvent
3655 * @param {Array}Array of Date field arrays in the format [YYYY, MM, DD].
3656 */
3657 this.selectEvent = new YAHOO.util.CustomEvent("select");
3658 this.selectEvent.subscribe = sub; this.selectEvent.unsubscribe = unsub;
3659
3660 /**
3661 * Fired before a selection is made
3662 * @event beforeDeselectEvent
3663 */
3664 this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
3665 this.beforeDeselectEvent.subscribe = sub; this.beforeDeselectEvent.unsubscribe = unsub;
3666
3667 /**
3668 * Fired when a selection is made
3669 * @event deselectEvent
3670 * @param {Array}Array of Date field arrays in the format [YYYY, MM, DD].
3671 */
3672 this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
3673 this.deselectEvent.subscribe = sub; this.deselectEvent.unsubscribe = unsub;
3674
3675 /**
3676 * Fired when the Calendar page is changed
3677 * @event changePageEvent
3678 */
3679 this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
3680 this.changePageEvent.subscribe = sub; this.changePageEvent.unsubscribe = unsub;
3681
3682 /**
3683 * Fired before the Calendar is rendered
3684 * @event beforeRenderEvent
3685 */
3686 this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
3687 this.beforeRenderEvent.subscribe = sub; this.beforeRenderEvent.unsubscribe = unsub;
3688
3689 /**
3690 * Fired when the Calendar is rendered
3691 * @event renderEvent
3692 */
3693 this.renderEvent = new YAHOO.util.CustomEvent("render");
3694 this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;
3695
3696 /**
3697 * Fired when the Calendar is reset
3698 * @event resetEvent
3699 */
3700 this.resetEvent = new YAHOO.util.CustomEvent("reset");
3701 this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;
3702
3703 /**
3704 * Fired when the Calendar is cleared
3705 * @event clearEvent
3706 */
3707 this.clearEvent = new YAHOO.util.CustomEvent("clear");
3708 this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;
3709
3710};
3711
3712/**
3713* The default Config handler for the "pages" property
3714* @method configPages
3715 * @param {String} typeThe CustomEvent type (usually the property name)
3716 * @param {Object[]} argsThe CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
3717 * @param {Object} objThe scope object. For configuration handlers, this will usually equal the owner.
3718*/
3719YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
3720 var pageCount = args[0];
3721
3722 for (var p=0;p<pageCount;++p) {
3723 var calId = this.id + "_" + p;
3724 var calContainerId = this.containerId + "_" + p;
3725
3726 var childConfig = this.cfg.getConfig();
3727 childConfig.close = false;
3728 childConfig.title = false;
3729
3730 var cal = this.constructChild(calId, calContainerId, childConfig);
3731 var caldate = cal.cfg.getProperty("pagedate");
3732 caldate.setMonth(caldate.getMonth()+p);
3733 cal.cfg.setProperty("pagedate", caldate);
3734
3735 YAHOO.util.Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
3736 YAHOO.util.Dom.addClass(cal.oDomContainer, "groupcal");
3737
3738 if (p===0) {
3739 YAHOO.util.Dom.addClass(cal.oDomContainer, "first");
3740 }
3741
3742 if (p==(pageCount-1)) {
3743 YAHOO.util.Dom.addClass(cal.oDomContainer, "last");
3744 }
3745
3746 cal.parent = this;
3747 cal.index = p;
3748
3749 this.pages[this.pages.length] = cal;
3750 }
3751};
3752
3753/**
3754* The default Config handler for the "pagedate" property
3755* @method configPageDate
3756 * @param {String} typeThe CustomEvent type (usually the property name)
3757 * @param {Object[]} argsThe CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
3758 * @param {Object} objThe scope object. For configuration handlers, this will usually equal the owner.
3759*/
3760YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
3761 var val = args[0];
3762
3763 for (var p=0;p<this.pages.length;++p) {
3764 var cal = this.pages[p];
3765 cal.cfg.setProperty("pagedate", val);
3766 var calDate = cal.cfg.getProperty("pagedate");
3767 calDate.setMonth(calDate.getMonth()+p);
3768 }
3769};
3770
3771/**
3772* Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
3773* @method delegateConfig
3774 * @param {String} typeThe CustomEvent type (usually the property name)
3775 * @param {Object[]} argsThe CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
3776 * @param {Object} objThe scope object. For configuration handlers, this will usually equal the owner.
3777*/
3778YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
3779 var val = args[0];
3780 var cal;
3781
3782 for (var p=0;p<this.pages.length;p++) {
3783 cal = this.pages[p];
3784 cal.cfg.setProperty(type, val);
3785 }
3786};
3787
3788
3789/**
3790* Adds a function to all child Calendars within this CalendarGroup.
3791* @method setChildFunction
3792 * @param {String} fnName The name of the function
3793 * @param {Function} fn The function to apply to each Calendar page object
3794*/
3795YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
3796 var pageCount = this.cfg.getProperty("pages");
3797
3798 for (var p=0;p<pageCount;++p) {
3799 this.pages[p][fnName] = fn;
3800 }
3801};
3802
3803/**
3804* Calls a function within all child Calendars within this CalendarGroup.
3805* @method callChildFunction
3806 * @param {String} fnName The name of the function
3807 * @param {Array} args The arguments to pass to the function
3808*/
3809YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
3810 var pageCount = this.cfg.getProperty("pages");
3811
3812 for (var p=0;p<pageCount;++p) {
3813 var page = this.pages[p];
3814 if (page[fnName]) {
3815 var fn = page[fnName];
3816 fn.call(page, args);
3817 }
3818 }
3819};
3820
3821/**
3822* Constructs a child calendar. This method can be overridden if a subclassed version of the default
3823* calendar is to be used.
3824* @method constructChild
3825 * @param {String} id The id of the table element that will represent the calendar widget
3826 * @param {String} containerIdThe id of the container div element that will wrap the calendar table
3827 * @param {Object} config The configuration object containing the Calendar's arguments
3828 * @return {YAHOO.widget.Calendar}The YAHOO.widget.Calendar instance that is constructed
3829*/
3830YAHOO.widget.CalendarGroup.prototype.constructChild = function(id,containerId,config) {
3831 var container = document.getElementById(containerId);
3832 if (! container) {
3833 container = document.createElement("div");
3834 container.id = containerId;
3835 this.oDomContainer.appendChild(container);
3836 }
3837 return new YAHOO.widget.Calendar(id,containerId,config);
3838};
3839
3840
3841/**
3842* Sets the calendar group's month explicitly. This month will be set into the first
3843* @method setMonth
3844* page of the multi-page calendar, and all other months will be iterated appropriately.
3845 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
3846*/
3847YAHOO.widget.CalendarGroup.prototype.setMonth = function(month) {
3848 for (var p=0;p<this.pages.length;++p) {
3849 var cal = this.pages[p];
3850 cal.setMonth(month+p);
3851 }
3852};
3853
3854/**
3855* Sets the calendar group's year explicitly. This year will be set into the first
3856* @method setYear
3857* page of the multi-page calendar, and all other months will be iterated appropriately.
3858 * @param {Number} year The numeric 4-digit year
3859*/
3860YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
3861 for (var p=0;p<this.pages.length;++p) {
3862 var cal = this.pages[p];
3863 var pageDate = cal.cfg.getProperty("pageDate");
3864
3865 if ((pageDate.getMonth()+1) == 1 && p>0) {
3866 year+=1;
3867 }
3868 cal.setYear(year);
3869 }
3870};
3871/**
3872* Calls the render function of all child calendars within the group.
3873* @method render
3874*/
3875YAHOO.widget.CalendarGroup.prototype.render = function() {
3876 this.renderHeader();
3877 for (var p=0;p<this.pages.length;++p) {
3878 var cal = this.pages[p];
3879 cal.render();
3880 }
3881 this.renderFooter();
3882};
3883
3884/**
3885* Selects a date or a collection of dates on the current calendar. This method, by default,
3886* does not call the render method explicitly. Once selection has completed, render must be
3887* called for the changes to be reflected visually.
3888* @method select
3889 * @param {String/Date/Date[]} dateThe date string of dates to select in the current calendar. Valid formats are
3890 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
3891 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
3892 * This method can also take a JavaScript Date object or an array of Date objects.
3893 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3894*/
3895YAHOO.widget.CalendarGroup.prototype.select = function(date) {
3896 for (var p=0;p<this.pages.length;++p) {
3897 var cal = this.pages[p];
3898 cal.select(date);
3899 }
3900 return this.getSelectedDates();
3901};
3902
3903/**
3904* Selects a date on the current calendar by referencing the index of the cell that should be selected.
3905* This method is used to easily select a single cell (usually with a mouse click) without having to do
3906* a full render. The selected style is applied to the cell directly.
3907* @method selectCell
3908 * @param {Number} cellIndexThe index of the cell to select in the current calendar.
3909 * @return {Date[]}Array of JavaScript Date objects representing all individual dates that are currently selected.
3910*/
3911YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
3912 for (var p=0;p<this.pages.length;++p) {
3913 var cal = this.pages[p];
3914 cal.selectCell(cellIndex);
3915 }
3916 return this.getSelectedDates();
3917};
3918
3919/**
3920* Deselects a date or a collection of dates on the current calendar. This method, by default,
3921* does not call the render method explicitly. Once deselection has completed, render must be
3922* called for the changes to be reflected visually.
3923* @method deselect
3924 * @param {String/Date/Date[]} dateThe date string of dates to deselect in the current calendar. Valid formats are
3925 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
3926 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
3927 * This method can also take a JavaScript Date object or an array of Date objects.
3928 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3929*/
3930YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
3931 for (var p=0;p<this.pages.length;++p) {
3932 var cal = this.pages[p];
3933 cal.deselect(date);
3934 }
3935 return this.getSelectedDates();
3936};
3937
3938/**
3939* Deselects all dates on the current calendar.
3940* @method deselectAll
3941 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
3942 * Assuming that this function executes properly, the return value should be an empty array.
3943 * However, the empty array is returned for the sake of being able to check the selection status
3944 * of the calendar.
3945*/
3946YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
3947 for (var p=0;p<this.pages.length;++p) {
3948 var cal = this.pages[p];
3949 cal.deselectAll();
3950 }
3951 return this.getSelectedDates();
3952};
3953
3954/**
3955* Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
3956* This method is used to easily deselect a single cell (usually with a mouse click) without having to do
3957* a full render. The selected style is removed from the cell directly.
3958* @method deselectCell
3959 * @param {Number} cellIndexThe index of the cell to deselect in the current calendar.
3960 * @return {Date[]}Array of JavaScript Date objects representing all individual dates that are currently selected.
3961*/
3962YAHOO.widget.CalendarGroup.prototype.deselectCell = function(cellIndex) {
3963 for (var p=0;p<this.pages.length;++p) {
3964 var cal = this.pages[p];
3965 cal.deselectCell(cellIndex);
3966 }
3967 return this.getSelectedDates();
3968};
3969
3970/**
3971* Resets the calendar widget to the originally selected month and year, and
3972* sets the calendar to the initial selection(s).
3973* @method reset
3974*/
3975YAHOO.widget.CalendarGroup.prototype.reset = function() {
3976 for (var p=0;p<this.pages.length;++p) {
3977 var cal = this.pages[p];
3978 cal.reset();
3979 }
3980};
3981
3982/**
3983* Clears the selected dates in the current calendar widget and sets the calendar
3984* to the current month and year.
3985* @method clear
3986*/
3987YAHOO.widget.CalendarGroup.prototype.clear = function() {
3988 for (var p=0;p<this.pages.length;++p) {
3989 var cal = this.pages[p];
3990 cal.clear();
3991 }
3992};
3993
3994/**
3995* Navigates to the next month page in the calendar widget.
3996* @method nextMonth
3997*/
3998YAHOO.widget.CalendarGroup.prototype.nextMonth = function() {
3999 for (var p=0;p<this.pages.length;++p) {
4000 var cal = this.pages[p];
4001 cal.nextMonth();
4002 }
4003};
4004
4005/**
4006* Navigates to the previous month page in the calendar widget.
4007* @method previousMonth
4008*/
4009YAHOO.widget.CalendarGroup.prototype.previousMonth = function() {
4010 for (var p=this.pages.length-1;p>=0;--p) {
4011 var cal = this.pages[p];
4012 cal.previousMonth();
4013 }
4014};
4015
4016/**
4017* Navigates to the next year in the currently selected month in the calendar widget.
4018* @method nextYear
4019*/
4020YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
4021 for (var p=0;p<this.pages.length;++p) {
4022 var cal = this.pages[p];
4023 cal.nextYear();
4024 }
4025};
4026
4027/**
4028* Navigates to the previous year in the currently selected month in the calendar widget.
4029* @method previousYear
4030*/
4031YAHOO.widget.CalendarGroup.prototype.previousYear = function() {
4032 for (var p=0;p<this.pages.length;++p) {
4033 var cal = this.pages[p];
4034 cal.previousYear();
4035 }
4036};
4037
4038
4039/**
4040* Gets the list of currently selected dates from the calendar.
4041 * @return An array of currently selected JavaScript Date objects.
4042* @type Date[]
4043*/
4044YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() {
4045 var returnDates = [];
4046 var selected = this.cfg.getProperty("selected");
4047
4048 for (var d=0;d<selected.length;++d) {
4049 var dateArray = selected[d];
4050
4051 var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
4052 returnDates.push(date);
4053 }
4054
4055 returnDates.sort( function(a,b) { return a-b; } );
4056 return returnDates;
4057};
4058
4059/**
4060* Adds a renderer to the render stack. The function reference passed to this method will be executed
4061* when a date cell matches the conditions specified in the date string for this renderer.
4062* @method addRenderer
4063 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
4064 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
4065 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
4066*/
4067YAHOO.widget.CalendarGroup.prototype.addRenderer = function(sDates, fnRender) {
4068 for (var p=0;p<this.pages.length;++p) {
4069 var cal = this.pages[p];
4070 cal.addRenderer(sDates, fnRender);
4071 }
4072};
4073
4074/**
4075* Adds a month to the render stack. The function reference passed to this method will be executed
4076* when a date cell matches the month passed to this method.
4077* @method addMonthRenderer
4078 * @param {Number} month The month (1-12) to associate with this renderer
4079 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
4080*/
4081YAHOO.widget.CalendarGroup.prototype.addMonthRenderer = function(month, fnRender) {
4082 for (var p=0;p<this.pages.length;++p) {
4083 var cal = this.pages[p];
4084 cal.addMonthRenderer(month, fnRender);
4085 }
4086};
4087
4088/**
4089* Adds a weekday to the render stack. The function reference passed to this method will be executed
4090* when a date cell matches the weekday passed to this method.
4091* @method addWeekdayRenderer
4092 * @param {Number} weekday The weekday (0-6) to associate with this renderer
4093 * @param {Function} fnRenderThe function executed to render cells that match the render rules for this renderer.
4094*/
4095YAHOO.widget.CalendarGroup.prototype.addWeekdayRenderer = function(weekday, fnRender) {
4096 for (var p=0;p<this.pages.length;++p) {
4097 var cal = this.pages[p];
4098 cal.addWeekdayRenderer(weekday, fnRender);
4099 }
4100};
4101
4102/**
4103* Renders the header for the CalendarGroup.
4104* @method renderHeader
4105*/
4106YAHOO.widget.CalendarGroup.prototype.renderHeader = function() {};
4107
4108/**
4109* Renders a footer for the 2-up calendar container. By default, this method is
4110* unimplemented.
4111* @method renderFooter
4112*/
4113YAHOO.widget.CalendarGroup.prototype.renderFooter = function() {};
4114
4115/**
4116* Adds the designated number of months to the current calendar month, and sets the current
4117* calendar page date to the new month.
4118* @method addMonths
4119 * @param {Number} countThe number of months to add to the current calendar
4120*/
4121YAHOO.widget.CalendarGroup.prototype.addMonths = function(count) {
4122 this.callChildFunction("addMonths", count);
4123};
4124
4125
4126/**
4127* Subtracts the designated number of months from the current calendar month, and sets the current
4128* calendar page date to the new month.
4129* @method subtractMonths
4130 * @param {Number} countThe number of months to subtract from the current calendar
4131*/
4132YAHOO.widget.CalendarGroup.prototype.subtractMonths = function(count) {
4133 this.callChildFunction("subtractMonths", count);
4134};
4135
4136/**
4137* Adds the designated number of years to the current calendar, and sets the current
4138* calendar page date to the new month.
4139* @method addYears
4140 * @param {Number} countThe number of years to add to the current calendar
4141*/
4142YAHOO.widget.CalendarGroup.prototype.addYears = function(count) {
4143 this.callChildFunction("addYears", count);
4144};
4145
4146/**
4147* Subtcats the designated number of years from the current calendar, and sets the current
4148* calendar page date to the new month.
4149* @method subtractYears
4150 * @param {Number} countThe number of years to subtract from the current calendar
4151*/
4152YAHOO.widget.CalendarGroup.prototype.subtractYears = function(count) {
4153 this.callChildFunction("subtractYears", count);
4154};
4155
4156/**
4157* CSS class representing the container for the calendar
4158* @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
4159* @static
4160* @final
4161* @type String
4162*/
4163YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
4164
4165/**
4166* CSS class representing the container for the calendar
4167* @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
4168* @static
4169* @final
4170* @type String
4171*/
4172YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";
4173
4174/**
4175* CSS class representing the title for the 2-up calendar
4176* @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
4177* @static
4178* @final
4179* @type String
4180*/
4181YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";
4182
4183/**
4184* CSS class representing the close icon for the 2-up calendar
4185* @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
4186* @static
4187* @final
4188* @type String
4189*/
4190YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";
4191
4192YAHOO.augment(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
4193 "buildMonthLabel",
4194 "renderOutOfBoundsDate",
4195 "renderRowHeader",
4196 "renderRowFooter",
4197 "renderCellDefault",
4198 "styleCellDefault",
4199 "renderCellStyleHighlight1",
4200 "renderCellStyleHighlight2",
4201 "renderCellStyleHighlight3",
4202 "renderCellStyleHighlight4",
4203 "renderCellStyleToday",
4204 "renderCellStyleSelected",
4205 "renderCellNotThisMonth",
4206 "renderBodyCellRestricted",
4207 "initStyles",
4208 "configTitle",
4209 "configClose",
4210 "hide",
4211 "show",
4212 "browser");
4213
4214/**
4215* Returns a string representation of the object.
4216* @method toString
4217 * @return {String}A string representation of the CalendarGroup object.
4218*/
4219YAHOO.widget.CalendarGroup.prototype.toString = function() {
4220 return "CalendarGroup " + this.id;
4221};
4222
4223YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
4224
4225/**
4226* @class YAHOO.widget.Calendar2up
4227* @extends YAHOO.widget.CalendarGroup
4228* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
4229*/
4230YAHOO.widget.Calendar2up = function(id, containerId, config) {
4231 this.init(id, containerId, config);
4232};
4233
4234YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);
4235
4236/**
4237* @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
4238*/
4239YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up; \ No newline at end of file