0
|
1 /*
|
|
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
|
|
3 Code licensed under the BSD License:
|
|
4 http://developer.yahoo.net/yui/license.txt
|
|
5 version: 2.8.0r4
|
|
6 */
|
|
7 (function () {
|
|
8
|
|
9 /**
|
|
10 * Config is a utility used within an Object to allow the implementer to
|
|
11 * maintain a list of local configuration properties and listen for changes
|
|
12 * to those properties dynamically using CustomEvent. The initial values are
|
|
13 * also maintained so that the configuration can be reset at any given point
|
|
14 * to its initial state.
|
|
15 * @namespace YAHOO.util
|
|
16 * @class Config
|
|
17 * @constructor
|
|
18 * @param {Object} owner The owner Object to which this Config Object belongs
|
|
19 */
|
|
20 YAHOO.util.Config = function (owner) {
|
|
21
|
|
22 if (owner) {
|
|
23 this.init(owner);
|
|
24 }
|
|
25
|
|
26 if (!owner) { YAHOO.log("No owner specified for Config object", "error", "Config"); }
|
|
27
|
|
28 };
|
|
29
|
|
30
|
|
31 var Lang = YAHOO.lang,
|
|
32 CustomEvent = YAHOO.util.CustomEvent,
|
|
33 Config = YAHOO.util.Config;
|
|
34
|
|
35
|
|
36 /**
|
|
37 * Constant representing the CustomEvent type for the config changed event.
|
|
38 * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
|
|
39 * @private
|
|
40 * @static
|
|
41 * @final
|
|
42 */
|
|
43 Config.CONFIG_CHANGED_EVENT = "configChanged";
|
|
44
|
|
45 /**
|
|
46 * Constant representing the boolean type string
|
|
47 * @property YAHOO.util.Config.BOOLEAN_TYPE
|
|
48 * @private
|
|
49 * @static
|
|
50 * @final
|
|
51 */
|
|
52 Config.BOOLEAN_TYPE = "boolean";
|
|
53
|
|
54 Config.prototype = {
|
|
55
|
|
56 /**
|
|
57 * Object reference to the owner of this Config Object
|
|
58 * @property owner
|
|
59 * @type Object
|
|
60 */
|
|
61 owner: null,
|
|
62
|
|
63 /**
|
|
64 * Boolean flag that specifies whether a queue is currently
|
|
65 * being executed
|
|
66 * @property queueInProgress
|
|
67 * @type Boolean
|
|
68 */
|
|
69 queueInProgress: false,
|
|
70
|
|
71 /**
|
|
72 * Maintains the local collection of configuration property objects and
|
|
73 * their specified values
|
|
74 * @property config
|
|
75 * @private
|
|
76 * @type Object
|
|
77 */
|
|
78 config: null,
|
|
79
|
|
80 /**
|
|
81 * Maintains the local collection of configuration property objects as
|
|
82 * they were initially applied.
|
|
83 * This object is used when resetting a property.
|
|
84 * @property initialConfig
|
|
85 * @private
|
|
86 * @type Object
|
|
87 */
|
|
88 initialConfig: null,
|
|
89
|
|
90 /**
|
|
91 * Maintains the local, normalized CustomEvent queue
|
|
92 * @property eventQueue
|
|
93 * @private
|
|
94 * @type Object
|
|
95 */
|
|
96 eventQueue: null,
|
|
97
|
|
98 /**
|
|
99 * Custom Event, notifying subscribers when Config properties are set
|
|
100 * (setProperty is called without the silent flag
|
|
101 * @event configChangedEvent
|
|
102 */
|
|
103 configChangedEvent: null,
|
|
104
|
|
105 /**
|
|
106 * Initializes the configuration Object and all of its local members.
|
|
107 * @method init
|
|
108 * @param {Object} owner The owner Object to which this Config
|
|
109 * Object belongs
|
|
110 */
|
|
111 init: function (owner) {
|
|
112
|
|
113 this.owner = owner;
|
|
114
|
|
115 this.configChangedEvent =
|
|
116 this.createEvent(Config.CONFIG_CHANGED_EVENT);
|
|
117
|
|
118 this.configChangedEvent.signature = CustomEvent.LIST;
|
|
119 this.queueInProgress = false;
|
|
120 this.config = {};
|
|
121 this.initialConfig = {};
|
|
122 this.eventQueue = [];
|
|
123
|
|
124 },
|
|
125
|
|
126 /**
|
|
127 * Validates that the value passed in is a Boolean.
|
|
128 * @method checkBoolean
|
|
129 * @param {Object} val The value to validate
|
|
130 * @return {Boolean} true, if the value is valid
|
|
131 */
|
|
132 checkBoolean: function (val) {
|
|
133 return (typeof val == Config.BOOLEAN_TYPE);
|
|
134 },
|
|
135
|
|
136 /**
|
|
137 * Validates that the value passed in is a number.
|
|
138 * @method checkNumber
|
|
139 * @param {Object} val The value to validate
|
|
140 * @return {Boolean} true, if the value is valid
|
|
141 */
|
|
142 checkNumber: function (val) {
|
|
143 return (!isNaN(val));
|
|
144 },
|
|
145
|
|
146 /**
|
|
147 * Fires a configuration property event using the specified value.
|
|
148 * @method fireEvent
|
|
149 * @private
|
|
150 * @param {String} key The configuration property's name
|
|
151 * @param {value} Object The value of the correct type for the property
|
|
152 */
|
|
153 fireEvent: function ( key, value ) {
|
|
154 YAHOO.log("Firing Config event: " + key + "=" + value, "info", "Config");
|
|
155 var property = this.config[key];
|
|
156
|
|
157 if (property && property.event) {
|
|
158 property.event.fire(value);
|
|
159 }
|
|
160 },
|
|
161
|
|
162 /**
|
|
163 * Adds a property to the Config Object's private config hash.
|
|
164 * @method addProperty
|
|
165 * @param {String} key The configuration property's name
|
|
166 * @param {Object} propertyObject The Object containing all of this
|
|
167 * property's arguments
|
|
168 */
|
|
169 addProperty: function ( key, propertyObject ) {
|
|
170 key = key.toLowerCase();
|
|
171 YAHOO.log("Added property: " + key, "info", "Config");
|
|
172
|
|
173 this.config[key] = propertyObject;
|
|
174
|
|
175 propertyObject.event = this.createEvent(key, { scope: this.owner });
|
|
176 propertyObject.event.signature = CustomEvent.LIST;
|
|
177
|
|
178
|
|
179 propertyObject.key = key;
|
|
180
|
|
181 if (propertyObject.handler) {
|
|
182 propertyObject.event.subscribe(propertyObject.handler,
|
|
183 this.owner);
|
|
184 }
|
|
185
|
|
186 this.setProperty(key, propertyObject.value, true);
|
|
187
|
|
188 if (! propertyObject.suppressEvent) {
|
|
189 this.queueProperty(key, propertyObject.value);
|
|
190 }
|
|
191
|
|
192 },
|
|
193
|
|
194 /**
|
|
195 * Returns a key-value configuration map of the values currently set in
|
|
196 * the Config Object.
|
|
197 * @method getConfig
|
|
198 * @return {Object} The current config, represented in a key-value map
|
|
199 */
|
|
200 getConfig: function () {
|
|
201
|
|
202 var cfg = {},
|
|
203 currCfg = this.config,
|
|
204 prop,
|
|
205 property;
|
|
206
|
|
207 for (prop in currCfg) {
|
|
208 if (Lang.hasOwnProperty(currCfg, prop)) {
|
|
209 property = currCfg[prop];
|
|
210 if (property && property.event) {
|
|
211 cfg[prop] = property.value;
|
|
212 }
|
|
213 }
|
|
214 }
|
|
215
|
|
216 return cfg;
|
|
217 },
|
|
218
|
|
219 /**
|
|
220 * Returns the value of specified property.
|
|
221 * @method getProperty
|
|
222 * @param {String} key The name of the property
|
|
223 * @return {Object} The value of the specified property
|
|
224 */
|
|
225 getProperty: function (key) {
|
|
226 var property = this.config[key.toLowerCase()];
|
|
227 if (property && property.event) {
|
|
228 return property.value;
|
|
229 } else {
|
|
230 return undefined;
|
|
231 }
|
|
232 },
|
|
233
|
|
234 /**
|
|
235 * Resets the specified property's value to its initial value.
|
|
236 * @method resetProperty
|
|
237 * @param {String} key The name of the property
|
|
238 * @return {Boolean} True is the property was reset, false if not
|
|
239 */
|
|
240 resetProperty: function (key) {
|
|
241
|
|
242 key = key.toLowerCase();
|
|
243
|
|
244 var property = this.config[key];
|
|
245
|
|
246 if (property && property.event) {
|
|
247
|
|
248 if (this.initialConfig[key] &&
|
|
249 !Lang.isUndefined(this.initialConfig[key])) {
|
|
250
|
|
251 this.setProperty(key, this.initialConfig[key]);
|
|
252
|
|
253 return true;
|
|
254
|
|
255 }
|
|
256
|
|
257 } else {
|
|
258
|
|
259 return false;
|
|
260 }
|
|
261
|
|
262 },
|
|
263
|
|
264 /**
|
|
265 * Sets the value of a property. If the silent property is passed as
|
|
266 * true, the property's event will not be fired.
|
|
267 * @method setProperty
|
|
268 * @param {String} key The name of the property
|
|
269 * @param {String} value The value to set the property to
|
|
270 * @param {Boolean} silent Whether the value should be set silently,
|
|
271 * without firing the property event.
|
|
272 * @return {Boolean} True, if the set was successful, false if it failed.
|
|
273 */
|
|
274 setProperty: function (key, value, silent) {
|
|
275
|
|
276 var property;
|
|
277
|
|
278 key = key.toLowerCase();
|
|
279 YAHOO.log("setProperty: " + key + "=" + value, "info", "Config");
|
|
280
|
|
281 if (this.queueInProgress && ! silent) {
|
|
282 // Currently running through a queue...
|
|
283 this.queueProperty(key,value);
|
|
284 return true;
|
|
285
|
|
286 } else {
|
|
287 property = this.config[key];
|
|
288 if (property && property.event) {
|
|
289 if (property.validator && !property.validator(value)) {
|
|
290 return false;
|
|
291 } else {
|
|
292 property.value = value;
|
|
293 if (! silent) {
|
|
294 this.fireEvent(key, value);
|
|
295 this.configChangedEvent.fire([key, value]);
|
|
296 }
|
|
297 return true;
|
|
298 }
|
|
299 } else {
|
|
300 return false;
|
|
301 }
|
|
302 }
|
|
303 },
|
|
304
|
|
305 /**
|
|
306 * Sets the value of a property and queues its event to execute. If the
|
|
307 * event is already scheduled to execute, it is
|
|
308 * moved from its current position to the end of the queue.
|
|
309 * @method queueProperty
|
|
310 * @param {String} key The name of the property
|
|
311 * @param {String} value The value to set the property to
|
|
312 * @return {Boolean} true, if the set was successful, false if
|
|
313 * it failed.
|
|
314 */
|
|
315 queueProperty: function (key, value) {
|
|
316
|
|
317 key = key.toLowerCase();
|
|
318 YAHOO.log("queueProperty: " + key + "=" + value, "info", "Config");
|
|
319
|
|
320 var property = this.config[key],
|
|
321 foundDuplicate = false,
|
|
322 iLen,
|
|
323 queueItem,
|
|
324 queueItemKey,
|
|
325 queueItemValue,
|
|
326 sLen,
|
|
327 supercedesCheck,
|
|
328 qLen,
|
|
329 queueItemCheck,
|
|
330 queueItemCheckKey,
|
|
331 queueItemCheckValue,
|
|
332 i,
|
|
333 s,
|
|
334 q;
|
|
335
|
|
336 if (property && property.event) {
|
|
337
|
|
338 if (!Lang.isUndefined(value) && property.validator &&
|
|
339 !property.validator(value)) { // validator
|
|
340 return false;
|
|
341 } else {
|
|
342
|
|
343 if (!Lang.isUndefined(value)) {
|
|
344 property.value = value;
|
|
345 } else {
|
|
346 value = property.value;
|
|
347 }
|
|
348
|
|
349 foundDuplicate = false;
|
|
350 iLen = this.eventQueue.length;
|
|
351
|
|
352 for (i = 0; i < iLen; i++) {
|
|
353 queueItem = this.eventQueue[i];
|
|
354
|
|
355 if (queueItem) {
|
|
356 queueItemKey = queueItem[0];
|
|
357 queueItemValue = queueItem[1];
|
|
358
|
|
359 if (queueItemKey == key) {
|
|
360
|
|
361 /*
|
|
362 found a dupe... push to end of queue, null
|
|
363 current item, and break
|
|
364 */
|
|
365
|
|
366 this.eventQueue[i] = null;
|
|
367
|
|
368 this.eventQueue.push(
|
|
369 [key, (!Lang.isUndefined(value) ?
|
|
370 value : queueItemValue)]);
|
|
371
|
|
372 foundDuplicate = true;
|
|
373 break;
|
|
374 }
|
|
375 }
|
|
376 }
|
|
377
|
|
378 // this is a refire, or a new property in the queue
|
|
379
|
|
380 if (! foundDuplicate && !Lang.isUndefined(value)) {
|
|
381 this.eventQueue.push([key, value]);
|
|
382 }
|
|
383 }
|
|
384
|
|
385 if (property.supercedes) {
|
|
386
|
|
387 sLen = property.supercedes.length;
|
|
388
|
|
389 for (s = 0; s < sLen; s++) {
|
|
390
|
|
391 supercedesCheck = property.supercedes[s];
|
|
392 qLen = this.eventQueue.length;
|
|
393
|
|
394 for (q = 0; q < qLen; q++) {
|
|
395 queueItemCheck = this.eventQueue[q];
|
|
396
|
|
397 if (queueItemCheck) {
|
|
398 queueItemCheckKey = queueItemCheck[0];
|
|
399 queueItemCheckValue = queueItemCheck[1];
|
|
400
|
|
401 if (queueItemCheckKey ==
|
|
402 supercedesCheck.toLowerCase() ) {
|
|
403
|
|
404 this.eventQueue.push([queueItemCheckKey,
|
|
405 queueItemCheckValue]);
|
|
406
|
|
407 this.eventQueue[q] = null;
|
|
408 break;
|
|
409
|
|
410 }
|
|
411 }
|
|
412 }
|
|
413 }
|
|
414 }
|
|
415
|
|
416 YAHOO.log("Config event queue: " + this.outputEventQueue(), "info", "Config");
|
|
417
|
|
418 return true;
|
|
419 } else {
|
|
420 return false;
|
|
421 }
|
|
422 },
|
|
423
|
|
424 /**
|
|
425 * Fires the event for a property using the property's current value.
|
|
426 * @method refireEvent
|
|
427 * @param {String} key The name of the property
|
|
428 */
|
|
429 refireEvent: function (key) {
|
|
430
|
|
431 key = key.toLowerCase();
|
|
432
|
|
433 var property = this.config[key];
|
|
434
|
|
435 if (property && property.event &&
|
|
436
|
|
437 !Lang.isUndefined(property.value)) {
|
|
438
|
|
439 if (this.queueInProgress) {
|
|
440
|
|
441 this.queueProperty(key);
|
|
442
|
|
443 } else {
|
|
444
|
|
445 this.fireEvent(key, property.value);
|
|
446
|
|
447 }
|
|
448
|
|
449 }
|
|
450 },
|
|
451
|
|
452 /**
|
|
453 * Applies a key-value Object literal to the configuration, replacing
|
|
454 * any existing values, and queueing the property events.
|
|
455 * Although the values will be set, fireQueue() must be called for their
|
|
456 * associated events to execute.
|
|
457 * @method applyConfig
|
|
458 * @param {Object} userConfig The configuration Object literal
|
|
459 * @param {Boolean} init When set to true, the initialConfig will
|
|
460 * be set to the userConfig passed in, so that calling a reset will
|
|
461 * reset the properties to the passed values.
|
|
462 */
|
|
463 applyConfig: function (userConfig, init) {
|
|
464
|
|
465 var sKey,
|
|
466 oConfig;
|
|
467
|
|
468 if (init) {
|
|
469 oConfig = {};
|
|
470 for (sKey in userConfig) {
|
|
471 if (Lang.hasOwnProperty(userConfig, sKey)) {
|
|
472 oConfig[sKey.toLowerCase()] = userConfig[sKey];
|
|
473 }
|
|
474 }
|
|
475 this.initialConfig = oConfig;
|
|
476 }
|
|
477
|
|
478 for (sKey in userConfig) {
|
|
479 if (Lang.hasOwnProperty(userConfig, sKey)) {
|
|
480 this.queueProperty(sKey, userConfig[sKey]);
|
|
481 }
|
|
482 }
|
|
483 },
|
|
484
|
|
485 /**
|
|
486 * Refires the events for all configuration properties using their
|
|
487 * current values.
|
|
488 * @method refresh
|
|
489 */
|
|
490 refresh: function () {
|
|
491
|
|
492 var prop;
|
|
493
|
|
494 for (prop in this.config) {
|
|
495 if (Lang.hasOwnProperty(this.config, prop)) {
|
|
496 this.refireEvent(prop);
|
|
497 }
|
|
498 }
|
|
499 },
|
|
500
|
|
501 /**
|
|
502 * Fires the normalized list of queued property change events
|
|
503 * @method fireQueue
|
|
504 */
|
|
505 fireQueue: function () {
|
|
506
|
|
507 var i,
|
|
508 queueItem,
|
|
509 key,
|
|
510 value,
|
|
511 property;
|
|
512
|
|
513 this.queueInProgress = true;
|
|
514 for (i = 0;i < this.eventQueue.length; i++) {
|
|
515 queueItem = this.eventQueue[i];
|
|
516 if (queueItem) {
|
|
517
|
|
518 key = queueItem[0];
|
|
519 value = queueItem[1];
|
|
520 property = this.config[key];
|
|
521
|
|
522 property.value = value;
|
|
523
|
|
524 // Clear out queue entry, to avoid it being
|
|
525 // re-added to the queue by any queueProperty/supercedes
|
|
526 // calls which are invoked during fireEvent
|
|
527 this.eventQueue[i] = null;
|
|
528
|
|
529 this.fireEvent(key,value);
|
|
530 }
|
|
531 }
|
|
532
|
|
533 this.queueInProgress = false;
|
|
534 this.eventQueue = [];
|
|
535 },
|
|
536
|
|
537 /**
|
|
538 * Subscribes an external handler to the change event for any
|
|
539 * given property.
|
|
540 * @method subscribeToConfigEvent
|
|
541 * @param {String} key The property name
|
|
542 * @param {Function} handler The handler function to use subscribe to
|
|
543 * the property's event
|
|
544 * @param {Object} obj The Object to use for scoping the event handler
|
|
545 * (see CustomEvent documentation)
|
|
546 * @param {Boolean} overrideContext Optional. If true, will override
|
|
547 * "this" within the handler to map to the scope Object passed into the
|
|
548 * method.
|
|
549 * @return {Boolean} True, if the subscription was successful,
|
|
550 * otherwise false.
|
|
551 */
|
|
552 subscribeToConfigEvent: function (key, handler, obj, overrideContext) {
|
|
553
|
|
554 var property = this.config[key.toLowerCase()];
|
|
555
|
|
556 if (property && property.event) {
|
|
557 if (!Config.alreadySubscribed(property.event, handler, obj)) {
|
|
558 property.event.subscribe(handler, obj, overrideContext);
|
|
559 }
|
|
560 return true;
|
|
561 } else {
|
|
562 return false;
|
|
563 }
|
|
564
|
|
565 },
|
|
566
|
|
567 /**
|
|
568 * Unsubscribes an external handler from the change event for any
|
|
569 * given property.
|
|
570 * @method unsubscribeFromConfigEvent
|
|
571 * @param {String} key The property name
|
|
572 * @param {Function} handler The handler function to use subscribe to
|
|
573 * the property's event
|
|
574 * @param {Object} obj The Object to use for scoping the event
|
|
575 * handler (see CustomEvent documentation)
|
|
576 * @return {Boolean} True, if the unsubscription was successful,
|
|
577 * otherwise false.
|
|
578 */
|
|
579 unsubscribeFromConfigEvent: function (key, handler, obj) {
|
|
580 var property = this.config[key.toLowerCase()];
|
|
581 if (property && property.event) {
|
|
582 return property.event.unsubscribe(handler, obj);
|
|
583 } else {
|
|
584 return false;
|
|
585 }
|
|
586 },
|
|
587
|
|
588 /**
|
|
589 * Returns a string representation of the Config object
|
|
590 * @method toString
|
|
591 * @return {String} The Config object in string format.
|
|
592 */
|
|
593 toString: function () {
|
|
594 var output = "Config";
|
|
595 if (this.owner) {
|
|
596 output += " [" + this.owner.toString() + "]";
|
|
597 }
|
|
598 return output;
|
|
599 },
|
|
600
|
|
601 /**
|
|
602 * Returns a string representation of the Config object's current
|
|
603 * CustomEvent queue
|
|
604 * @method outputEventQueue
|
|
605 * @return {String} The string list of CustomEvents currently queued
|
|
606 * for execution
|
|
607 */
|
|
608 outputEventQueue: function () {
|
|
609
|
|
610 var output = "",
|
|
611 queueItem,
|
|
612 q,
|
|
613 nQueue = this.eventQueue.length;
|
|
614
|
|
615 for (q = 0; q < nQueue; q++) {
|
|
616 queueItem = this.eventQueue[q];
|
|
617 if (queueItem) {
|
|
618 output += queueItem[0] + "=" + queueItem[1] + ", ";
|
|
619 }
|
|
620 }
|
|
621 return output;
|
|
622 },
|
|
623
|
|
624 /**
|
|
625 * Sets all properties to null, unsubscribes all listeners from each
|
|
626 * property's change event and all listeners from the configChangedEvent.
|
|
627 * @method destroy
|
|
628 */
|
|
629 destroy: function () {
|
|
630
|
|
631 var oConfig = this.config,
|
|
632 sProperty,
|
|
633 oProperty;
|
|
634
|
|
635
|
|
636 for (sProperty in oConfig) {
|
|
637
|
|
638 if (Lang.hasOwnProperty(oConfig, sProperty)) {
|
|
639
|
|
640 oProperty = oConfig[sProperty];
|
|
641
|
|
642 oProperty.event.unsubscribeAll();
|
|
643 oProperty.event = null;
|
|
644
|
|
645 }
|
|
646
|
|
647 }
|
|
648
|
|
649 this.configChangedEvent.unsubscribeAll();
|
|
650
|
|
651 this.configChangedEvent = null;
|
|
652 this.owner = null;
|
|
653 this.config = null;
|
|
654 this.initialConfig = null;
|
|
655 this.eventQueue = null;
|
|
656
|
|
657 }
|
|
658
|
|
659 };
|
|
660
|
|
661
|
|
662
|
|
663 /**
|
|
664 * Checks to determine if a particular function/Object pair are already
|
|
665 * subscribed to the specified CustomEvent
|
|
666 * @method YAHOO.util.Config.alreadySubscribed
|
|
667 * @static
|
|
668 * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check
|
|
669 * the subscriptions
|
|
670 * @param {Function} fn The function to look for in the subscribers list
|
|
671 * @param {Object} obj The execution scope Object for the subscription
|
|
672 * @return {Boolean} true, if the function/Object pair is already subscribed
|
|
673 * to the CustomEvent passed in
|
|
674 */
|
|
675 Config.alreadySubscribed = function (evt, fn, obj) {
|
|
676
|
|
677 var nSubscribers = evt.subscribers.length,
|
|
678 subsc,
|
|
679 i;
|
|
680
|
|
681 if (nSubscribers > 0) {
|
|
682 i = nSubscribers - 1;
|
|
683 do {
|
|
684 subsc = evt.subscribers[i];
|
|
685 if (subsc && subsc.obj == obj && subsc.fn == fn) {
|
|
686 return true;
|
|
687 }
|
|
688 }
|
|
689 while (i--);
|
|
690 }
|
|
691
|
|
692 return false;
|
|
693
|
|
694 };
|
|
695
|
|
696 YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
|
|
697
|
|
698 }());
|
|
699 /**
|
|
700 * The datemath module provides utility methods for basic JavaScript Date object manipulation and
|
|
701 * comparison.
|
|
702 *
|
|
703 * @module datemath
|
|
704 */
|
|
705
|
|
706 /**
|
|
707 * YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
|
|
708 * used for adding, subtracting, and comparing dates.
|
|
709 * @namespace YAHOO.widget
|
|
710 * @class DateMath
|
|
711 */
|
|
712 YAHOO.widget.DateMath = {
|
|
713 /**
|
|
714 * Constant field representing Day
|
|
715 * @property DAY
|
|
716 * @static
|
|
717 * @final
|
|
718 * @type String
|
|
719 */
|
|
720 DAY : "D",
|
|
721
|
|
722 /**
|
|
723 * Constant field representing Week
|
|
724 * @property WEEK
|
|
725 * @static
|
|
726 * @final
|
|
727 * @type String
|
|
728 */
|
|
729 WEEK : "W",
|
|
730
|
|
731 /**
|
|
732 * Constant field representing Year
|
|
733 * @property YEAR
|
|
734 * @static
|
|
735 * @final
|
|
736 * @type String
|
|
737 */
|
|
738 YEAR : "Y",
|
|
739
|
|
740 /**
|
|
741 * Constant field representing Month
|
|
742 * @property MONTH
|
|
743 * @static
|
|
744 * @final
|
|
745 * @type String
|
|
746 */
|
|
747 MONTH : "M",
|
|
748
|
|
749 /**
|
|
750 * Constant field representing one day, in milliseconds
|
|
751 * @property ONE_DAY_MS
|
|
752 * @static
|
|
753 * @final
|
|
754 * @type Number
|
|
755 */
|
|
756 ONE_DAY_MS : 1000*60*60*24,
|
|
757
|
|
758 /**
|
|
759 * Constant field representing the date in first week of January
|
|
760 * which identifies the first week of the year.
|
|
761 * <p>
|
|
762 * In the U.S, Jan 1st is normally used based on a Sunday start of week.
|
|
763 * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
|
|
764 * </p>
|
|
765 * @property WEEK_ONE_JAN_DATE
|
|
766 * @static
|
|
767 * @type Number
|
|
768 */
|
|
769 WEEK_ONE_JAN_DATE : 1,
|
|
770
|
|
771 /**
|
|
772 * Adds the specified amount of time to the this instance.
|
|
773 * @method add
|
|
774 * @param {Date} date The JavaScript Date object to perform addition on
|
|
775 * @param {String} field The field constant to be used for performing addition.
|
|
776 * @param {Number} amount The number of units (measured in the field constant) to add to the date.
|
|
777 * @return {Date} The resulting Date object
|
|
778 */
|
|
779 add : function(date, field, amount) {
|
|
780 var d = new Date(date.getTime());
|
|
781 switch (field) {
|
|
782 case this.MONTH:
|
|
783 var newMonth = date.getMonth() + amount;
|
|
784 var years = 0;
|
|
785
|
|
786 if (newMonth < 0) {
|
|
787 while (newMonth < 0) {
|
|
788 newMonth += 12;
|
|
789 years -= 1;
|
|
790 }
|
|
791 } else if (newMonth > 11) {
|
|
792 while (newMonth > 11) {
|
|
793 newMonth -= 12;
|
|
794 years += 1;
|
|
795 }
|
|
796 }
|
|
797
|
|
798 d.setMonth(newMonth);
|
|
799 d.setFullYear(date.getFullYear() + years);
|
|
800 break;
|
|
801 case this.DAY:
|
|
802 this._addDays(d, amount);
|
|
803 // d.setDate(date.getDate() + amount);
|
|
804 break;
|
|
805 case this.YEAR:
|
|
806 d.setFullYear(date.getFullYear() + amount);
|
|
807 break;
|
|
808 case this.WEEK:
|
|
809 this._addDays(d, (amount * 7));
|
|
810 // d.setDate(date.getDate() + (amount * 7));
|
|
811 break;
|
|
812 }
|
|
813 return d;
|
|
814 },
|
|
815
|
|
816 /**
|
|
817 * Private helper method to account for bug in Safari 2 (webkit < 420)
|
|
818 * when Date.setDate(n) is called with n less than -128 or greater than 127.
|
|
819 * <p>
|
|
820 * Fix approach and original findings are available here:
|
|
821 * http://brianary.blogspot.com/2006/03/safari-date-bug.html
|
|
822 * </p>
|
|
823 * @method _addDays
|
|
824 * @param {Date} d JavaScript date object
|
|
825 * @param {Number} nDays The number of days to add to the date object (can be negative)
|
|
826 * @private
|
|
827 */
|
|
828 _addDays : function(d, nDays) {
|
|
829 if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
|
|
830 if (nDays < 0) {
|
|
831 // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
|
|
832 for(var min = -128; nDays < min; nDays -= min) {
|
|
833 d.setDate(d.getDate() + min);
|
|
834 }
|
|
835 } else {
|
|
836 // Ensure we don't go above 96 + 31 = 127
|
|
837 for(var max = 96; nDays > max; nDays -= max) {
|
|
838 d.setDate(d.getDate() + max);
|
|
839 }
|
|
840 }
|
|
841 // nDays should be remainder between -128 and 96
|
|
842 }
|
|
843 d.setDate(d.getDate() + nDays);
|
|
844 },
|
|
845
|
|
846 /**
|
|
847 * Subtracts the specified amount of time from the this instance.
|
|
848 * @method subtract
|
|
849 * @param {Date} date The JavaScript Date object to perform subtraction on
|
|
850 * @param {Number} field The this field constant to be used for performing subtraction.
|
|
851 * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
|
|
852 * @return {Date} The resulting Date object
|
|
853 */
|
|
854 subtract : function(date, field, amount) {
|
|
855 return this.add(date, field, (amount*-1));
|
|
856 },
|
|
857
|
|
858 /**
|
|
859 * Determines whether a given date is before another date on the calendar.
|
|
860 * @method before
|
|
861 * @param {Date} date The Date object to compare with the compare argument
|
|
862 * @param {Date} compareTo The Date object to use for the comparison
|
|
863 * @return {Boolean} true if the date occurs before the compared date; false if not.
|
|
864 */
|
|
865 before : function(date, compareTo) {
|
|
866 var ms = compareTo.getTime();
|
|
867 if (date.getTime() < ms) {
|
|
868 return true;
|
|
869 } else {
|
|
870 return false;
|
|
871 }
|
|
872 },
|
|
873
|
|
874 /**
|
|
875 * Determines whether a given date is after another date on the calendar.
|
|
876 * @method after
|
|
877 * @param {Date} date The Date object to compare with the compare argument
|
|
878 * @param {Date} compareTo The Date object to use for the comparison
|
|
879 * @return {Boolean} true if the date occurs after the compared date; false if not.
|
|
880 */
|
|
881 after : function(date, compareTo) {
|
|
882 var ms = compareTo.getTime();
|
|
883 if (date.getTime() > ms) {
|
|
884 return true;
|
|
885 } else {
|
|
886 return false;
|
|
887 }
|
|
888 },
|
|
889
|
|
890 /**
|
|
891 * Determines whether a given date is between two other dates on the calendar.
|
|
892 * @method between
|
|
893 * @param {Date} date The date to check for
|
|
894 * @param {Date} dateBegin The start of the range
|
|
895 * @param {Date} dateEnd The end of the range
|
|
896 * @return {Boolean} true if the date occurs between the compared dates; false if not.
|
|
897 */
|
|
898 between : function(date, dateBegin, dateEnd) {
|
|
899 if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
|
|
900 return true;
|
|
901 } else {
|
|
902 return false;
|
|
903 }
|
|
904 },
|
|
905
|
|
906 /**
|
|
907 * Retrieves a JavaScript Date object representing January 1 of any given year.
|
|
908 * @method getJan1
|
|
909 * @param {Number} calendarYear The calendar year for which to retrieve January 1
|
|
910 * @return {Date} January 1 of the calendar year specified.
|
|
911 */
|
|
912 getJan1 : function(calendarYear) {
|
|
913 return this.getDate(calendarYear,0,1);
|
|
914 },
|
|
915
|
|
916 /**
|
|
917 * Calculates the number of days the specified date is from January 1 of the specified calendar year.
|
|
918 * Passing January 1 to this function would return an offset value of zero.
|
|
919 * @method getDayOffset
|
|
920 * @param {Date} date The JavaScript date for which to find the offset
|
|
921 * @param {Number} calendarYear The calendar year to use for determining the offset
|
|
922 * @return {Number} The number of days since January 1 of the given year
|
|
923 */
|
|
924 getDayOffset : function(date, calendarYear) {
|
|
925 var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
|
|
926
|
|
927 // Find the number of days the passed in date is away from the calendar year start
|
|
928 var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
|
|
929 return dayOffset;
|
|
930 },
|
|
931
|
|
932 /**
|
|
933 * Calculates the week number for the given date. Can currently support standard
|
|
934 * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
|
|
935 * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
|
|
936 *
|
|
937 * @method getWeekNumber
|
|
938 * @param {Date} date The JavaScript date for which to find the week number
|
|
939 * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
|
|
940 * Defaults to 0
|
|
941 * @param {Number} janDate The date in the first week of January which defines week one for the year
|
|
942 * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
|
|
943 * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
|
|
944 *
|
|
945 * @return {Number} The number of the week containing the given date.
|
|
946 */
|
|
947 getWeekNumber : function(date, firstDayOfWeek, janDate) {
|
|
948
|
|
949 // Setup Defaults
|
|
950 firstDayOfWeek = firstDayOfWeek || 0;
|
|
951 janDate = janDate || this.WEEK_ONE_JAN_DATE;
|
|
952
|
|
953 var targetDate = this.clearTime(date),
|
|
954 startOfWeek,
|
|
955 endOfWeek;
|
|
956
|
|
957 if (targetDate.getDay() === firstDayOfWeek) {
|
|
958 startOfWeek = targetDate;
|
|
959 } else {
|
|
960 startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
|
|
961 }
|
|
962
|
|
963 var startYear = startOfWeek.getFullYear();
|
|
964
|
|
965 // DST shouldn't be a problem here, math is quicker than setDate();
|
|
966 endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
|
|
967
|
|
968 var weekNum;
|
|
969 if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
|
|
970 // If years don't match, endOfWeek is in Jan. and if the
|
|
971 // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
|
|
972 weekNum = 1;
|
|
973 } else {
|
|
974 // Get the 1st day of the 1st week, and
|
|
975 // find how many days away we are from it.
|
|
976 var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
|
|
977 weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
|
|
978
|
|
979 // Round days to smoothen out 1 hr DST diff
|
|
980 var daysDiff = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
|
|
981
|
|
982 // Calc. Full Weeks
|
|
983 var rem = daysDiff % 7;
|
|
984 var weeksDiff = (daysDiff - rem)/7;
|
|
985 weekNum = weeksDiff + 1;
|
|
986 }
|
|
987 return weekNum;
|
|
988 },
|
|
989
|
|
990 /**
|
|
991 * Get the first day of the week, for the give date.
|
|
992 * @param {Date} dt The date in the week for which the first day is required.
|
|
993 * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
|
|
994 * @return {Date} The first day of the week
|
|
995 */
|
|
996 getFirstDayOfWeek : function (dt, startOfWeek) {
|
|
997 startOfWeek = startOfWeek || 0;
|
|
998 var dayOfWeekIndex = dt.getDay(),
|
|
999 dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
|
|
1000
|
|
1001 return this.subtract(dt, this.DAY, dayOfWeek);
|
|
1002 },
|
|
1003
|
|
1004 /**
|
|
1005 * Determines if a given week overlaps two different years.
|
|
1006 * @method isYearOverlapWeek
|
|
1007 * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
|
|
1008 * @return {Boolean} true if the date overlaps two different years.
|
|
1009 */
|
|
1010 isYearOverlapWeek : function(weekBeginDate) {
|
|
1011 var overlaps = false;
|
|
1012 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
|
|
1013 if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
|
|
1014 overlaps = true;
|
|
1015 }
|
|
1016 return overlaps;
|
|
1017 },
|
|
1018
|
|
1019 /**
|
|
1020 * Determines if a given week overlaps two different months.
|
|
1021 * @method isMonthOverlapWeek
|
|
1022 * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
|
|
1023 * @return {Boolean} true if the date overlaps two different months.
|
|
1024 */
|
|
1025 isMonthOverlapWeek : function(weekBeginDate) {
|
|
1026 var overlaps = false;
|
|
1027 var nextWeek = this.add(weekBeginDate, this.DAY, 6);
|
|
1028 if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
|
|
1029 overlaps = true;
|
|
1030 }
|
|
1031 return overlaps;
|
|
1032 },
|
|
1033
|
|
1034 /**
|
|
1035 * Gets the first day of a month containing a given date.
|
|
1036 * @method findMonthStart
|
|
1037 * @param {Date} date The JavaScript Date used to calculate the month start
|
|
1038 * @return {Date} The JavaScript Date representing the first day of the month
|
|
1039 */
|
|
1040 findMonthStart : function(date) {
|
|
1041 var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
|
|
1042 return start;
|
|
1043 },
|
|
1044
|
|
1045 /**
|
|
1046 * Gets the last day of a month containing a given date.
|
|
1047 * @method findMonthEnd
|
|
1048 * @param {Date} date The JavaScript Date used to calculate the month end
|
|
1049 * @return {Date} The JavaScript Date representing the last day of the month
|
|
1050 */
|
|
1051 findMonthEnd : function(date) {
|
|
1052 var start = this.findMonthStart(date);
|
|
1053 var nextMonth = this.add(start, this.MONTH, 1);
|
|
1054 var end = this.subtract(nextMonth, this.DAY, 1);
|
|
1055 return end;
|
|
1056 },
|
|
1057
|
|
1058 /**
|
|
1059 * Clears the time fields from a given date, effectively setting the time to 12 noon.
|
|
1060 * @method clearTime
|
|
1061 * @param {Date} date The JavaScript Date for which the time fields will be cleared
|
|
1062 * @return {Date} The JavaScript Date cleared of all time fields
|
|
1063 */
|
|
1064 clearTime : function(date) {
|
|
1065 date.setHours(12,0,0,0);
|
|
1066 return date;
|
|
1067 },
|
|
1068
|
|
1069 /**
|
|
1070 * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
|
|
1071 * are set to 0. The method allows Date instances to be created with the a year less than 100. "new Date(year, month, date)" implementations
|
|
1072 * set the year to 19xx if a year (xx) which is less than 100 is provided.
|
|
1073 * <p>
|
|
1074 * <em>NOTE:</em>Validation on argument values is not performed. It is the caller's responsibility to ensure
|
|
1075 * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
|
|
1076 * </p>
|
|
1077 * @method getDate
|
|
1078 * @param {Number} y Year.
|
|
1079 * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
|
|
1080 * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
|
|
1081 * @return {Date} The JavaScript date object with year, month, date set as provided.
|
|
1082 */
|
|
1083 getDate : function(y, m, d) {
|
|
1084 var dt = null;
|
|
1085 if (YAHOO.lang.isUndefined(d)) {
|
|
1086 d = 1;
|
|
1087 }
|
|
1088 if (y >= 100) {
|
|
1089 dt = new Date(y, m, d);
|
|
1090 } else {
|
|
1091 dt = new Date();
|
|
1092 dt.setFullYear(y);
|
|
1093 dt.setMonth(m);
|
|
1094 dt.setDate(d);
|
|
1095 dt.setHours(0,0,0,0);
|
|
1096 }
|
|
1097 return dt;
|
|
1098 }
|
|
1099 };
|
|
1100 /**
|
|
1101 * The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month or
|
|
1102 * multi-month interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
|
|
1103 * @module calendar
|
|
1104 * @title Calendar
|
|
1105 * @namespace YAHOO.widget
|
|
1106 * @requires yahoo,dom,event
|
|
1107 */
|
|
1108 (function(){
|
|
1109
|
|
1110 var Dom = YAHOO.util.Dom,
|
|
1111 Event = YAHOO.util.Event,
|
|
1112 Lang = YAHOO.lang,
|
|
1113 DateMath = YAHOO.widget.DateMath;
|
|
1114
|
|
1115 /**
|
|
1116 * Calendar is the base class for the Calendar widget. In its most basic
|
|
1117 * implementation, it has the ability to render a calendar widget on the page
|
|
1118 * that can be manipulated to select a single date, move back and forth between
|
|
1119 * months and years.
|
|
1120 * <p>To construct the placeholder for the calendar widget, the code is as
|
|
1121 * follows:
|
|
1122 * <xmp>
|
|
1123 * <div id="calContainer"></div>
|
|
1124 * </xmp>
|
|
1125 * </p>
|
|
1126 * <p>
|
|
1127 * <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
|
|
1128 * The Calendar can be constructed by simply providing a container ID string,
|
|
1129 * or a reference to a container DIV HTMLElement (the element needs to exist
|
|
1130 * in the document).
|
|
1131 *
|
|
1132 * E.g.:
|
|
1133 * <xmp>
|
|
1134 * var c = new YAHOO.widget.Calendar("calContainer", configOptions);
|
|
1135 * </xmp>
|
|
1136 * or:
|
|
1137 * <xmp>
|
|
1138 * var containerDiv = YAHOO.util.Dom.get("calContainer");
|
|
1139 * var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
|
|
1140 * </xmp>
|
|
1141 * </p>
|
|
1142 * <p>
|
|
1143 * If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
|
|
1144 * For example if an ID is not provided, and the container's ID is "calContainer", the Calendar's ID will be set to "calContainer_t".
|
|
1145 * </p>
|
|
1146 *
|
|
1147 * @namespace YAHOO.widget
|
|
1148 * @class Calendar
|
|
1149 * @constructor
|
|
1150 * @param {String} id optional The id of the table element that will represent the Calendar widget. As of 2.4.0, this argument is optional.
|
|
1151 * @param {String | HTMLElement} container The id of the container div element that will wrap the Calendar table, or a reference to a DIV element which exists in the document.
|
|
1152 * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
|
|
1153 */
|
|
1154 function Calendar(id, containerId, config) {
|
|
1155 this.init.apply(this, arguments);
|
|
1156 }
|
|
1157
|
|
1158 /**
|
|
1159 * The path to be used for images loaded for the Calendar
|
|
1160 * @property YAHOO.widget.Calendar.IMG_ROOT
|
|
1161 * @static
|
|
1162 * @deprecated You can now customize images by overriding the calclose, calnavleft and calnavright default CSS classes for the close icon, left arrow and right arrow respectively
|
|
1163 * @type String
|
|
1164 */
|
|
1165 Calendar.IMG_ROOT = null;
|
|
1166
|
|
1167 /**
|
|
1168 * Type constant used for renderers to represent an individual date (M/D/Y)
|
|
1169 * @property YAHOO.widget.Calendar.DATE
|
|
1170 * @static
|
|
1171 * @final
|
|
1172 * @type String
|
|
1173 */
|
|
1174 Calendar.DATE = "D";
|
|
1175
|
|
1176 /**
|
|
1177 * Type constant used for renderers to represent an individual date across any year (M/D)
|
|
1178 * @property YAHOO.widget.Calendar.MONTH_DAY
|
|
1179 * @static
|
|
1180 * @final
|
|
1181 * @type String
|
|
1182 */
|
|
1183 Calendar.MONTH_DAY = "MD";
|
|
1184
|
|
1185 /**
|
|
1186 * Type constant used for renderers to represent a weekday
|
|
1187 * @property YAHOO.widget.Calendar.WEEKDAY
|
|
1188 * @static
|
|
1189 * @final
|
|
1190 * @type String
|
|
1191 */
|
|
1192 Calendar.WEEKDAY = "WD";
|
|
1193
|
|
1194 /**
|
|
1195 * Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
|
|
1196 * @property YAHOO.widget.Calendar.RANGE
|
|
1197 * @static
|
|
1198 * @final
|
|
1199 * @type String
|
|
1200 */
|
|
1201 Calendar.RANGE = "R";
|
|
1202
|
|
1203 /**
|
|
1204 * Type constant used for renderers to represent a month across any year
|
|
1205 * @property YAHOO.widget.Calendar.MONTH
|
|
1206 * @static
|
|
1207 * @final
|
|
1208 * @type String
|
|
1209 */
|
|
1210 Calendar.MONTH = "M";
|
|
1211
|
|
1212 /**
|
|
1213 * Constant that represents the total number of date cells that are displayed in a given month
|
|
1214 * @property YAHOO.widget.Calendar.DISPLAY_DAYS
|
|
1215 * @static
|
|
1216 * @final
|
|
1217 * @type Number
|
|
1218 */
|
|
1219 Calendar.DISPLAY_DAYS = 42;
|
|
1220
|
|
1221 /**
|
|
1222 * Constant used for halting the execution of the remainder of the render stack
|
|
1223 * @property YAHOO.widget.Calendar.STOP_RENDER
|
|
1224 * @static
|
|
1225 * @final
|
|
1226 * @type String
|
|
1227 */
|
|
1228 Calendar.STOP_RENDER = "S";
|
|
1229
|
|
1230 /**
|
|
1231 * Constant used to represent short date field string formats (e.g. Tu or Feb)
|
|
1232 * @property YAHOO.widget.Calendar.SHORT
|
|
1233 * @static
|
|
1234 * @final
|
|
1235 * @type String
|
|
1236 */
|
|
1237 Calendar.SHORT = "short";
|
|
1238
|
|
1239 /**
|
|
1240 * Constant used to represent long date field string formats (e.g. Monday or February)
|
|
1241 * @property YAHOO.widget.Calendar.LONG
|
|
1242 * @static
|
|
1243 * @final
|
|
1244 * @type String
|
|
1245 */
|
|
1246 Calendar.LONG = "long";
|
|
1247
|
|
1248 /**
|
|
1249 * Constant used to represent medium date field string formats (e.g. Mon)
|
|
1250 * @property YAHOO.widget.Calendar.MEDIUM
|
|
1251 * @static
|
|
1252 * @final
|
|
1253 * @type String
|
|
1254 */
|
|
1255 Calendar.MEDIUM = "medium";
|
|
1256
|
|
1257 /**
|
|
1258 * Constant used to represent single character date field string formats (e.g. M, T, W)
|
|
1259 * @property YAHOO.widget.Calendar.ONE_CHAR
|
|
1260 * @static
|
|
1261 * @final
|
|
1262 * @type String
|
|
1263 */
|
|
1264 Calendar.ONE_CHAR = "1char";
|
|
1265
|
|
1266 /**
|
|
1267 * The set of default Config property keys and values for the Calendar.
|
|
1268 *
|
|
1269 * <p>
|
|
1270 * NOTE: This property is made public in order to allow users to change
|
|
1271 * the default values of configuration properties. Users should not
|
|
1272 * modify the key string, unless they are overriding the Calendar implementation
|
|
1273 * </p>
|
|
1274 *
|
|
1275 * <p>
|
|
1276 * The property is an object with key/value pairs, the key being the
|
|
1277 * uppercase configuration property name and the value being an object
|
|
1278 * literal with a key string property, and a value property, specifying the
|
|
1279 * default value of the property. To override a default value, you can set
|
|
1280 * the value property, for example, <code>YAHOO.widget.Calendar.DEFAULT_CONFIG.MULTI_SELECT.value = true;</code>
|
|
1281 *
|
|
1282 * @property YAHOO.widget.Calendar.DEFAULT_CONFIG
|
|
1283 * @static
|
|
1284 * @type Object
|
|
1285 */
|
|
1286
|
|
1287 Calendar.DEFAULT_CONFIG = {
|
|
1288 YEAR_OFFSET : {key:"year_offset", value:0, supercedes:["pagedate", "selected", "mindate","maxdate"]},
|
|
1289 TODAY : {key:"today", value:new Date(), supercedes:["pagedate"]},
|
|
1290 PAGEDATE : {key:"pagedate", value:null},
|
|
1291 SELECTED : {key:"selected", value:[]},
|
|
1292 TITLE : {key:"title", value:""},
|
|
1293 CLOSE : {key:"close", value:false},
|
|
1294 IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
|
|
1295 MINDATE : {key:"mindate", value:null},
|
|
1296 MAXDATE : {key:"maxdate", value:null},
|
|
1297 MULTI_SELECT : {key:"multi_select", value:false},
|
|
1298 START_WEEKDAY : {key:"start_weekday", value:0},
|
|
1299 SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
|
|
1300 SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
|
|
1301 SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
|
|
1302 HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
|
|
1303 NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
|
|
1304 NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
|
|
1305 MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
|
|
1306 MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
|
|
1307 WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
|
|
1308 WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
|
|
1309 WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
|
|
1310 WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
|
|
1311 LOCALE_MONTHS:{key:"locale_months", value:"long"},
|
|
1312 LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
|
|
1313 DATE_DELIMITER:{key:"date_delimiter", value:","},
|
|
1314 DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
|
|
1315 DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
|
|
1316 MY_MONTH_POSITION:{key:"my_month_position", value:1},
|
|
1317 MY_YEAR_POSITION:{key:"my_year_position", value:2},
|
|
1318 MD_MONTH_POSITION:{key:"md_month_position", value:1},
|
|
1319 MD_DAY_POSITION:{key:"md_day_position", value:2},
|
|
1320 MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
|
|
1321 MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
|
|
1322 MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
|
|
1323 MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
|
|
1324 MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
|
|
1325 MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
|
|
1326 MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""},
|
|
1327 NAV: {key:"navigator", value: null},
|
|
1328 STRINGS : {
|
|
1329 key:"strings",
|
|
1330 value: {
|
|
1331 previousMonth : "Previous Month",
|
|
1332 nextMonth : "Next Month",
|
|
1333 close: "Close"
|
|
1334 },
|
|
1335 supercedes : ["close", "title"]
|
|
1336 }
|
|
1337 };
|
|
1338
|
|
1339 /**
|
|
1340 * The set of default Config property keys and values for the Calendar
|
|
1341 * @property YAHOO.widget.Calendar._DEFAULT_CONFIG
|
|
1342 * @deprecated Made public. See the public DEFAULT_CONFIG property for details
|
|
1343 * @final
|
|
1344 * @static
|
|
1345 * @private
|
|
1346 * @type Object
|
|
1347 */
|
|
1348 Calendar._DEFAULT_CONFIG = Calendar.DEFAULT_CONFIG;
|
|
1349
|
|
1350 var DEF_CFG = Calendar.DEFAULT_CONFIG;
|
|
1351
|
|
1352 /**
|
|
1353 * The set of Custom Event types supported by the Calendar
|
|
1354 * @property YAHOO.widget.Calendar._EVENT_TYPES
|
|
1355 * @final
|
|
1356 * @static
|
|
1357 * @private
|
|
1358 * @type Object
|
|
1359 */
|
|
1360 Calendar._EVENT_TYPES = {
|
|
1361 BEFORE_SELECT : "beforeSelect",
|
|
1362 SELECT : "select",
|
|
1363 BEFORE_DESELECT : "beforeDeselect",
|
|
1364 DESELECT : "deselect",
|
|
1365 CHANGE_PAGE : "changePage",
|
|
1366 BEFORE_RENDER : "beforeRender",
|
|
1367 RENDER : "render",
|
|
1368 BEFORE_DESTROY : "beforeDestroy",
|
|
1369 DESTROY : "destroy",
|
|
1370 RESET : "reset",
|
|
1371 CLEAR : "clear",
|
|
1372 BEFORE_HIDE : "beforeHide",
|
|
1373 HIDE : "hide",
|
|
1374 BEFORE_SHOW : "beforeShow",
|
|
1375 SHOW : "show",
|
|
1376 BEFORE_HIDE_NAV : "beforeHideNav",
|
|
1377 HIDE_NAV : "hideNav",
|
|
1378 BEFORE_SHOW_NAV : "beforeShowNav",
|
|
1379 SHOW_NAV : "showNav",
|
|
1380 BEFORE_RENDER_NAV : "beforeRenderNav",
|
|
1381 RENDER_NAV : "renderNav"
|
|
1382 };
|
|
1383
|
|
1384 /**
|
|
1385 * The set of default style constants for the Calendar
|
|
1386 * @property YAHOO.widget.Calendar.STYLES
|
|
1387 * @static
|
|
1388 * @type Object An object with name/value pairs for the class name identifier/value.
|
|
1389 */
|
|
1390 Calendar.STYLES = {
|
|
1391 CSS_ROW_HEADER: "calrowhead",
|
|
1392 CSS_ROW_FOOTER: "calrowfoot",
|
|
1393 CSS_CELL : "calcell",
|
|
1394 CSS_CELL_SELECTOR : "selector",
|
|
1395 CSS_CELL_SELECTED : "selected",
|
|
1396 CSS_CELL_SELECTABLE : "selectable",
|
|
1397 CSS_CELL_RESTRICTED : "restricted",
|
|
1398 CSS_CELL_TODAY : "today",
|
|
1399 CSS_CELL_OOM : "oom",
|
|
1400 CSS_CELL_OOB : "previous",
|
|
1401 CSS_HEADER : "calheader",
|
|
1402 CSS_HEADER_TEXT : "calhead",
|
|
1403 CSS_BODY : "calbody",
|
|
1404 CSS_WEEKDAY_CELL : "calweekdaycell",
|
|
1405 CSS_WEEKDAY_ROW : "calweekdayrow",
|
|
1406 CSS_FOOTER : "calfoot",
|
|
1407 CSS_CALENDAR : "yui-calendar",
|
|
1408 CSS_SINGLE : "single",
|
|
1409 CSS_CONTAINER : "yui-calcontainer",
|
|
1410 CSS_NAV_LEFT : "calnavleft",
|
|
1411 CSS_NAV_RIGHT : "calnavright",
|
|
1412 CSS_NAV : "calnav",
|
|
1413 CSS_CLOSE : "calclose",
|
|
1414 CSS_CELL_TOP : "calcelltop",
|
|
1415 CSS_CELL_LEFT : "calcellleft",
|
|
1416 CSS_CELL_RIGHT : "calcellright",
|
|
1417 CSS_CELL_BOTTOM : "calcellbottom",
|
|
1418 CSS_CELL_HOVER : "calcellhover",
|
|
1419 CSS_CELL_HIGHLIGHT1 : "highlight1",
|
|
1420 CSS_CELL_HIGHLIGHT2 : "highlight2",
|
|
1421 CSS_CELL_HIGHLIGHT3 : "highlight3",
|
|
1422 CSS_CELL_HIGHLIGHT4 : "highlight4",
|
|
1423 CSS_WITH_TITLE: "withtitle",
|
|
1424 CSS_FIXED_SIZE: "fixedsize",
|
|
1425 CSS_LINK_CLOSE: "link-close"
|
|
1426 };
|
|
1427
|
|
1428 /**
|
|
1429 * The set of default style constants for the Calendar
|
|
1430 * @property YAHOO.widget.Calendar._STYLES
|
|
1431 * @deprecated Made public. See the public STYLES property for details
|
|
1432 * @final
|
|
1433 * @static
|
|
1434 * @private
|
|
1435 * @type Object
|
|
1436 */
|
|
1437 Calendar._STYLES = Calendar.STYLES;
|
|
1438
|
|
1439 Calendar.prototype = {
|
|
1440
|
|
1441 /**
|
|
1442 * The configuration object used to set up the calendars various locale and style options.
|
|
1443 * @property Config
|
|
1444 * @private
|
|
1445 * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
|
|
1446 * @type Object
|
|
1447 */
|
|
1448 Config : null,
|
|
1449
|
|
1450 /**
|
|
1451 * The parent CalendarGroup, only to be set explicitly by the parent group
|
|
1452 * @property parent
|
|
1453 * @type CalendarGroup
|
|
1454 */
|
|
1455 parent : null,
|
|
1456
|
|
1457 /**
|
|
1458 * The index of this item in the parent group
|
|
1459 * @property index
|
|
1460 * @type Number
|
|
1461 */
|
|
1462 index : -1,
|
|
1463
|
|
1464 /**
|
|
1465 * The collection of calendar table cells
|
|
1466 * @property cells
|
|
1467 * @type HTMLTableCellElement[]
|
|
1468 */
|
|
1469 cells : null,
|
|
1470
|
|
1471 /**
|
|
1472 * 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].
|
|
1473 * @property cellDates
|
|
1474 * @type Array[](Number[])
|
|
1475 */
|
|
1476 cellDates : null,
|
|
1477
|
|
1478 /**
|
|
1479 * The id that uniquely identifies this Calendar.
|
|
1480 * @property id
|
|
1481 * @type String
|
|
1482 */
|
|
1483 id : null,
|
|
1484
|
|
1485 /**
|
|
1486 * The unique id associated with the Calendar's container
|
|
1487 * @property containerId
|
|
1488 * @type String
|
|
1489 */
|
|
1490 containerId: null,
|
|
1491
|
|
1492 /**
|
|
1493 * 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.
|
|
1494 * @property oDomContainer
|
|
1495 * @type HTMLElement
|
|
1496 */
|
|
1497 oDomContainer : null,
|
|
1498
|
|
1499 /**
|
|
1500 * A Date object representing today's date.
|
|
1501 * @deprecated Use the "today" configuration property
|
|
1502 * @property today
|
|
1503 * @type Date
|
|
1504 */
|
|
1505 today : null,
|
|
1506
|
|
1507 /**
|
|
1508 * The list of render functions, along with required parameters, used to render cells.
|
|
1509 * @property renderStack
|
|
1510 * @type Array[]
|
|
1511 */
|
|
1512 renderStack : null,
|
|
1513
|
|
1514 /**
|
|
1515 * A copy of the initial render functions created before rendering.
|
|
1516 * @property _renderStack
|
|
1517 * @private
|
|
1518 * @type Array
|
|
1519 */
|
|
1520 _renderStack : null,
|
|
1521
|
|
1522 /**
|
|
1523 * A reference to the CalendarNavigator instance created for this Calendar.
|
|
1524 * Will be null if the "navigator" configuration property has not been set
|
|
1525 * @property oNavigator
|
|
1526 * @type CalendarNavigator
|
|
1527 */
|
|
1528 oNavigator : null,
|
|
1529
|
|
1530 /**
|
|
1531 * The private list of initially selected dates.
|
|
1532 * @property _selectedDates
|
|
1533 * @private
|
|
1534 * @type Array
|
|
1535 */
|
|
1536 _selectedDates : null,
|
|
1537
|
|
1538 /**
|
|
1539 * A map of DOM event handlers to attach to cells associated with specific CSS class names
|
|
1540 * @property domEventMap
|
|
1541 * @type Object
|
|
1542 */
|
|
1543 domEventMap : null,
|
|
1544
|
|
1545 /**
|
|
1546 * Protected helper used to parse Calendar constructor/init arguments.
|
|
1547 *
|
|
1548 * As of 2.4.0, Calendar supports a simpler constructor
|
|
1549 * signature. This method reconciles arguments
|
|
1550 * received in the pre 2.4.0 and 2.4.0 formats.
|
|
1551 *
|
|
1552 * @protected
|
|
1553 * @method _parseArgs
|
|
1554 * @param {Array} Function "arguments" array
|
|
1555 * @return {Object} Object with id, container, config properties containing
|
|
1556 * the reconciled argument values.
|
|
1557 **/
|
|
1558 _parseArgs : function(args) {
|
|
1559 /*
|
|
1560 2.4.0 Constructors signatures
|
|
1561
|
|
1562 new Calendar(String)
|
|
1563 new Calendar(HTMLElement)
|
|
1564 new Calendar(String, ConfigObject)
|
|
1565 new Calendar(HTMLElement, ConfigObject)
|
|
1566
|
|
1567 Pre 2.4.0 Constructor signatures
|
|
1568
|
|
1569 new Calendar(String, String)
|
|
1570 new Calendar(String, HTMLElement)
|
|
1571 new Calendar(String, String, ConfigObject)
|
|
1572 new Calendar(String, HTMLElement, ConfigObject)
|
|
1573 */
|
|
1574 var nArgs = {id:null, container:null, config:null};
|
|
1575
|
|
1576 if (args && args.length && args.length > 0) {
|
|
1577 switch (args.length) {
|
|
1578 case 1:
|
|
1579 nArgs.id = null;
|
|
1580 nArgs.container = args[0];
|
|
1581 nArgs.config = null;
|
|
1582 break;
|
|
1583 case 2:
|
|
1584 if (Lang.isObject(args[1]) && !args[1].tagName && !(args[1] instanceof String)) {
|
|
1585 nArgs.id = null;
|
|
1586 nArgs.container = args[0];
|
|
1587 nArgs.config = args[1];
|
|
1588 } else {
|
|
1589 nArgs.id = args[0];
|
|
1590 nArgs.container = args[1];
|
|
1591 nArgs.config = null;
|
|
1592 }
|
|
1593 break;
|
|
1594 default: // 3+
|
|
1595 nArgs.id = args[0];
|
|
1596 nArgs.container = args[1];
|
|
1597 nArgs.config = args[2];
|
|
1598 break;
|
|
1599 }
|
|
1600 } else {
|
|
1601 this.logger.log("Invalid constructor/init arguments", "error");
|
|
1602 }
|
|
1603 return nArgs;
|
|
1604 },
|
|
1605
|
|
1606 /**
|
|
1607 * Initializes the Calendar widget.
|
|
1608 * @method init
|
|
1609 *
|
|
1610 * @param {String} id optional The id of the table element that will represent the Calendar widget. As of 2.4.0, this argument is optional.
|
|
1611 * @param {String | HTMLElement} container The id of the container div element that will wrap the Calendar table, or a reference to a DIV element which exists in the document.
|
|
1612 * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
|
|
1613 */
|
|
1614 init : function(id, container, config) {
|
|
1615 // Normalize 2.4.0, pre 2.4.0 args
|
|
1616 var nArgs = this._parseArgs(arguments);
|
|
1617
|
|
1618 id = nArgs.id;
|
|
1619 container = nArgs.container;
|
|
1620 config = nArgs.config;
|
|
1621
|
|
1622 this.oDomContainer = Dom.get(container);
|
|
1623 if (!this.oDomContainer) { this.logger.log("Container not found in document.", "error"); }
|
|
1624
|
|
1625 if (!this.oDomContainer.id) {
|
|
1626 this.oDomContainer.id = Dom.generateId();
|
|
1627 }
|
|
1628 if (!id) {
|
|
1629 id = this.oDomContainer.id + "_t";
|
|
1630 }
|
|
1631
|
|
1632 this.id = id;
|
|
1633 this.containerId = this.oDomContainer.id;
|
|
1634
|
|
1635 this.logger = new YAHOO.widget.LogWriter("Calendar " + this.id);
|
|
1636 this.initEvents();
|
|
1637
|
|
1638 /**
|
|
1639 * The Config object used to hold the configuration variables for the Calendar
|
|
1640 * @property cfg
|
|
1641 * @type YAHOO.util.Config
|
|
1642 */
|
|
1643 this.cfg = new YAHOO.util.Config(this);
|
|
1644
|
|
1645 /**
|
|
1646 * The local object which contains the Calendar's options
|
|
1647 * @property Options
|
|
1648 * @type Object
|
|
1649 */
|
|
1650 this.Options = {};
|
|
1651
|
|
1652 /**
|
|
1653 * The local object which contains the Calendar's locale settings
|
|
1654 * @property Locale
|
|
1655 * @type Object
|
|
1656 */
|
|
1657 this.Locale = {};
|
|
1658
|
|
1659 this.initStyles();
|
|
1660
|
|
1661 Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
|
|
1662 Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
|
|
1663
|
|
1664 this.cellDates = [];
|
|
1665 this.cells = [];
|
|
1666 this.renderStack = [];
|
|
1667 this._renderStack = [];
|
|
1668
|
|
1669 this.setupConfig();
|
|
1670
|
|
1671 if (config) {
|
|
1672 this.cfg.applyConfig(config, true);
|
|
1673 }
|
|
1674
|
|
1675 this.cfg.fireQueue();
|
|
1676
|
|
1677 this.today = this.cfg.getProperty("today");
|
|
1678 },
|
|
1679
|
|
1680 /**
|
|
1681 * Default Config listener for the iframe property. If the iframe config property is set to true,
|
|
1682 * renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
|
|
1683 *
|
|
1684 * @method configIframe
|
|
1685 */
|
|
1686 configIframe : function(type, args, obj) {
|
|
1687 var useIframe = args[0];
|
|
1688
|
|
1689 if (!this.parent) {
|
|
1690 if (Dom.inDocument(this.oDomContainer)) {
|
|
1691 if (useIframe) {
|
|
1692 var pos = Dom.getStyle(this.oDomContainer, "position");
|
|
1693
|
|
1694 if (pos == "absolute" || pos == "relative") {
|
|
1695
|
|
1696 if (!Dom.inDocument(this.iframe)) {
|
|
1697 this.iframe = document.createElement("iframe");
|
|
1698 this.iframe.src = "javascript:false;";
|
|
1699
|
|
1700 Dom.setStyle(this.iframe, "opacity", "0");
|
|
1701
|
|
1702 if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
|
|
1703 Dom.addClass(this.iframe, this.Style.CSS_FIXED_SIZE);
|
|
1704 }
|
|
1705
|
|
1706 this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
|
|
1707 }
|
|
1708 }
|
|
1709 } else {
|
|
1710 if (this.iframe) {
|
|
1711 if (this.iframe.parentNode) {
|
|
1712 this.iframe.parentNode.removeChild(this.iframe);
|
|
1713 }
|
|
1714 this.iframe = null;
|
|
1715 }
|
|
1716 }
|
|
1717 }
|
|
1718 }
|
|
1719 },
|
|
1720
|
|
1721 /**
|
|
1722 * Default handler for the "title" property
|
|
1723 * @method configTitle
|
|
1724 */
|
|
1725 configTitle : function(type, args, obj) {
|
|
1726 var title = args[0];
|
|
1727
|
|
1728 // "" disables title bar
|
|
1729 if (title) {
|
|
1730 this.createTitleBar(title);
|
|
1731 } else {
|
|
1732 var close = this.cfg.getProperty(DEF_CFG.CLOSE.key);
|
|
1733 if (!close) {
|
|
1734 this.removeTitleBar();
|
|
1735 } else {
|
|
1736 this.createTitleBar(" ");
|
|
1737 }
|
|
1738 }
|
|
1739 },
|
|
1740
|
|
1741 /**
|
|
1742 * Default handler for the "close" property
|
|
1743 * @method configClose
|
|
1744 */
|
|
1745 configClose : function(type, args, obj) {
|
|
1746 var close = args[0],
|
|
1747 title = this.cfg.getProperty(DEF_CFG.TITLE.key);
|
|
1748
|
|
1749 if (close) {
|
|
1750 if (!title) {
|
|
1751 this.createTitleBar(" ");
|
|
1752 }
|
|
1753 this.createCloseButton();
|
|
1754 } else {
|
|
1755 this.removeCloseButton();
|
|
1756 if (!title) {
|
|
1757 this.removeTitleBar();
|
|
1758 }
|
|
1759 }
|
|
1760 },
|
|
1761
|
|
1762 /**
|
|
1763 * Initializes Calendar's built-in CustomEvents
|
|
1764 * @method initEvents
|
|
1765 */
|
|
1766 initEvents : function() {
|
|
1767
|
|
1768 var defEvents = Calendar._EVENT_TYPES,
|
|
1769 CE = YAHOO.util.CustomEvent,
|
|
1770 cal = this; // To help with minification
|
|
1771
|
|
1772 /**
|
|
1773 * Fired before a date selection is made
|
|
1774 * @event beforeSelectEvent
|
|
1775 */
|
|
1776 cal.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
|
|
1777
|
|
1778 /**
|
|
1779 * Fired when a date selection is made
|
|
1780 * @event selectEvent
|
|
1781 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
|
|
1782 */
|
|
1783 cal.selectEvent = new CE(defEvents.SELECT);
|
|
1784
|
|
1785 /**
|
|
1786 * Fired before a date or set of dates is deselected
|
|
1787 * @event beforeDeselectEvent
|
|
1788 */
|
|
1789 cal.beforeDeselectEvent = new CE(defEvents.BEFORE_DESELECT);
|
|
1790
|
|
1791 /**
|
|
1792 * Fired when a date or set of dates is deselected
|
|
1793 * @event deselectEvent
|
|
1794 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
|
|
1795 */
|
|
1796 cal.deselectEvent = new CE(defEvents.DESELECT);
|
|
1797
|
|
1798 /**
|
|
1799 * Fired when the Calendar page is changed
|
|
1800 * @event changePageEvent
|
|
1801 * @param {Date} prevDate The date before the page was changed
|
|
1802 * @param {Date} newDate The date after the page was changed
|
|
1803 */
|
|
1804 cal.changePageEvent = new CE(defEvents.CHANGE_PAGE);
|
|
1805
|
|
1806 /**
|
|
1807 * Fired before the Calendar is rendered
|
|
1808 * @event beforeRenderEvent
|
|
1809 */
|
|
1810 cal.beforeRenderEvent = new CE(defEvents.BEFORE_RENDER);
|
|
1811
|
|
1812 /**
|
|
1813 * Fired when the Calendar is rendered
|
|
1814 * @event renderEvent
|
|
1815 */
|
|
1816 cal.renderEvent = new CE(defEvents.RENDER);
|
|
1817
|
|
1818 /**
|
|
1819 * Fired just before the Calendar is to be destroyed
|
|
1820 * @event beforeDestroyEvent
|
|
1821 */
|
|
1822 cal.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
|
|
1823
|
|
1824 /**
|
|
1825 * Fired after the Calendar is destroyed. This event should be used
|
|
1826 * for notification only. When this event is fired, important Calendar instance
|
|
1827 * properties, dom references and event listeners have already been
|
|
1828 * removed/dereferenced, and hence the Calendar instance is not in a usable
|
|
1829 * state.
|
|
1830 *
|
|
1831 * @event destroyEvent
|
|
1832 */
|
|
1833 cal.destroyEvent = new CE(defEvents.DESTROY);
|
|
1834
|
|
1835 /**
|
|
1836 * Fired when the Calendar is reset
|
|
1837 * @event resetEvent
|
|
1838 */
|
|
1839 cal.resetEvent = new CE(defEvents.RESET);
|
|
1840
|
|
1841 /**
|
|
1842 * Fired when the Calendar is cleared
|
|
1843 * @event clearEvent
|
|
1844 */
|
|
1845 cal.clearEvent = new CE(defEvents.CLEAR);
|
|
1846
|
|
1847 /**
|
|
1848 * Fired just before the Calendar is to be shown
|
|
1849 * @event beforeShowEvent
|
|
1850 */
|
|
1851 cal.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
|
|
1852
|
|
1853 /**
|
|
1854 * Fired after the Calendar is shown
|
|
1855 * @event showEvent
|
|
1856 */
|
|
1857 cal.showEvent = new CE(defEvents.SHOW);
|
|
1858
|
|
1859 /**
|
|
1860 * Fired just before the Calendar is to be hidden
|
|
1861 * @event beforeHideEvent
|
|
1862 */
|
|
1863 cal.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
|
|
1864
|
|
1865 /**
|
|
1866 * Fired after the Calendar is hidden
|
|
1867 * @event hideEvent
|
|
1868 */
|
|
1869 cal.hideEvent = new CE(defEvents.HIDE);
|
|
1870
|
|
1871 /**
|
|
1872 * Fired just before the CalendarNavigator is to be shown
|
|
1873 * @event beforeShowNavEvent
|
|
1874 */
|
|
1875 cal.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
|
|
1876
|
|
1877 /**
|
|
1878 * Fired after the CalendarNavigator is shown
|
|
1879 * @event showNavEvent
|
|
1880 */
|
|
1881 cal.showNavEvent = new CE(defEvents.SHOW_NAV);
|
|
1882
|
|
1883 /**
|
|
1884 * Fired just before the CalendarNavigator is to be hidden
|
|
1885 * @event beforeHideNavEvent
|
|
1886 */
|
|
1887 cal.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
|
|
1888
|
|
1889 /**
|
|
1890 * Fired after the CalendarNavigator is hidden
|
|
1891 * @event hideNavEvent
|
|
1892 */
|
|
1893 cal.hideNavEvent = new CE(defEvents.HIDE_NAV);
|
|
1894
|
|
1895 /**
|
|
1896 * Fired just before the CalendarNavigator is to be rendered
|
|
1897 * @event beforeRenderNavEvent
|
|
1898 */
|
|
1899 cal.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
|
|
1900
|
|
1901 /**
|
|
1902 * Fired after the CalendarNavigator is rendered
|
|
1903 * @event renderNavEvent
|
|
1904 */
|
|
1905 cal.renderNavEvent = new CE(defEvents.RENDER_NAV);
|
|
1906
|
|
1907 cal.beforeSelectEvent.subscribe(cal.onBeforeSelect, this, true);
|
|
1908 cal.selectEvent.subscribe(cal.onSelect, this, true);
|
|
1909 cal.beforeDeselectEvent.subscribe(cal.onBeforeDeselect, this, true);
|
|
1910 cal.deselectEvent.subscribe(cal.onDeselect, this, true);
|
|
1911 cal.changePageEvent.subscribe(cal.onChangePage, this, true);
|
|
1912 cal.renderEvent.subscribe(cal.onRender, this, true);
|
|
1913 cal.resetEvent.subscribe(cal.onReset, this, true);
|
|
1914 cal.clearEvent.subscribe(cal.onClear, this, true);
|
|
1915 },
|
|
1916
|
|
1917 /**
|
|
1918 * The default event handler for clicks on the "Previous Month" navigation UI
|
|
1919 *
|
|
1920 * @method doPreviousMonthNav
|
|
1921 * @param {DOMEvent} e The DOM event
|
|
1922 * @param {Calendar} cal A reference to the calendar
|
|
1923 */
|
|
1924 doPreviousMonthNav : function(e, cal) {
|
|
1925 Event.preventDefault(e);
|
|
1926 // previousMonth invoked in a timeout, to allow
|
|
1927 // event to bubble up, with correct target. Calling
|
|
1928 // previousMonth, will call render which will remove
|
|
1929 // HTML which generated the event, resulting in an
|
|
1930 // invalid event target in certain browsers.
|
|
1931 setTimeout(function() {
|
|
1932 cal.previousMonth();
|
|
1933 var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_LEFT, "a", cal.oDomContainer);
|
|
1934 if (navs && navs[0]) {
|
|
1935 try {
|
|
1936 navs[0].focus();
|
|
1937 } catch (ex) {
|
|
1938 // ignore
|
|
1939 }
|
|
1940 }
|
|
1941 }, 0);
|
|
1942 },
|
|
1943
|
|
1944 /**
|
|
1945 * The default event handler for clicks on the "Next Month" navigation UI
|
|
1946 *
|
|
1947 * @method doNextMonthNav
|
|
1948 * @param {DOMEvent} e The DOM event
|
|
1949 * @param {Calendar} cal A reference to the calendar
|
|
1950 */
|
|
1951 doNextMonthNav : function(e, cal) {
|
|
1952 Event.preventDefault(e);
|
|
1953 setTimeout(function() {
|
|
1954 cal.nextMonth();
|
|
1955 var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_RIGHT, "a", cal.oDomContainer);
|
|
1956 if (navs && navs[0]) {
|
|
1957 try {
|
|
1958 navs[0].focus();
|
|
1959 } catch (ex) {
|
|
1960 // ignore
|
|
1961 }
|
|
1962 }
|
|
1963 }, 0);
|
|
1964 },
|
|
1965
|
|
1966 /**
|
|
1967 * The default event handler for date cell selection. Currently attached to
|
|
1968 * the Calendar's bounding box, referenced by it's <a href="#property_oDomContainer">oDomContainer</a> property.
|
|
1969 *
|
|
1970 * @method doSelectCell
|
|
1971 * @param {DOMEvent} e The DOM event
|
|
1972 * @param {Calendar} cal A reference to the calendar
|
|
1973 */
|
|
1974 doSelectCell : function(e, cal) {
|
|
1975 var cell, d, date, index;
|
|
1976
|
|
1977 var target = Event.getTarget(e),
|
|
1978 tagName = target.tagName.toLowerCase(),
|
|
1979 defSelector = false;
|
|
1980
|
|
1981 while (tagName != "td" && !Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
|
|
1982
|
|
1983 if (!defSelector && tagName == "a" && Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
|
|
1984 defSelector = true;
|
|
1985 }
|
|
1986
|
|
1987 target = target.parentNode;
|
|
1988 tagName = target.tagName.toLowerCase();
|
|
1989
|
|
1990 if (target == this.oDomContainer || tagName == "html") {
|
|
1991 return;
|
|
1992 }
|
|
1993 }
|
|
1994
|
|
1995 if (defSelector) {
|
|
1996 // Stop link href navigation for default renderer
|
|
1997 Event.preventDefault(e);
|
|
1998 }
|
|
1999
|
|
2000 cell = target;
|
|
2001
|
|
2002 if (Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
|
|
2003 index = cal.getIndexFromId(cell.id);
|
|
2004 if (index > -1) {
|
|
2005 d = cal.cellDates[index];
|
|
2006 if (d) {
|
|
2007 date = DateMath.getDate(d[0],d[1]-1,d[2]);
|
|
2008
|
|
2009 var link;
|
|
2010
|
|
2011 cal.logger.log("Selecting cell " + index + " via click", "info");
|
|
2012 if (cal.Options.MULTI_SELECT) {
|
|
2013 link = cell.getElementsByTagName("a")[0];
|
|
2014 if (link) {
|
|
2015 link.blur();
|
|
2016 }
|
|
2017
|
|
2018 var cellDate = cal.cellDates[index];
|
|
2019 var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
|
|
2020
|
|
2021 if (cellDateIndex > -1) {
|
|
2022 cal.deselectCell(index);
|
|
2023 } else {
|
|
2024 cal.selectCell(index);
|
|
2025 }
|
|
2026
|
|
2027 } else {
|
|
2028 link = cell.getElementsByTagName("a")[0];
|
|
2029 if (link) {
|
|
2030 link.blur();
|
|
2031 }
|
|
2032 cal.selectCell(index);
|
|
2033 }
|
|
2034 }
|
|
2035 }
|
|
2036 }
|
|
2037 },
|
|
2038
|
|
2039 /**
|
|
2040 * The event that is executed when the user hovers over a cell
|
|
2041 * @method doCellMouseOver
|
|
2042 * @param {DOMEvent} e The event
|
|
2043 * @param {Calendar} cal A reference to the calendar passed by the Event utility
|
|
2044 */
|
|
2045 doCellMouseOver : function(e, cal) {
|
|
2046 var target;
|
|
2047 if (e) {
|
|
2048 target = Event.getTarget(e);
|
|
2049 } else {
|
|
2050 target = this;
|
|
2051 }
|
|
2052
|
|
2053 while (target.tagName && target.tagName.toLowerCase() != "td") {
|
|
2054 target = target.parentNode;
|
|
2055 if (!target.tagName || target.tagName.toLowerCase() == "html") {
|
|
2056 return;
|
|
2057 }
|
|
2058 }
|
|
2059
|
|
2060 if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
|
|
2061 Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
|
|
2062 }
|
|
2063 },
|
|
2064
|
|
2065 /**
|
|
2066 * The event that is executed when the user moves the mouse out of a cell
|
|
2067 * @method doCellMouseOut
|
|
2068 * @param {DOMEvent} e The event
|
|
2069 * @param {Calendar} cal A reference to the calendar passed by the Event utility
|
|
2070 */
|
|
2071 doCellMouseOut : function(e, cal) {
|
|
2072 var target;
|
|
2073 if (e) {
|
|
2074 target = Event.getTarget(e);
|
|
2075 } else {
|
|
2076 target = this;
|
|
2077 }
|
|
2078
|
|
2079 while (target.tagName && target.tagName.toLowerCase() != "td") {
|
|
2080 target = target.parentNode;
|
|
2081 if (!target.tagName || target.tagName.toLowerCase() == "html") {
|
|
2082 return;
|
|
2083 }
|
|
2084 }
|
|
2085
|
|
2086 if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
|
|
2087 Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
|
|
2088 }
|
|
2089 },
|
|
2090
|
|
2091 setupConfig : function() {
|
|
2092
|
|
2093 var cfg = this.cfg;
|
|
2094
|
|
2095 /**
|
|
2096 * The date to use to represent "Today".
|
|
2097 *
|
|
2098 * @config today
|
|
2099 * @type Date
|
|
2100 * @default The client side date (new Date()) when the Calendar is instantiated.
|
|
2101 */
|
|
2102 cfg.addProperty(DEF_CFG.TODAY.key, { value: new Date(DEF_CFG.TODAY.value.getTime()), supercedes:DEF_CFG.TODAY.supercedes, handler:this.configToday, suppressEvent:true } );
|
|
2103
|
|
2104 /**
|
|
2105 * The month/year representing the current visible Calendar date (mm/yyyy)
|
|
2106 * @config pagedate
|
|
2107 * @type String | Date
|
|
2108 * @default Today's date
|
|
2109 */
|
|
2110 cfg.addProperty(DEF_CFG.PAGEDATE.key, { value: DEF_CFG.PAGEDATE.value || new Date(DEF_CFG.TODAY.value.getTime()), handler:this.configPageDate } );
|
|
2111
|
|
2112 /**
|
|
2113 * The date or range of dates representing the current Calendar selection
|
|
2114 * @config selected
|
|
2115 * @type String
|
|
2116 * @default []
|
|
2117 */
|
|
2118 cfg.addProperty(DEF_CFG.SELECTED.key, { value:DEF_CFG.SELECTED.value.concat(), handler:this.configSelected } );
|
|
2119
|
|
2120 /**
|
|
2121 * The title to display above the Calendar's month header
|
|
2122 * @config title
|
|
2123 * @type String
|
|
2124 * @default ""
|
|
2125 */
|
|
2126 cfg.addProperty(DEF_CFG.TITLE.key, { value:DEF_CFG.TITLE.value, handler:this.configTitle } );
|
|
2127
|
|
2128 /**
|
|
2129 * Whether or not a close button should be displayed for this Calendar
|
|
2130 * @config close
|
|
2131 * @type Boolean
|
|
2132 * @default false
|
|
2133 */
|
|
2134 cfg.addProperty(DEF_CFG.CLOSE.key, { value:DEF_CFG.CLOSE.value, handler:this.configClose } );
|
|
2135
|
|
2136 /**
|
|
2137 * 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.
|
|
2138 * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
|
|
2139 * enabled if required.
|
|
2140 *
|
|
2141 * @config iframe
|
|
2142 * @type Boolean
|
|
2143 * @default true for IE6 and below, false for all other browsers
|
|
2144 */
|
|
2145 cfg.addProperty(DEF_CFG.IFRAME.key, { value:DEF_CFG.IFRAME.value, handler:this.configIframe, validator:cfg.checkBoolean } );
|
|
2146
|
|
2147 /**
|
|
2148 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
|
|
2149 * @config mindate
|
|
2150 * @type String | Date
|
|
2151 * @default null
|
|
2152 */
|
|
2153 cfg.addProperty(DEF_CFG.MINDATE.key, { value:DEF_CFG.MINDATE.value, handler:this.configMinDate } );
|
|
2154
|
|
2155 /**
|
|
2156 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
|
|
2157 * @config maxdate
|
|
2158 * @type String | Date
|
|
2159 * @default null
|
|
2160 */
|
|
2161 cfg.addProperty(DEF_CFG.MAXDATE.key, { value:DEF_CFG.MAXDATE.value, handler:this.configMaxDate } );
|
|
2162
|
|
2163 // Options properties
|
|
2164
|
|
2165 /**
|
|
2166 * True if the Calendar should allow multiple selections. False by default.
|
|
2167 * @config MULTI_SELECT
|
|
2168 * @type Boolean
|
|
2169 * @default false
|
|
2170 */
|
|
2171 cfg.addProperty(DEF_CFG.MULTI_SELECT.key, { value:DEF_CFG.MULTI_SELECT.value, handler:this.configOptions, validator:cfg.checkBoolean } );
|
|
2172
|
|
2173 /**
|
|
2174 * The weekday the week begins on. Default is 0 (Sunday = 0, Monday = 1 ... Saturday = 6).
|
|
2175 * @config START_WEEKDAY
|
|
2176 * @type number
|
|
2177 * @default 0
|
|
2178 */
|
|
2179 cfg.addProperty(DEF_CFG.START_WEEKDAY.key, { value:DEF_CFG.START_WEEKDAY.value, handler:this.configOptions, validator:cfg.checkNumber } );
|
|
2180
|
|
2181 /**
|
|
2182 * True if the Calendar should show weekday labels. True by default.
|
|
2183 * @config SHOW_WEEKDAYS
|
|
2184 * @type Boolean
|
|
2185 * @default true
|
|
2186 */
|
|
2187 cfg.addProperty(DEF_CFG.SHOW_WEEKDAYS.key, { value:DEF_CFG.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:cfg.checkBoolean } );
|
|
2188
|
|
2189 /**
|
|
2190 * True if the Calendar should show week row headers. False by default.
|
|
2191 * @config SHOW_WEEK_HEADER
|
|
2192 * @type Boolean
|
|
2193 * @default false
|
|
2194 */
|
|
2195 cfg.addProperty(DEF_CFG.SHOW_WEEK_HEADER.key, { value:DEF_CFG.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
|
|
2196
|
|
2197 /**
|
|
2198 * True if the Calendar should show week row footers. False by default.
|
|
2199 * @config SHOW_WEEK_FOOTER
|
|
2200 * @type Boolean
|
|
2201 * @default false
|
|
2202 */
|
|
2203 cfg.addProperty(DEF_CFG.SHOW_WEEK_FOOTER.key,{ value:DEF_CFG.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
|
|
2204
|
|
2205 /**
|
|
2206 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
|
|
2207 * @config HIDE_BLANK_WEEKS
|
|
2208 * @type Boolean
|
|
2209 * @default false
|
|
2210 */
|
|
2211 cfg.addProperty(DEF_CFG.HIDE_BLANK_WEEKS.key, { value:DEF_CFG.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator:cfg.checkBoolean } );
|
|
2212
|
|
2213 /**
|
|
2214 * The image that should be used for the left navigation arrow.
|
|
2215 * @config NAV_ARROW_LEFT
|
|
2216 * @type String
|
|
2217 * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
|
|
2218 * @default null
|
|
2219 */
|
|
2220 cfg.addProperty(DEF_CFG.NAV_ARROW_LEFT.key, { value:DEF_CFG.NAV_ARROW_LEFT.value, handler:this.configOptions } );
|
|
2221
|
|
2222 /**
|
|
2223 * The image that should be used for the right navigation arrow.
|
|
2224 * @config NAV_ARROW_RIGHT
|
|
2225 * @type String
|
|
2226 * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
|
|
2227 * @default null
|
|
2228 */
|
|
2229 cfg.addProperty(DEF_CFG.NAV_ARROW_RIGHT.key, { value:DEF_CFG.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
|
|
2230
|
|
2231 // Locale properties
|
|
2232
|
|
2233 /**
|
|
2234 * The short month labels for the current locale.
|
|
2235 * @config MONTHS_SHORT
|
|
2236 * @type String[]
|
|
2237 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
|
2238 */
|
|
2239 cfg.addProperty(DEF_CFG.MONTHS_SHORT.key, { value:DEF_CFG.MONTHS_SHORT.value, handler:this.configLocale } );
|
|
2240
|
|
2241 /**
|
|
2242 * The long month labels for the current locale.
|
|
2243 * @config MONTHS_LONG
|
|
2244 * @type String[]
|
|
2245 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
|
2246 */
|
|
2247 cfg.addProperty(DEF_CFG.MONTHS_LONG.key, { value:DEF_CFG.MONTHS_LONG.value, handler:this.configLocale } );
|
|
2248
|
|
2249 /**
|
|
2250 * The 1-character weekday labels for the current locale.
|
|
2251 * @config WEEKDAYS_1CHAR
|
|
2252 * @type String[]
|
|
2253 * @default ["S", "M", "T", "W", "T", "F", "S"]
|
|
2254 */
|
|
2255 cfg.addProperty(DEF_CFG.WEEKDAYS_1CHAR.key, { value:DEF_CFG.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
|
|
2256
|
|
2257 /**
|
|
2258 * The short weekday labels for the current locale.
|
|
2259 * @config WEEKDAYS_SHORT
|
|
2260 * @type String[]
|
|
2261 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
|
|
2262 */
|
|
2263 cfg.addProperty(DEF_CFG.WEEKDAYS_SHORT.key, { value:DEF_CFG.WEEKDAYS_SHORT.value, handler:this.configLocale } );
|
|
2264
|
|
2265 /**
|
|
2266 * The medium weekday labels for the current locale.
|
|
2267 * @config WEEKDAYS_MEDIUM
|
|
2268 * @type String[]
|
|
2269 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
|
2270 */
|
|
2271 cfg.addProperty(DEF_CFG.WEEKDAYS_MEDIUM.key, { value:DEF_CFG.WEEKDAYS_MEDIUM.value, handler:this.configLocale } );
|
|
2272
|
|
2273 /**
|
|
2274 * The long weekday labels for the current locale.
|
|
2275 * @config WEEKDAYS_LONG
|
|
2276 * @type String[]
|
|
2277 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
|
2278 */
|
|
2279 cfg.addProperty(DEF_CFG.WEEKDAYS_LONG.key, { value:DEF_CFG.WEEKDAYS_LONG.value, handler:this.configLocale } );
|
|
2280
|
|
2281 /**
|
|
2282 * Refreshes the locale values used to build the Calendar.
|
|
2283 * @method refreshLocale
|
|
2284 * @private
|
|
2285 */
|
|
2286 var refreshLocale = function() {
|
|
2287 cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
|
|
2288 cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
|
|
2289 };
|
|
2290
|
|
2291 cfg.subscribeToConfigEvent(DEF_CFG.START_WEEKDAY.key, refreshLocale, this, true);
|
|
2292 cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_SHORT.key, refreshLocale, this, true);
|
|
2293 cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_LONG.key, refreshLocale, this, true);
|
|
2294 cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
|
|
2295 cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_SHORT.key, refreshLocale, this, true);
|
|
2296 cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
|
|
2297 cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_LONG.key, refreshLocale, this, true);
|
|
2298
|
|
2299 /**
|
|
2300 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
|
|
2301 * @config LOCALE_MONTHS
|
|
2302 * @type String
|
|
2303 * @default "long"
|
|
2304 */
|
|
2305 cfg.addProperty(DEF_CFG.LOCALE_MONTHS.key, { value:DEF_CFG.LOCALE_MONTHS.value, handler:this.configLocaleValues } );
|
|
2306
|
|
2307 /**
|
|
2308 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
|
|
2309 * @config LOCALE_WEEKDAYS
|
|
2310 * @type String
|
|
2311 * @default "short"
|
|
2312 */
|
|
2313 cfg.addProperty(DEF_CFG.LOCALE_WEEKDAYS.key, { value:DEF_CFG.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
|
|
2314
|
|
2315 /**
|
|
2316 * The positive or negative year offset from the Gregorian calendar year (assuming a January 1st rollover) to
|
|
2317 * be used when displaying and parsing dates. NOTE: All JS Date objects returned by methods, or expected as input by
|
|
2318 * methods will always represent the Gregorian year, in order to maintain date/month/week values.
|
|
2319 *
|
|
2320 * @config YEAR_OFFSET
|
|
2321 * @type Number
|
|
2322 * @default 0
|
|
2323 */
|
|
2324 cfg.addProperty(DEF_CFG.YEAR_OFFSET.key, { value:DEF_CFG.YEAR_OFFSET.value, supercedes:DEF_CFG.YEAR_OFFSET.supercedes, handler:this.configLocale } );
|
|
2325
|
|
2326 /**
|
|
2327 * The value used to delimit individual dates in a date string passed to various Calendar functions.
|
|
2328 * @config DATE_DELIMITER
|
|
2329 * @type String
|
|
2330 * @default ","
|
|
2331 */
|
|
2332 cfg.addProperty(DEF_CFG.DATE_DELIMITER.key, { value:DEF_CFG.DATE_DELIMITER.value, handler:this.configLocale } );
|
|
2333
|
|
2334 /**
|
|
2335 * The value used to delimit date fields in a date string passed to various Calendar functions.
|
|
2336 * @config DATE_FIELD_DELIMITER
|
|
2337 * @type String
|
|
2338 * @default "/"
|
|
2339 */
|
|
2340 cfg.addProperty(DEF_CFG.DATE_FIELD_DELIMITER.key, { value:DEF_CFG.DATE_FIELD_DELIMITER.value, handler:this.configLocale } );
|
|
2341
|
|
2342 /**
|
|
2343 * The value used to delimit date ranges in a date string passed to various Calendar functions.
|
|
2344 * @config DATE_RANGE_DELIMITER
|
|
2345 * @type String
|
|
2346 * @default "-"
|
|
2347 */
|
|
2348 cfg.addProperty(DEF_CFG.DATE_RANGE_DELIMITER.key, { value:DEF_CFG.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
|
|
2349
|
|
2350 /**
|
|
2351 * The position of the month in a month/year date string
|
|
2352 * @config MY_MONTH_POSITION
|
|
2353 * @type Number
|
|
2354 * @default 1
|
|
2355 */
|
|
2356 cfg.addProperty(DEF_CFG.MY_MONTH_POSITION.key, { value:DEF_CFG.MY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2357
|
|
2358 /**
|
|
2359 * The position of the year in a month/year date string
|
|
2360 * @config MY_YEAR_POSITION
|
|
2361 * @type Number
|
|
2362 * @default 2
|
|
2363 */
|
|
2364 cfg.addProperty(DEF_CFG.MY_YEAR_POSITION.key, { value:DEF_CFG.MY_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2365
|
|
2366 /**
|
|
2367 * The position of the month in a month/day date string
|
|
2368 * @config MD_MONTH_POSITION
|
|
2369 * @type Number
|
|
2370 * @default 1
|
|
2371 */
|
|
2372 cfg.addProperty(DEF_CFG.MD_MONTH_POSITION.key, { value:DEF_CFG.MD_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2373
|
|
2374 /**
|
|
2375 * The position of the day in a month/year date string
|
|
2376 * @config MD_DAY_POSITION
|
|
2377 * @type Number
|
|
2378 * @default 2
|
|
2379 */
|
|
2380 cfg.addProperty(DEF_CFG.MD_DAY_POSITION.key, { value:DEF_CFG.MD_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2381
|
|
2382 /**
|
|
2383 * The position of the month in a month/day/year date string
|
|
2384 * @config MDY_MONTH_POSITION
|
|
2385 * @type Number
|
|
2386 * @default 1
|
|
2387 */
|
|
2388 cfg.addProperty(DEF_CFG.MDY_MONTH_POSITION.key, { value:DEF_CFG.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2389
|
|
2390 /**
|
|
2391 * The position of the day in a month/day/year date string
|
|
2392 * @config MDY_DAY_POSITION
|
|
2393 * @type Number
|
|
2394 * @default 2
|
|
2395 */
|
|
2396 cfg.addProperty(DEF_CFG.MDY_DAY_POSITION.key, { value:DEF_CFG.MDY_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2397
|
|
2398 /**
|
|
2399 * The position of the year in a month/day/year date string
|
|
2400 * @config MDY_YEAR_POSITION
|
|
2401 * @type Number
|
|
2402 * @default 3
|
|
2403 */
|
|
2404 cfg.addProperty(DEF_CFG.MDY_YEAR_POSITION.key, { value:DEF_CFG.MDY_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2405
|
|
2406 /**
|
|
2407 * The position of the month in the month year label string used as the Calendar header
|
|
2408 * @config MY_LABEL_MONTH_POSITION
|
|
2409 * @type Number
|
|
2410 * @default 1
|
|
2411 */
|
|
2412 cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_POSITION.key, { value:DEF_CFG.MY_LABEL_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2413
|
|
2414 /**
|
|
2415 * The position of the year in the month year label string used as the Calendar header
|
|
2416 * @config MY_LABEL_YEAR_POSITION
|
|
2417 * @type Number
|
|
2418 * @default 2
|
|
2419 */
|
|
2420 cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_POSITION.key, { value:DEF_CFG.MY_LABEL_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
|
|
2421
|
|
2422 /**
|
|
2423 * The suffix used after the month when rendering the Calendar header
|
|
2424 * @config MY_LABEL_MONTH_SUFFIX
|
|
2425 * @type String
|
|
2426 * @default " "
|
|
2427 */
|
|
2428 cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_SUFFIX.key, { value:DEF_CFG.MY_LABEL_MONTH_SUFFIX.value, handler:this.configLocale } );
|
|
2429
|
|
2430 /**
|
|
2431 * The suffix used after the year when rendering the Calendar header
|
|
2432 * @config MY_LABEL_YEAR_SUFFIX
|
|
2433 * @type String
|
|
2434 * @default ""
|
|
2435 */
|
|
2436 cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_SUFFIX.key, { value:DEF_CFG.MY_LABEL_YEAR_SUFFIX.value, handler:this.configLocale } );
|
|
2437
|
|
2438 /**
|
|
2439 * Configuration for the Month/Year CalendarNavigator UI which allows the user to jump directly to a
|
|
2440 * specific Month/Year without having to scroll sequentially through months.
|
|
2441 * <p>
|
|
2442 * Setting this property to null (default value) or false, will disable the CalendarNavigator UI.
|
|
2443 * </p>
|
|
2444 * <p>
|
|
2445 * Setting this property to true will enable the CalendarNavigatior UI with the default CalendarNavigator configuration values.
|
|
2446 * </p>
|
|
2447 * <p>
|
|
2448 * This property can also be set to an object literal containing configuration properties for the CalendarNavigator UI.
|
|
2449 * The configuration object expects the the following case-sensitive properties, with the "strings" property being a nested object.
|
|
2450 * Any properties which are not provided will use the default values (defined in the CalendarNavigator class).
|
|
2451 * </p>
|
|
2452 * <dl>
|
|
2453 * <dt>strings</dt>
|
|
2454 * <dd><em>Object</em> : An object with the properties shown below, defining the string labels to use in the Navigator's UI
|
|
2455 * <dl>
|
|
2456 * <dt>month</dt><dd><em>String</em> : The string to use for the month label. Defaults to "Month".</dd>
|
|
2457 * <dt>year</dt><dd><em>String</em> : The string to use for the year label. Defaults to "Year".</dd>
|
|
2458 * <dt>submit</dt><dd><em>String</em> : The string to use for the submit button label. Defaults to "Okay".</dd>
|
|
2459 * <dt>cancel</dt><dd><em>String</em> : The string to use for the cancel button label. Defaults to "Cancel".</dd>
|
|
2460 * <dt>invalidYear</dt><dd><em>String</em> : The string to use for invalid year values. Defaults to "Year needs to be a number".</dd>
|
|
2461 * </dl>
|
|
2462 * </dd>
|
|
2463 * <dt>monthFormat</dt><dd><em>String</em> : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG</dd>
|
|
2464 * <dt>initialFocus</dt><dd><em>String</em> : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"</dd>
|
|
2465 * </dl>
|
|
2466 * <p>E.g.</p>
|
|
2467 * <pre>
|
|
2468 * var navConfig = {
|
|
2469 * strings: {
|
|
2470 * month:"Calendar Month",
|
|
2471 * year:"Calendar Year",
|
|
2472 * submit: "Submit",
|
|
2473 * cancel: "Cancel",
|
|
2474 * invalidYear: "Please enter a valid year"
|
|
2475 * },
|
|
2476 * monthFormat: YAHOO.widget.Calendar.SHORT,
|
|
2477 * initialFocus: "month"
|
|
2478 * }
|
|
2479 * </pre>
|
|
2480 * @config navigator
|
|
2481 * @type {Object|Boolean}
|
|
2482 * @default null
|
|
2483 */
|
|
2484 cfg.addProperty(DEF_CFG.NAV.key, { value:DEF_CFG.NAV.value, handler:this.configNavigator } );
|
|
2485
|
|
2486 /**
|
|
2487 * The map of UI strings which the Calendar UI uses.
|
|
2488 *
|
|
2489 * @config strings
|
|
2490 * @type {Object}
|
|
2491 * @default An object with the properties shown below:
|
|
2492 * <dl>
|
|
2493 * <dt>previousMonth</dt><dd><em>String</em> : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".</dd>
|
|
2494 * <dt>nextMonth</dt><dd><em>String</em> : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".</dd>
|
|
2495 * <dt>close</dt><dd><em>String</em> : The string to use for the close button label. Defaults to "Close".</dd>
|
|
2496 * </dl>
|
|
2497 */
|
|
2498 cfg.addProperty(DEF_CFG.STRINGS.key, {
|
|
2499 value:DEF_CFG.STRINGS.value,
|
|
2500 handler:this.configStrings,
|
|
2501 validator: function(val) {
|
|
2502 return Lang.isObject(val);
|
|
2503 },
|
|
2504 supercedes:DEF_CFG.STRINGS.supercedes
|
|
2505 });
|
|
2506 },
|
|
2507
|
|
2508 /**
|
|
2509 * The default handler for the "strings" property
|
|
2510 * @method configStrings
|
|
2511 */
|
|
2512 configStrings : function(type, args, obj) {
|
|
2513 var val = Lang.merge(DEF_CFG.STRINGS.value, args[0]);
|
|
2514 this.cfg.setProperty(DEF_CFG.STRINGS.key, val, true);
|
|
2515 },
|
|
2516
|
|
2517 /**
|
|
2518 * The default handler for the "pagedate" property
|
|
2519 * @method configPageDate
|
|
2520 */
|
|
2521 configPageDate : function(type, args, obj) {
|
|
2522 this.cfg.setProperty(DEF_CFG.PAGEDATE.key, this._parsePageDate(args[0]), true);
|
|
2523 },
|
|
2524
|
|
2525 /**
|
|
2526 * The default handler for the "mindate" property
|
|
2527 * @method configMinDate
|
|
2528 */
|
|
2529 configMinDate : function(type, args, obj) {
|
|
2530 var val = args[0];
|
|
2531 if (Lang.isString(val)) {
|
|
2532 val = this._parseDate(val);
|
|
2533 this.cfg.setProperty(DEF_CFG.MINDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
|
|
2534 }
|
|
2535 },
|
|
2536
|
|
2537 /**
|
|
2538 * The default handler for the "maxdate" property
|
|
2539 * @method configMaxDate
|
|
2540 */
|
|
2541 configMaxDate : function(type, args, obj) {
|
|
2542 var val = args[0];
|
|
2543 if (Lang.isString(val)) {
|
|
2544 val = this._parseDate(val);
|
|
2545 this.cfg.setProperty(DEF_CFG.MAXDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
|
|
2546 }
|
|
2547 },
|
|
2548
|
|
2549 /**
|
|
2550 * The default handler for the "today" property
|
|
2551 * @method configToday
|
|
2552 */
|
|
2553 configToday : function(type, args, obj) {
|
|
2554 // Only do this for initial set. Changing the today property after the initial
|
|
2555 // set, doesn't affect pagedate
|
|
2556 var val = args[0];
|
|
2557 if (Lang.isString(val)) {
|
|
2558 val = this._parseDate(val);
|
|
2559 }
|
|
2560 var today = DateMath.clearTime(val);
|
|
2561 if (!this.cfg.initialConfig[DEF_CFG.PAGEDATE.key]) {
|
|
2562 this.cfg.setProperty(DEF_CFG.PAGEDATE.key, today);
|
|
2563 }
|
|
2564 this.today = today;
|
|
2565 this.cfg.setProperty(DEF_CFG.TODAY.key, today, true);
|
|
2566 },
|
|
2567
|
|
2568 /**
|
|
2569 * The default handler for the "selected" property
|
|
2570 * @method configSelected
|
|
2571 */
|
|
2572 configSelected : function(type, args, obj) {
|
|
2573 var selected = args[0],
|
|
2574 cfgSelected = DEF_CFG.SELECTED.key;
|
|
2575
|
|
2576 if (selected) {
|
|
2577 if (Lang.isString(selected)) {
|
|
2578 this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
|
|
2579 }
|
|
2580 }
|
|
2581 if (! this._selectedDates) {
|
|
2582 this._selectedDates = this.cfg.getProperty(cfgSelected);
|
|
2583 }
|
|
2584 },
|
|
2585
|
|
2586 /**
|
|
2587 * The default handler for all configuration options properties
|
|
2588 * @method configOptions
|
|
2589 */
|
|
2590 configOptions : function(type, args, obj) {
|
|
2591 this.Options[type.toUpperCase()] = args[0];
|
|
2592 },
|
|
2593
|
|
2594 /**
|
|
2595 * The default handler for all configuration locale properties
|
|
2596 * @method configLocale
|
|
2597 */
|
|
2598 configLocale : function(type, args, obj) {
|
|
2599 this.Locale[type.toUpperCase()] = args[0];
|
|
2600
|
|
2601 this.cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
|
|
2602 this.cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
|
|
2603 },
|
|
2604
|
|
2605 /**
|
|
2606 * The default handler for all configuration locale field length properties
|
|
2607 * @method configLocaleValues
|
|
2608 */
|
|
2609 configLocaleValues : function(type, args, obj) {
|
|
2610
|
|
2611 type = type.toLowerCase();
|
|
2612
|
|
2613 var val = args[0],
|
|
2614 cfg = this.cfg,
|
|
2615 Locale = this.Locale;
|
|
2616
|
|
2617 switch (type) {
|
|
2618 case DEF_CFG.LOCALE_MONTHS.key:
|
|
2619 switch (val) {
|
|
2620 case Calendar.SHORT:
|
|
2621 Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_SHORT.key).concat();
|
|
2622 break;
|
|
2623 case Calendar.LONG:
|
|
2624 Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_LONG.key).concat();
|
|
2625 break;
|
|
2626 }
|
|
2627 break;
|
|
2628 case DEF_CFG.LOCALE_WEEKDAYS.key:
|
|
2629 switch (val) {
|
|
2630 case Calendar.ONE_CHAR:
|
|
2631 Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_1CHAR.key).concat();
|
|
2632 break;
|
|
2633 case Calendar.SHORT:
|
|
2634 Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_SHORT.key).concat();
|
|
2635 break;
|
|
2636 case Calendar.MEDIUM:
|
|
2637 Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_MEDIUM.key).concat();
|
|
2638 break;
|
|
2639 case Calendar.LONG:
|
|
2640 Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_LONG.key).concat();
|
|
2641 break;
|
|
2642 }
|
|
2643
|
|
2644 var START_WEEKDAY = cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
|
|
2645
|
|
2646 if (START_WEEKDAY > 0) {
|
|
2647 for (var w=0; w < START_WEEKDAY; ++w) {
|
|
2648 Locale.LOCALE_WEEKDAYS.push(Locale.LOCALE_WEEKDAYS.shift());
|
|
2649 }
|
|
2650 }
|
|
2651 break;
|
|
2652 }
|
|
2653 },
|
|
2654
|
|
2655 /**
|
|
2656 * The default handler for the "navigator" property
|
|
2657 * @method configNavigator
|
|
2658 */
|
|
2659 configNavigator : function(type, args, obj) {
|
|
2660 var val = args[0];
|
|
2661 if (YAHOO.widget.CalendarNavigator && (val === true || Lang.isObject(val))) {
|
|
2662 if (!this.oNavigator) {
|
|
2663 this.oNavigator = new YAHOO.widget.CalendarNavigator(this);
|
|
2664 // Cleanup DOM Refs/Events before innerHTML is removed.
|
|
2665 this.beforeRenderEvent.subscribe(function () {
|
|
2666 if (!this.pages) {
|
|
2667 this.oNavigator.erase();
|
|
2668 }
|
|
2669 }, this, true);
|
|
2670 }
|
|
2671 } else {
|
|
2672 if (this.oNavigator) {
|
|
2673 this.oNavigator.destroy();
|
|
2674 this.oNavigator = null;
|
|
2675 }
|
|
2676 }
|
|
2677 },
|
|
2678
|
|
2679 /**
|
|
2680 * Defines the style constants for the Calendar
|
|
2681 * @method initStyles
|
|
2682 */
|
|
2683 initStyles : function() {
|
|
2684
|
|
2685 var defStyle = Calendar.STYLES;
|
|
2686
|
|
2687 this.Style = {
|
|
2688 /**
|
|
2689 * @property Style.CSS_ROW_HEADER
|
|
2690 */
|
|
2691 CSS_ROW_HEADER: defStyle.CSS_ROW_HEADER,
|
|
2692 /**
|
|
2693 * @property Style.CSS_ROW_FOOTER
|
|
2694 */
|
|
2695 CSS_ROW_FOOTER: defStyle.CSS_ROW_FOOTER,
|
|
2696 /**
|
|
2697 * @property Style.CSS_CELL
|
|
2698 */
|
|
2699 CSS_CELL : defStyle.CSS_CELL,
|
|
2700 /**
|
|
2701 * @property Style.CSS_CELL_SELECTOR
|
|
2702 */
|
|
2703 CSS_CELL_SELECTOR : defStyle.CSS_CELL_SELECTOR,
|
|
2704 /**
|
|
2705 * @property Style.CSS_CELL_SELECTED
|
|
2706 */
|
|
2707 CSS_CELL_SELECTED : defStyle.CSS_CELL_SELECTED,
|
|
2708 /**
|
|
2709 * @property Style.CSS_CELL_SELECTABLE
|
|
2710 */
|
|
2711 CSS_CELL_SELECTABLE : defStyle.CSS_CELL_SELECTABLE,
|
|
2712 /**
|
|
2713 * @property Style.CSS_CELL_RESTRICTED
|
|
2714 */
|
|
2715 CSS_CELL_RESTRICTED : defStyle.CSS_CELL_RESTRICTED,
|
|
2716 /**
|
|
2717 * @property Style.CSS_CELL_TODAY
|
|
2718 */
|
|
2719 CSS_CELL_TODAY : defStyle.CSS_CELL_TODAY,
|
|
2720 /**
|
|
2721 * @property Style.CSS_CELL_OOM
|
|
2722 */
|
|
2723 CSS_CELL_OOM : defStyle.CSS_CELL_OOM,
|
|
2724 /**
|
|
2725 * @property Style.CSS_CELL_OOB
|
|
2726 */
|
|
2727 CSS_CELL_OOB : defStyle.CSS_CELL_OOB,
|
|
2728 /**
|
|
2729 * @property Style.CSS_HEADER
|
|
2730 */
|
|
2731 CSS_HEADER : defStyle.CSS_HEADER,
|
|
2732 /**
|
|
2733 * @property Style.CSS_HEADER_TEXT
|
|
2734 */
|
|
2735 CSS_HEADER_TEXT : defStyle.CSS_HEADER_TEXT,
|
|
2736 /**
|
|
2737 * @property Style.CSS_BODY
|
|
2738 */
|
|
2739 CSS_BODY : defStyle.CSS_BODY,
|
|
2740 /**
|
|
2741 * @property Style.CSS_WEEKDAY_CELL
|
|
2742 */
|
|
2743 CSS_WEEKDAY_CELL : defStyle.CSS_WEEKDAY_CELL,
|
|
2744 /**
|
|
2745 * @property Style.CSS_WEEKDAY_ROW
|
|
2746 */
|
|
2747 CSS_WEEKDAY_ROW : defStyle.CSS_WEEKDAY_ROW,
|
|
2748 /**
|
|
2749 * @property Style.CSS_FOOTER
|
|
2750 */
|
|
2751 CSS_FOOTER : defStyle.CSS_FOOTER,
|
|
2752 /**
|
|
2753 * @property Style.CSS_CALENDAR
|
|
2754 */
|
|
2755 CSS_CALENDAR : defStyle.CSS_CALENDAR,
|
|
2756 /**
|
|
2757 * @property Style.CSS_SINGLE
|
|
2758 */
|
|
2759 CSS_SINGLE : defStyle.CSS_SINGLE,
|
|
2760 /**
|
|
2761 * @property Style.CSS_CONTAINER
|
|
2762 */
|
|
2763 CSS_CONTAINER : defStyle.CSS_CONTAINER,
|
|
2764 /**
|
|
2765 * @property Style.CSS_NAV_LEFT
|
|
2766 */
|
|
2767 CSS_NAV_LEFT : defStyle.CSS_NAV_LEFT,
|
|
2768 /**
|
|
2769 * @property Style.CSS_NAV_RIGHT
|
|
2770 */
|
|
2771 CSS_NAV_RIGHT : defStyle.CSS_NAV_RIGHT,
|
|
2772 /**
|
|
2773 * @property Style.CSS_NAV
|
|
2774 */
|
|
2775 CSS_NAV : defStyle.CSS_NAV,
|
|
2776 /**
|
|
2777 * @property Style.CSS_CLOSE
|
|
2778 */
|
|
2779 CSS_CLOSE : defStyle.CSS_CLOSE,
|
|
2780 /**
|
|
2781 * @property Style.CSS_CELL_TOP
|
|
2782 */
|
|
2783 CSS_CELL_TOP : defStyle.CSS_CELL_TOP,
|
|
2784 /**
|
|
2785 * @property Style.CSS_CELL_LEFT
|
|
2786 */
|
|
2787 CSS_CELL_LEFT : defStyle.CSS_CELL_LEFT,
|
|
2788 /**
|
|
2789 * @property Style.CSS_CELL_RIGHT
|
|
2790 */
|
|
2791 CSS_CELL_RIGHT : defStyle.CSS_CELL_RIGHT,
|
|
2792 /**
|
|
2793 * @property Style.CSS_CELL_BOTTOM
|
|
2794 */
|
|
2795 CSS_CELL_BOTTOM : defStyle.CSS_CELL_BOTTOM,
|
|
2796 /**
|
|
2797 * @property Style.CSS_CELL_HOVER
|
|
2798 */
|
|
2799 CSS_CELL_HOVER : defStyle.CSS_CELL_HOVER,
|
|
2800 /**
|
|
2801 * @property Style.CSS_CELL_HIGHLIGHT1
|
|
2802 */
|
|
2803 CSS_CELL_HIGHLIGHT1 : defStyle.CSS_CELL_HIGHLIGHT1,
|
|
2804 /**
|
|
2805 * @property Style.CSS_CELL_HIGHLIGHT2
|
|
2806 */
|
|
2807 CSS_CELL_HIGHLIGHT2 : defStyle.CSS_CELL_HIGHLIGHT2,
|
|
2808 /**
|
|
2809 * @property Style.CSS_CELL_HIGHLIGHT3
|
|
2810 */
|
|
2811 CSS_CELL_HIGHLIGHT3 : defStyle.CSS_CELL_HIGHLIGHT3,
|
|
2812 /**
|
|
2813 * @property Style.CSS_CELL_HIGHLIGHT4
|
|
2814 */
|
|
2815 CSS_CELL_HIGHLIGHT4 : defStyle.CSS_CELL_HIGHLIGHT4,
|
|
2816 /**
|
|
2817 * @property Style.CSS_WITH_TITLE
|
|
2818 */
|
|
2819 CSS_WITH_TITLE : defStyle.CSS_WITH_TITLE,
|
|
2820 /**
|
|
2821 * @property Style.CSS_FIXED_SIZE
|
|
2822 */
|
|
2823 CSS_FIXED_SIZE : defStyle.CSS_FIXED_SIZE,
|
|
2824 /**
|
|
2825 * @property Style.CSS_LINK_CLOSE
|
|
2826 */
|
|
2827 CSS_LINK_CLOSE : defStyle.CSS_LINK_CLOSE
|
|
2828 };
|
|
2829 },
|
|
2830
|
|
2831 /**
|
|
2832 * Builds the date label that will be displayed in the calendar header or
|
|
2833 * footer, depending on configuration.
|
|
2834 * @method buildMonthLabel
|
|
2835 * @return {String} The formatted calendar month label
|
|
2836 */
|
|
2837 buildMonthLabel : function() {
|
|
2838 return this._buildMonthLabel(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
|
|
2839 },
|
|
2840
|
|
2841 /**
|
|
2842 * Helper method, to format a Month Year string, given a JavaScript Date, based on the
|
|
2843 * Calendar localization settings
|
|
2844 *
|
|
2845 * @method _buildMonthLabel
|
|
2846 * @private
|
|
2847 * @param {Date} date
|
|
2848 * @return {String} Formated month, year string
|
|
2849 */
|
|
2850 _buildMonthLabel : function(date) {
|
|
2851 var monthLabel = this.Locale.LOCALE_MONTHS[date.getMonth()] + this.Locale.MY_LABEL_MONTH_SUFFIX,
|
|
2852 yearLabel = (date.getFullYear() + this.Locale.YEAR_OFFSET) + this.Locale.MY_LABEL_YEAR_SUFFIX;
|
|
2853
|
|
2854 if (this.Locale.MY_LABEL_MONTH_POSITION == 2 || this.Locale.MY_LABEL_YEAR_POSITION == 1) {
|
|
2855 return yearLabel + monthLabel;
|
|
2856 } else {
|
|
2857 return monthLabel + yearLabel;
|
|
2858 }
|
|
2859 },
|
|
2860
|
|
2861 /**
|
|
2862 * Builds the date digit that will be displayed in calendar cells
|
|
2863 * @method buildDayLabel
|
|
2864 * @param {Date} workingDate The current working date
|
|
2865 * @return {String} The formatted day label
|
|
2866 */
|
|
2867 buildDayLabel : function(workingDate) {
|
|
2868 return workingDate.getDate();
|
|
2869 },
|
|
2870
|
|
2871 /**
|
|
2872 * Creates the title bar element and adds it to Calendar container DIV
|
|
2873 *
|
|
2874 * @method createTitleBar
|
|
2875 * @param {String} strTitle The title to display in the title bar
|
|
2876 * @return The title bar element
|
|
2877 */
|
|
2878 createTitleBar : function(strTitle) {
|
|
2879 var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
|
|
2880 tDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
|
|
2881 tDiv.innerHTML = strTitle;
|
|
2882 this.oDomContainer.insertBefore(tDiv, this.oDomContainer.firstChild);
|
|
2883
|
|
2884 Dom.addClass(this.oDomContainer, this.Style.CSS_WITH_TITLE);
|
|
2885
|
|
2886 return tDiv;
|
|
2887 },
|
|
2888
|
|
2889 /**
|
|
2890 * Removes the title bar element from the DOM
|
|
2891 *
|
|
2892 * @method removeTitleBar
|
|
2893 */
|
|
2894 removeTitleBar : function() {
|
|
2895 var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
|
|
2896 if (tDiv) {
|
|
2897 Event.purgeElement(tDiv);
|
|
2898 this.oDomContainer.removeChild(tDiv);
|
|
2899 }
|
|
2900 Dom.removeClass(this.oDomContainer, this.Style.CSS_WITH_TITLE);
|
|
2901 },
|
|
2902
|
|
2903 /**
|
|
2904 * Creates the close button HTML element and adds it to Calendar container DIV
|
|
2905 *
|
|
2906 * @method createCloseButton
|
|
2907 * @return The close HTML element created
|
|
2908 */
|
|
2909 createCloseButton : function() {
|
|
2910 var cssClose = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE,
|
|
2911 cssLinkClose = this.Style.CSS_LINK_CLOSE,
|
|
2912 DEPR_CLOSE_PATH = "us/my/bn/x_d.gif",
|
|
2913
|
|
2914 lnk = Dom.getElementsByClassName(cssLinkClose, "a", this.oDomContainer)[0],
|
|
2915 strings = this.cfg.getProperty(DEF_CFG.STRINGS.key),
|
|
2916 closeStr = (strings && strings.close) ? strings.close : "";
|
|
2917
|
|
2918 if (!lnk) {
|
|
2919 lnk = document.createElement("a");
|
|
2920 Event.addListener(lnk, "click", function(e, cal) {
|
|
2921 cal.hide();
|
|
2922 Event.preventDefault(e);
|
|
2923 }, this);
|
|
2924 }
|
|
2925
|
|
2926 lnk.href = "#";
|
|
2927 lnk.className = cssLinkClose;
|
|
2928
|
|
2929 if (Calendar.IMG_ROOT !== null) {
|
|
2930 var img = Dom.getElementsByClassName(cssClose, "img", lnk)[0] || document.createElement("img");
|
|
2931 img.src = Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
|
|
2932 img.className = cssClose;
|
|
2933 lnk.appendChild(img);
|
|
2934 } else {
|
|
2935 lnk.innerHTML = '<span class="' + cssClose + ' ' + this.Style.CSS_CLOSE + '">' + closeStr + '</span>';
|
|
2936 }
|
|
2937 this.oDomContainer.appendChild(lnk);
|
|
2938
|
|
2939 return lnk;
|
|
2940 },
|
|
2941
|
|
2942 /**
|
|
2943 * Removes the close button HTML element from the DOM
|
|
2944 *
|
|
2945 * @method removeCloseButton
|
|
2946 */
|
|
2947 removeCloseButton : function() {
|
|
2948 var btn = Dom.getElementsByClassName(this.Style.CSS_LINK_CLOSE, "a", this.oDomContainer)[0] || null;
|
|
2949 if (btn) {
|
|
2950 Event.purgeElement(btn);
|
|
2951 this.oDomContainer.removeChild(btn);
|
|
2952 }
|
|
2953 },
|
|
2954
|
|
2955 /**
|
|
2956 * Renders the calendar header.
|
|
2957 * @method renderHeader
|
|
2958 * @param {Array} html The current working HTML array
|
|
2959 * @return {Array} The current working HTML array
|
|
2960 */
|
|
2961 renderHeader : function(html) {
|
|
2962
|
|
2963 this.logger.log("Rendering header", "render");
|
|
2964
|
|
2965 var colSpan = 7,
|
|
2966 DEPR_NAV_LEFT = "us/tr/callt.gif",
|
|
2967 DEPR_NAV_RIGHT = "us/tr/calrt.gif",
|
|
2968 cfg = this.cfg,
|
|
2969 pageDate = cfg.getProperty(DEF_CFG.PAGEDATE.key),
|
|
2970 strings= cfg.getProperty(DEF_CFG.STRINGS.key),
|
|
2971 prevStr = (strings && strings.previousMonth) ? strings.previousMonth : "",
|
|
2972 nextStr = (strings && strings.nextMonth) ? strings.nextMonth : "",
|
|
2973 monthLabel;
|
|
2974
|
|
2975 if (cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key)) {
|
|
2976 colSpan += 1;
|
|
2977 }
|
|
2978
|
|
2979 if (cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key)) {
|
|
2980 colSpan += 1;
|
|
2981 }
|
|
2982
|
|
2983 html[html.length] = "<thead>";
|
|
2984 html[html.length] = "<tr>";
|
|
2985 html[html.length] = '<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
|
|
2986 html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
|
|
2987
|
|
2988 var renderLeft, renderRight = false;
|
|
2989
|
|
2990 if (this.parent) {
|
|
2991 if (this.index === 0) {
|
|
2992 renderLeft = true;
|
|
2993 }
|
|
2994 if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
|
|
2995 renderRight = true;
|
|
2996 }
|
|
2997 } else {
|
|
2998 renderLeft = true;
|
|
2999 renderRight = true;
|
|
3000 }
|
|
3001
|
|
3002 if (renderLeft) {
|
|
3003 monthLabel = this._buildMonthLabel(DateMath.subtract(pageDate, DateMath.MONTH, 1));
|
|
3004
|
|
3005 var leftArrow = cfg.getProperty(DEF_CFG.NAV_ARROW_LEFT.key);
|
|
3006 // Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
|
|
3007 if (leftArrow === null && Calendar.IMG_ROOT !== null) {
|
|
3008 leftArrow = Calendar.IMG_ROOT + DEPR_NAV_LEFT;
|
|
3009 }
|
|
3010 var leftStyle = (leftArrow === null) ? "" : ' style="background-image:url(' + leftArrow + ')"';
|
|
3011 html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '"' + leftStyle + ' href="#">' + prevStr + ' (' + monthLabel + ')' + '</a>';
|
|
3012 }
|
|
3013
|
|
3014 var lbl = this.buildMonthLabel();
|
|
3015 var cal = this.parent || this;
|
|
3016 if (cal.cfg.getProperty("navigator")) {
|
|
3017 lbl = "<a class=\"" + this.Style.CSS_NAV + "\" href=\"#\">" + lbl + "</a>";
|
|
3018 }
|
|
3019 html[html.length] = lbl;
|
|
3020
|
|
3021 if (renderRight) {
|
|
3022 monthLabel = this._buildMonthLabel(DateMath.add(pageDate, DateMath.MONTH, 1));
|
|
3023
|
|
3024 var rightArrow = cfg.getProperty(DEF_CFG.NAV_ARROW_RIGHT.key);
|
|
3025 if (rightArrow === null && Calendar.IMG_ROOT !== null) {
|
|
3026 rightArrow = Calendar.IMG_ROOT + DEPR_NAV_RIGHT;
|
|
3027 }
|
|
3028 var rightStyle = (rightArrow === null) ? "" : ' style="background-image:url(' + rightArrow + ')"';
|
|
3029 html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '"' + rightStyle + ' href="#">' + nextStr + ' (' + monthLabel + ')' + '</a>';
|
|
3030 }
|
|
3031
|
|
3032 html[html.length] = '</div>\n</th>\n</tr>';
|
|
3033
|
|
3034 if (cfg.getProperty(DEF_CFG.SHOW_WEEKDAYS.key)) {
|
|
3035 html = this.buildWeekdays(html);
|
|
3036 }
|
|
3037
|
|
3038 html[html.length] = '</thead>';
|
|
3039
|
|
3040 return html;
|
|
3041 },
|
|
3042
|
|
3043 /**
|
|
3044 * Renders the Calendar's weekday headers.
|
|
3045 * @method buildWeekdays
|
|
3046 * @param {Array} html The current working HTML array
|
|
3047 * @return {Array} The current working HTML array
|
|
3048 */
|
|
3049 buildWeekdays : function(html) {
|
|
3050
|
|
3051 html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';
|
|
3052
|
|
3053 if (this.cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key)) {
|
|
3054 html[html.length] = '<th> </th>';
|
|
3055 }
|
|
3056
|
|
3057 for(var i=0;i < this.Locale.LOCALE_WEEKDAYS.length; ++i) {
|
|
3058 html[html.length] = '<th class="' + this.Style.CSS_WEEKDAY_CELL + '">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
|
|
3059 }
|
|
3060
|
|
3061 if (this.cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key)) {
|
|
3062 html[html.length] = '<th> </th>';
|
|
3063 }
|
|
3064
|
|
3065 html[html.length] = '</tr>';
|
|
3066
|
|
3067 return html;
|
|
3068 },
|
|
3069
|
|
3070 /**
|
|
3071 * Renders the calendar body.
|
|
3072 * @method renderBody
|
|
3073 * @param {Date} workingDate The current working Date being used for the render process
|
|
3074 * @param {Array} html The current working HTML array
|
|
3075 * @return {Array} The current working HTML array
|
|
3076 */
|
|
3077 renderBody : function(workingDate, html) {
|
|
3078 this.logger.log("Rendering body", "render");
|
|
3079
|
|
3080 var startDay = this.cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
|
|
3081
|
|
3082 this.preMonthDays = workingDate.getDay();
|
|
3083 if (startDay > 0) {
|
|
3084 this.preMonthDays -= startDay;
|
|
3085 }
|
|
3086 if (this.preMonthDays < 0) {
|
|
3087 this.preMonthDays += 7;
|
|
3088 }
|
|
3089
|
|
3090 this.monthDays = DateMath.findMonthEnd(workingDate).getDate();
|
|
3091 this.postMonthDays = Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
|
|
3092
|
|
3093 this.logger.log(this.preMonthDays + " preciding out-of-month days", "render");
|
|
3094 this.logger.log(this.monthDays + " month days", "render");
|
|
3095 this.logger.log(this.postMonthDays + " post-month days", "render");
|
|
3096
|
|
3097 workingDate = DateMath.subtract(workingDate, DateMath.DAY, this.preMonthDays);
|
|
3098 this.logger.log("Calendar page starts on " + workingDate, "render");
|
|
3099
|
|
3100 var weekNum,
|
|
3101 weekClass,
|
|
3102 weekPrefix = "w",
|
|
3103 cellPrefix = "_cell",
|
|
3104 workingDayPrefix = "wd",
|
|
3105 dayPrefix = "d",
|
|
3106 cellRenderers,
|
|
3107 renderer,
|
|
3108 t = this.today,
|
|
3109 cfg = this.cfg,
|
|
3110 todayYear = t.getFullYear(),
|
|
3111 todayMonth = t.getMonth(),
|
|
3112 todayDate = t.getDate(),
|
|
3113 useDate = cfg.getProperty(DEF_CFG.PAGEDATE.key),
|
|
3114 hideBlankWeeks = cfg.getProperty(DEF_CFG.HIDE_BLANK_WEEKS.key),
|
|
3115 showWeekFooter = cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key),
|
|
3116 showWeekHeader = cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key),
|
|
3117 mindate = cfg.getProperty(DEF_CFG.MINDATE.key),
|
|
3118 maxdate = cfg.getProperty(DEF_CFG.MAXDATE.key),
|
|
3119 yearOffset = this.Locale.YEAR_OFFSET;
|
|
3120
|
|
3121 if (mindate) {
|
|
3122 mindate = DateMath.clearTime(mindate);
|
|
3123 }
|
|
3124 if (maxdate) {
|
|
3125 maxdate = DateMath.clearTime(maxdate);
|
|
3126 }
|
|
3127
|
|
3128 html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
|
|
3129
|
|
3130 var i = 0,
|
|
3131 tempDiv = document.createElement("div"),
|
|
3132 cell = document.createElement("td");
|
|
3133
|
|
3134 tempDiv.appendChild(cell);
|
|
3135
|
|
3136 var cal = this.parent || this;
|
|
3137
|
|
3138 for (var r=0;r<6;r++) {
|
|
3139 weekNum = DateMath.getWeekNumber(workingDate, startDay);
|
|
3140 weekClass = weekPrefix + weekNum;
|
|
3141
|
|
3142 // Local OOM check for performance, since we already have pagedate
|
|
3143 if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
|
|
3144 break;
|
|
3145 } else {
|
|
3146 html[html.length] = '<tr class="' + weekClass + '">';
|
|
3147
|
|
3148 if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
|
|
3149
|
|
3150 for (var d=0; d < 7; d++){ // Render actual days
|
|
3151
|
|
3152 cellRenderers = [];
|
|
3153
|
|
3154 this.clearElement(cell);
|
|
3155 cell.className = this.Style.CSS_CELL;
|
|
3156 cell.id = this.id + cellPrefix + i;
|
|
3157 this.logger.log("Rendering cell " + cell.id + " (" + workingDate.getFullYear() + yearOffset + "-" + (workingDate.getMonth()+1) + "-" + workingDate.getDate() + ")", "cellrender");
|
|
3158
|
|
3159 if (workingDate.getDate() == todayDate &&
|
|
3160 workingDate.getMonth() == todayMonth &&
|
|
3161 workingDate.getFullYear() == todayYear) {
|
|
3162 cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
|
|
3163 }
|
|
3164
|
|
3165 var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
|
|
3166 this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
|
|
3167
|
|
3168 // Local OOM check for performance, since we already have pagedate
|
|
3169 if (workingDate.getMonth() != useDate.getMonth()) {
|
|
3170 cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
|
|
3171 } else {
|
|
3172 Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
|
|
3173 Dom.addClass(cell, dayPrefix + workingDate.getDate());
|
|
3174
|
|
3175 for (var s=0;s<this.renderStack.length;++s) {
|
|
3176
|
|
3177 renderer = null;
|
|
3178
|
|
3179 var rArray = this.renderStack[s],
|
|
3180 type = rArray[0],
|
|
3181 month,
|
|
3182 day,
|
|
3183 year;
|
|
3184
|
|
3185 switch (type) {
|
|
3186 case Calendar.DATE:
|
|
3187 month = rArray[1][1];
|
|
3188 day = rArray[1][2];
|
|
3189 year = rArray[1][0];
|
|
3190
|
|
3191 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
|
|
3192 renderer = rArray[2];
|
|
3193 this.renderStack.splice(s,1);
|
|
3194 }
|
|
3195 break;
|
|
3196 case Calendar.MONTH_DAY:
|
|
3197 month = rArray[1][0];
|
|
3198 day = rArray[1][1];
|
|
3199
|
|
3200 if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
|
|
3201 renderer = rArray[2];
|
|
3202 this.renderStack.splice(s,1);
|
|
3203 }
|
|
3204 break;
|
|
3205 case Calendar.RANGE:
|
|
3206 var date1 = rArray[1][0],
|
|
3207 date2 = rArray[1][1],
|
|
3208 d1month = date1[1],
|
|
3209 d1day = date1[2],
|
|
3210 d1year = date1[0],
|
|
3211 d1 = DateMath.getDate(d1year, d1month-1, d1day),
|
|
3212 d2month = date2[1],
|
|
3213 d2day = date2[2],
|
|
3214 d2year = date2[0],
|
|
3215 d2 = DateMath.getDate(d2year, d2month-1, d2day);
|
|
3216
|
|
3217 if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
|
|
3218 renderer = rArray[2];
|
|
3219
|
|
3220 if (workingDate.getTime()==d2.getTime()) {
|
|
3221 this.renderStack.splice(s,1);
|
|
3222 }
|
|
3223 }
|
|
3224 break;
|
|
3225 case Calendar.WEEKDAY:
|
|
3226 var weekday = rArray[1][0];
|
|
3227 if (workingDate.getDay()+1 == weekday) {
|
|
3228 renderer = rArray[2];
|
|
3229 }
|
|
3230 break;
|
|
3231 case Calendar.MONTH:
|
|
3232 month = rArray[1][0];
|
|
3233 if (workingDate.getMonth()+1 == month) {
|
|
3234 renderer = rArray[2];
|
|
3235 }
|
|
3236 break;
|
|
3237 }
|
|
3238
|
|
3239 if (renderer) {
|
|
3240 cellRenderers[cellRenderers.length]=renderer;
|
|
3241 }
|
|
3242 }
|
|
3243
|
|
3244 }
|
|
3245
|
|
3246 if (this._indexOfSelectedFieldArray(workingArray) > -1) {
|
|
3247 cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
|
|
3248 }
|
|
3249
|
|
3250 if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
|
|
3251 (maxdate && (workingDate.getTime() > maxdate.getTime()))
|
|
3252 ) {
|
|
3253 cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
|
|
3254 } else {
|
|
3255 cellRenderers[cellRenderers.length]=cal.styleCellDefault;
|
|
3256 cellRenderers[cellRenderers.length]=cal.renderCellDefault;
|
|
3257 }
|
|
3258
|
|
3259 for (var x=0; x < cellRenderers.length; ++x) {
|
|
3260 this.logger.log("renderer[" + x + "] for (" + workingDate.getFullYear() + yearOffset + "-" + (workingDate.getMonth()+1) + "-" + workingDate.getDate() + ")", "cellrender");
|
|
3261 if (cellRenderers[x].call(cal, workingDate, cell) == Calendar.STOP_RENDER) {
|
|
3262 break;
|
|
3263 }
|
|
3264 }
|
|
3265
|
|
3266 workingDate.setTime(workingDate.getTime() + DateMath.ONE_DAY_MS);
|
|
3267 // Just in case we crossed DST/Summertime boundaries
|
|
3268 workingDate = DateMath.clearTime(workingDate);
|
|
3269
|
|
3270 if (i >= 0 && i <= 6) {
|
|
3271 Dom.addClass(cell, this.Style.CSS_CELL_TOP);
|
|
3272 }
|
|
3273 if ((i % 7) === 0) {
|
|
3274 Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
|
|
3275 }
|
|
3276 if (((i+1) % 7) === 0) {
|
|
3277 Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
|
|
3278 }
|
|
3279
|
|
3280 var postDays = this.postMonthDays;
|
|
3281 if (hideBlankWeeks && postDays >= 7) {
|
|
3282 var blankWeeks = Math.floor(postDays/7);
|
|
3283 for (var p=0;p<blankWeeks;++p) {
|
|
3284 postDays -= 7;
|
|
3285 }
|
|
3286 }
|
|
3287
|
|
3288 if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
|
|
3289 Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
|
|
3290 }
|
|
3291
|
|
3292 html[html.length] = tempDiv.innerHTML;
|
|
3293 i++;
|
|
3294 }
|
|
3295
|
|
3296 if (showWeekFooter) { html = this.renderRowFooter(weekNum, html); }
|
|
3297
|
|
3298 html[html.length] = '</tr>';
|
|
3299 }
|
|
3300 }
|
|
3301
|
|
3302 html[html.length] = '</tbody>';
|
|
3303
|
|
3304 return html;
|
|
3305 },
|
|
3306
|
|
3307 /**
|
|
3308 * Renders the calendar footer. In the default implementation, there is
|
|
3309 * no footer.
|
|
3310 * @method renderFooter
|
|
3311 * @param {Array} html The current working HTML array
|
|
3312 * @return {Array} The current working HTML array
|
|
3313 */
|
|
3314 renderFooter : function(html) { return html; },
|
|
3315
|
|
3316 /**
|
|
3317 * Renders the calendar after it has been configured. The render() method has a specific call chain that will execute
|
|
3318 * when the method is called: renderHeader, renderBody, renderFooter.
|
|
3319 * Refer to the documentation for those methods for information on
|
|
3320 * individual render tasks.
|
|
3321 * @method render
|
|
3322 */
|
|
3323 render : function() {
|
|
3324 this.beforeRenderEvent.fire();
|
|
3325
|
|
3326 // Find starting day of the current month
|
|
3327 var workingDate = DateMath.findMonthStart(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
|
|
3328
|
|
3329 this.resetRenderers();
|
|
3330 this.cellDates.length = 0;
|
|
3331
|
|
3332 Event.purgeElement(this.oDomContainer, true);
|
|
3333
|
|
3334 var html = [];
|
|
3335
|
|
3336 html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + (workingDate.getFullYear() + this.Locale.YEAR_OFFSET) +'" id="' + this.id + '">';
|
|
3337 html = this.renderHeader(html);
|
|
3338 html = this.renderBody(workingDate, html);
|
|
3339 html = this.renderFooter(html);
|
|
3340 html[html.length] = '</table>';
|
|
3341
|
|
3342 this.oDomContainer.innerHTML = html.join("\n");
|
|
3343
|
|
3344 this.applyListeners();
|
|
3345 this.cells = Dom.getElementsByClassName(this.Style.CSS_CELL, "td", this.id);
|
|
3346
|
|
3347 this.cfg.refireEvent(DEF_CFG.TITLE.key);
|
|
3348 this.cfg.refireEvent(DEF_CFG.CLOSE.key);
|
|
3349 this.cfg.refireEvent(DEF_CFG.IFRAME.key);
|
|
3350
|
|
3351 this.renderEvent.fire();
|
|
3352 },
|
|
3353
|
|
3354 /**
|
|
3355 * Applies the Calendar's DOM listeners to applicable elements.
|
|
3356 * @method applyListeners
|
|
3357 */
|
|
3358 applyListeners : function() {
|
|
3359 var root = this.oDomContainer,
|
|
3360 cal = this.parent || this,
|
|
3361 anchor = "a",
|
|
3362 click = "click";
|
|
3363
|
|
3364 var linkLeft = Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, anchor, root),
|
|
3365 linkRight = Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, anchor, root);
|
|
3366
|
|
3367 if (linkLeft && linkLeft.length > 0) {
|
|
3368 this.linkLeft = linkLeft[0];
|
|
3369 Event.addListener(this.linkLeft, click, this.doPreviousMonthNav, cal, true);
|
|
3370 }
|
|
3371
|
|
3372 if (linkRight && linkRight.length > 0) {
|
|
3373 this.linkRight = linkRight[0];
|
|
3374 Event.addListener(this.linkRight, click, this.doNextMonthNav, cal, true);
|
|
3375 }
|
|
3376
|
|
3377 if (cal.cfg.getProperty("navigator") !== null) {
|
|
3378 this.applyNavListeners();
|
|
3379 }
|
|
3380
|
|
3381 if (this.domEventMap) {
|
|
3382 var el,elements;
|
|
3383 for (var cls in this.domEventMap) {
|
|
3384 if (Lang.hasOwnProperty(this.domEventMap, cls)) {
|
|
3385 var items = this.domEventMap[cls];
|
|
3386
|
|
3387 if (! (items instanceof Array)) {
|
|
3388 items = [items];
|
|
3389 }
|
|
3390
|
|
3391 for (var i=0;i<items.length;i++) {
|
|
3392 var item = items[i];
|
|
3393 elements = Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);
|
|
3394
|
|
3395 for (var c=0;c<elements.length;c++) {
|
|
3396 el = elements[c];
|
|
3397 Event.addListener(el, item.event, item.handler, item.scope, item.correct );
|
|
3398 }
|
|
3399 }
|
|
3400 }
|
|
3401 }
|
|
3402 }
|
|
3403
|
|
3404 Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
|
|
3405 Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
|
|
3406 Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
|
|
3407 },
|
|
3408
|
|
3409 applyNavListeners : function() {
|
|
3410 var calParent = this.parent || this,
|
|
3411 cal = this,
|
|
3412 navBtns = Dom.getElementsByClassName(this.Style.CSS_NAV, "a", this.oDomContainer);
|
|
3413
|
|
3414 if (navBtns.length > 0) {
|
|
3415
|
|
3416 Event.addListener(navBtns, "click", function (e, obj) {
|
|
3417 var target = Event.getTarget(e);
|
|
3418 // this == navBtn
|
|
3419 if (this === target || Dom.isAncestor(this, target)) {
|
|
3420 Event.preventDefault(e);
|
|
3421 }
|
|
3422 var navigator = calParent.oNavigator;
|
|
3423 if (navigator) {
|
|
3424 var pgdate = cal.cfg.getProperty("pagedate");
|
|
3425 navigator.setYear(pgdate.getFullYear() + cal.Locale.YEAR_OFFSET);
|
|
3426 navigator.setMonth(pgdate.getMonth());
|
|
3427 navigator.show();
|
|
3428 }
|
|
3429 });
|
|
3430 }
|
|
3431 },
|
|
3432
|
|
3433 /**
|
|
3434 * Retrieves the Date object for the specified Calendar cell
|
|
3435 * @method getDateByCellId
|
|
3436 * @param {String} id The id of the cell
|
|
3437 * @return {Date} The Date object for the specified Calendar cell
|
|
3438 */
|
|
3439 getDateByCellId : function(id) {
|
|
3440 var date = this.getDateFieldsByCellId(id);
|
|
3441 return (date) ? DateMath.getDate(date[0],date[1]-1,date[2]) : null;
|
|
3442 },
|
|
3443
|
|
3444 /**
|
|
3445 * Retrieves the Date object for the specified Calendar cell
|
|
3446 * @method getDateFieldsByCellId
|
|
3447 * @param {String} id The id of the cell
|
|
3448 * @return {Array} The array of Date fields for the specified Calendar cell
|
|
3449 */
|
|
3450 getDateFieldsByCellId : function(id) {
|
|
3451 id = this.getIndexFromId(id);
|
|
3452 return (id > -1) ? this.cellDates[id] : null;
|
|
3453 },
|
|
3454
|
|
3455 /**
|
|
3456 * Find the Calendar's cell index for a given date.
|
|
3457 * If the date is not found, the method returns -1.
|
|
3458 * <p>
|
|
3459 * The returned index can be used to lookup the cell HTMLElement
|
|
3460 * using the Calendar's cells array or passed to selectCell to select
|
|
3461 * cells by index.
|
|
3462 * </p>
|
|
3463 *
|
|
3464 * See <a href="#cells">cells</a>, <a href="#selectCell">selectCell</a>.
|
|
3465 *
|
|
3466 * @method getCellIndex
|
|
3467 * @param {Date} date JavaScript Date object, for which to find a cell index.
|
|
3468 * @return {Number} The index of the date in Calendars cellDates/cells arrays, or -1 if the date
|
|
3469 * is not on the curently rendered Calendar page.
|
|
3470 */
|
|
3471 getCellIndex : function(date) {
|
|
3472 var idx = -1;
|
|
3473 if (date) {
|
|
3474 var m = date.getMonth(),
|
|
3475 y = date.getFullYear(),
|
|
3476 d = date.getDate(),
|
|
3477 dates = this.cellDates;
|
|
3478
|
|
3479 for (var i = 0; i < dates.length; ++i) {
|
|
3480 var cellDate = dates[i];
|
|
3481 if (cellDate[0] === y && cellDate[1] === m+1 && cellDate[2] === d) {
|
|
3482 idx = i;
|
|
3483 break;
|
|
3484 }
|
|
3485 }
|
|
3486 }
|
|
3487 return idx;
|
|
3488 },
|
|
3489
|
|
3490 /**
|
|
3491 * Given the id used to mark each Calendar cell, this method
|
|
3492 * extracts the index number from the id.
|
|
3493 *
|
|
3494 * @param {String} strId The cell id
|
|
3495 * @return {Number} The index of the cell, or -1 if id does not contain an index number
|
|
3496 */
|
|
3497 getIndexFromId : function(strId) {
|
|
3498 var idx = -1,
|
|
3499 li = strId.lastIndexOf("_cell");
|
|
3500
|
|
3501 if (li > -1) {
|
|
3502 idx = parseInt(strId.substring(li + 5), 10);
|
|
3503 }
|
|
3504
|
|
3505 return idx;
|
|
3506 },
|
|
3507
|
|
3508 // BEGIN BUILT-IN TABLE CELL RENDERERS
|
|
3509
|
|
3510 /**
|
|
3511 * Renders a cell that falls before the minimum date or after the maximum date.
|
|
3512 * widget class.
|
|
3513 * @method renderOutOfBoundsDate
|
|
3514 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3515 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3516 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
|
|
3517 * should not be terminated
|
|
3518 */
|
|
3519 renderOutOfBoundsDate : function(workingDate, cell) {
|
|
3520 Dom.addClass(cell, this.Style.CSS_CELL_OOB);
|
|
3521 cell.innerHTML = workingDate.getDate();
|
|
3522 return Calendar.STOP_RENDER;
|
|
3523 },
|
|
3524
|
|
3525 /**
|
|
3526 * Renders the row header for a week.
|
|
3527 * @method renderRowHeader
|
|
3528 * @param {Number} weekNum The week number of the current row
|
|
3529 * @param {Array} cell The current working HTML array
|
|
3530 */
|
|
3531 renderRowHeader : function(weekNum, html) {
|
|
3532 html[html.length] = '<th class="' + this.Style.CSS_ROW_HEADER + '">' + weekNum + '</th>';
|
|
3533 return html;
|
|
3534 },
|
|
3535
|
|
3536 /**
|
|
3537 * Renders the row footer for a week.
|
|
3538 * @method renderRowFooter
|
|
3539 * @param {Number} weekNum The week number of the current row
|
|
3540 * @param {Array} cell The current working HTML array
|
|
3541 */
|
|
3542 renderRowFooter : function(weekNum, html) {
|
|
3543 html[html.length] = '<th class="' + this.Style.CSS_ROW_FOOTER + '">' + weekNum + '</th>';
|
|
3544 return html;
|
|
3545 },
|
|
3546
|
|
3547 /**
|
|
3548 * Renders a single standard calendar cell in the calendar widget table.
|
|
3549 * All logic for determining how a standard default cell will be rendered is
|
|
3550 * encapsulated in this method, and must be accounted for when extending the
|
|
3551 * widget class.
|
|
3552 * @method renderCellDefault
|
|
3553 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3554 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3555 */
|
|
3556 renderCellDefault : function(workingDate, cell) {
|
|
3557 cell.innerHTML = '<a href="#" class="' + this.Style.CSS_CELL_SELECTOR + '">' + this.buildDayLabel(workingDate) + "</a>";
|
|
3558 },
|
|
3559
|
|
3560 /**
|
|
3561 * Styles a selectable cell.
|
|
3562 * @method styleCellDefault
|
|
3563 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3564 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3565 */
|
|
3566 styleCellDefault : function(workingDate, cell) {
|
|
3567 Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
|
|
3568 },
|
|
3569
|
|
3570
|
|
3571 /**
|
|
3572 * Renders a single standard calendar cell using the CSS hightlight1 style
|
|
3573 * @method renderCellStyleHighlight1
|
|
3574 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3575 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3576 */
|
|
3577 renderCellStyleHighlight1 : function(workingDate, cell) {
|
|
3578 Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
|
|
3579 },
|
|
3580
|
|
3581 /**
|
|
3582 * Renders a single standard calendar cell using the CSS hightlight2 style
|
|
3583 * @method renderCellStyleHighlight2
|
|
3584 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3585 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3586 */
|
|
3587 renderCellStyleHighlight2 : function(workingDate, cell) {
|
|
3588 Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
|
|
3589 },
|
|
3590
|
|
3591 /**
|
|
3592 * Renders a single standard calendar cell using the CSS hightlight3 style
|
|
3593 * @method renderCellStyleHighlight3
|
|
3594 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3595 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3596 */
|
|
3597 renderCellStyleHighlight3 : function(workingDate, cell) {
|
|
3598 Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
|
|
3599 },
|
|
3600
|
|
3601 /**
|
|
3602 * Renders a single standard calendar cell using the CSS hightlight4 style
|
|
3603 * @method renderCellStyleHighlight4
|
|
3604 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3605 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3606 */
|
|
3607 renderCellStyleHighlight4 : function(workingDate, cell) {
|
|
3608 Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
|
|
3609 },
|
|
3610
|
|
3611 /**
|
|
3612 * Applies the default style used for rendering today's date to the current calendar cell
|
|
3613 * @method renderCellStyleToday
|
|
3614 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3615 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3616 */
|
|
3617 renderCellStyleToday : function(workingDate, cell) {
|
|
3618 Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
|
|
3619 },
|
|
3620
|
|
3621 /**
|
|
3622 * Applies the default style used for rendering selected dates to the current calendar cell
|
|
3623 * @method renderCellStyleSelected
|
|
3624 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3625 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3626 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
|
|
3627 * should not be terminated
|
|
3628 */
|
|
3629 renderCellStyleSelected : function(workingDate, cell) {
|
|
3630 Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
|
|
3631 },
|
|
3632
|
|
3633 /**
|
|
3634 * Applies the default style used for rendering dates that are not a part of the current
|
|
3635 * month (preceding or trailing the cells for the current month)
|
|
3636 * @method renderCellNotThisMonth
|
|
3637 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3638 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3639 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
|
|
3640 * should not be terminated
|
|
3641 */
|
|
3642 renderCellNotThisMonth : function(workingDate, cell) {
|
|
3643 Dom.addClass(cell, this.Style.CSS_CELL_OOM);
|
|
3644 cell.innerHTML=workingDate.getDate();
|
|
3645 return Calendar.STOP_RENDER;
|
|
3646 },
|
|
3647
|
|
3648 /**
|
|
3649 * Renders the current calendar cell as a non-selectable "black-out" date using the default
|
|
3650 * restricted style.
|
|
3651 * @method renderBodyCellRestricted
|
|
3652 * @param {Date} workingDate The current working Date object being used to generate the calendar
|
|
3653 * @param {HTMLTableCellElement} cell The current working cell in the calendar
|
|
3654 * @return {String} YAHOO.widget.Calendar.STOP_RENDER if rendering should stop with this style, null or nothing if rendering
|
|
3655 * should not be terminated
|
|
3656 */
|
|
3657 renderBodyCellRestricted : function(workingDate, cell) {
|
|
3658 Dom.addClass(cell, this.Style.CSS_CELL);
|
|
3659 Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
|
|
3660 cell.innerHTML=workingDate.getDate();
|
|
3661 return Calendar.STOP_RENDER;
|
|
3662 },
|
|
3663
|
|
3664 // END BUILT-IN TABLE CELL RENDERERS
|
|
3665
|
|
3666 // BEGIN MONTH NAVIGATION METHODS
|
|
3667
|
|
3668 /**
|
|
3669 * Adds the designated number of months to the current calendar month, and sets the current
|
|
3670 * calendar page date to the new month.
|
|
3671 * @method addMonths
|
|
3672 * @param {Number} count The number of months to add to the current calendar
|
|
3673 */
|
|
3674 addMonths : function(count) {
|
|
3675 var cfgPageDate = DEF_CFG.PAGEDATE.key,
|
|
3676
|
|
3677 prevDate = this.cfg.getProperty(cfgPageDate),
|
|
3678 newDate = DateMath.add(prevDate, DateMath.MONTH, count);
|
|
3679
|
|
3680 this.cfg.setProperty(cfgPageDate, newDate);
|
|
3681 this.resetRenderers();
|
|
3682 this.changePageEvent.fire(prevDate, newDate);
|
|
3683 },
|
|
3684
|
|
3685 /**
|
|
3686 * Subtracts the designated number of months from the current calendar month, and sets the current
|
|
3687 * calendar page date to the new month.
|
|
3688 * @method subtractMonths
|
|
3689 * @param {Number} count The number of months to subtract from the current calendar
|
|
3690 */
|
|
3691 subtractMonths : function(count) {
|
|
3692 this.addMonths(-1*count);
|
|
3693 },
|
|
3694
|
|
3695 /**
|
|
3696 * Adds the designated number of years to the current calendar, and sets the current
|
|
3697 * calendar page date to the new month.
|
|
3698 * @method addYears
|
|
3699 * @param {Number} count The number of years to add to the current calendar
|
|
3700 */
|
|
3701 addYears : function(count) {
|
|
3702 var cfgPageDate = DEF_CFG.PAGEDATE.key,
|
|
3703
|
|
3704 prevDate = this.cfg.getProperty(cfgPageDate),
|
|
3705 newDate = DateMath.add(prevDate, DateMath.YEAR, count);
|
|
3706
|
|
3707 this.cfg.setProperty(cfgPageDate, newDate);
|
|
3708 this.resetRenderers();
|
|
3709 this.changePageEvent.fire(prevDate, newDate);
|
|
3710 },
|
|
3711
|
|
3712 /**
|
|
3713 * Subtcats the designated number of years from the current calendar, and sets the current
|
|
3714 * calendar page date to the new month.
|
|
3715 * @method subtractYears
|
|
3716 * @param {Number} count The number of years to subtract from the current calendar
|
|
3717 */
|
|
3718 subtractYears : function(count) {
|
|
3719 this.addYears(-1*count);
|
|
3720 },
|
|
3721
|
|
3722 /**
|
|
3723 * Navigates to the next month page in the calendar widget.
|
|
3724 * @method nextMonth
|
|
3725 */
|
|
3726 nextMonth : function() {
|
|
3727 this.addMonths(1);
|
|
3728 },
|
|
3729
|
|
3730 /**
|
|
3731 * Navigates to the previous month page in the calendar widget.
|
|
3732 * @method previousMonth
|
|
3733 */
|
|
3734 previousMonth : function() {
|
|
3735 this.addMonths(-1);
|
|
3736 },
|
|
3737
|
|
3738 /**
|
|
3739 * Navigates to the next year in the currently selected month in the calendar widget.
|
|
3740 * @method nextYear
|
|
3741 */
|
|
3742 nextYear : function() {
|
|
3743 this.addYears(1);
|
|
3744 },
|
|
3745
|
|
3746 /**
|
|
3747 * Navigates to the previous year in the currently selected month in the calendar widget.
|
|
3748 * @method previousYear
|
|
3749 */
|
|
3750 previousYear : function() {
|
|
3751 this.addYears(-1);
|
|
3752 },
|
|
3753
|
|
3754 // END MONTH NAVIGATION METHODS
|
|
3755
|
|
3756 // BEGIN SELECTION METHODS
|
|
3757
|
|
3758 /**
|
|
3759 * Resets the calendar widget to the originally selected month and year, and
|
|
3760 * sets the calendar to the initial selection(s).
|
|
3761 * @method reset
|
|
3762 */
|
|
3763 reset : function() {
|
|
3764 this.cfg.resetProperty(DEF_CFG.SELECTED.key);
|
|
3765 this.cfg.resetProperty(DEF_CFG.PAGEDATE.key);
|
|
3766 this.resetEvent.fire();
|
|
3767 },
|
|
3768
|
|
3769 /**
|
|
3770 * Clears the selected dates in the current calendar widget and sets the calendar
|
|
3771 * to the current month and year.
|
|
3772 * @method clear
|
|
3773 */
|
|
3774 clear : function() {
|
|
3775 this.cfg.setProperty(DEF_CFG.SELECTED.key, []);
|
|
3776 this.cfg.setProperty(DEF_CFG.PAGEDATE.key, new Date(this.today.getTime()));
|
|
3777 this.clearEvent.fire();
|
|
3778 },
|
|
3779
|
|
3780 /**
|
|
3781 * Selects a date or a collection of dates on the current calendar. This method, by default,
|
|
3782 * does not call the render method explicitly. Once selection has completed, render must be
|
|
3783 * called for the changes to be reflected visually.
|
|
3784 *
|
|
3785 * Any dates which are OOB (out of bounds, not selectable) will not be selected and the array of
|
|
3786 * selected dates passed to the selectEvent will not contain OOB dates.
|
|
3787 *
|
|
3788 * If all dates are OOB, the no state change will occur; beforeSelect and select events will not be fired.
|
|
3789 *
|
|
3790 * @method select
|
|
3791 * @param {String/Date/Date[]} date The date string of dates to select in the current calendar. Valid formats are
|
|
3792 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
|
|
3793 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
|
|
3794 * This method can also take a JavaScript Date object or an array of Date objects.
|
|
3795 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
3796 */
|
|
3797 select : function(date) {
|
|
3798 this.logger.log("Select: " + date, "info");
|
|
3799
|
|
3800 var aToBeSelected = this._toFieldArray(date),
|
|
3801 validDates = [],
|
|
3802 selected = [],
|
|
3803 cfgSelected = DEF_CFG.SELECTED.key;
|
|
3804
|
|
3805 this.logger.log("Selection field array: " + aToBeSelected, "info");
|
|
3806
|
|
3807 for (var a=0; a < aToBeSelected.length; ++a) {
|
|
3808 var toSelect = aToBeSelected[a];
|
|
3809
|
|
3810 if (!this.isDateOOB(this._toDate(toSelect))) {
|
|
3811
|
|
3812 if (validDates.length === 0) {
|
|
3813 this.beforeSelectEvent.fire();
|
|
3814 selected = this.cfg.getProperty(cfgSelected);
|
|
3815 }
|
|
3816 validDates.push(toSelect);
|
|
3817
|
|
3818 if (this._indexOfSelectedFieldArray(toSelect) == -1) {
|
|
3819 selected[selected.length] = toSelect;
|
|
3820 }
|
|
3821 }
|
|
3822 }
|
|
3823
|
|
3824 if (validDates.length === 0) { this.logger.log("All provided dates were OOB. beforeSelect and select events not fired", "info"); }
|
|
3825
|
|
3826 if (validDates.length > 0) {
|
|
3827 if (this.parent) {
|
|
3828 this.parent.cfg.setProperty(cfgSelected, selected);
|
|
3829 } else {
|
|
3830 this.cfg.setProperty(cfgSelected, selected);
|
|
3831 }
|
|
3832 this.selectEvent.fire(validDates);
|
|
3833 }
|
|
3834
|
|
3835 return this.getSelectedDates();
|
|
3836 },
|
|
3837
|
|
3838 /**
|
|
3839 * Selects a date on the current calendar by referencing the index of the cell that should be selected.
|
|
3840 * This method is used to easily select a single cell (usually with a mouse click) without having to do
|
|
3841 * a full render. The selected style is applied to the cell directly.
|
|
3842 *
|
|
3843 * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
|
|
3844 * or out of bounds cells), it will not be selected and in such a case beforeSelect and select events will not be fired.
|
|
3845 *
|
|
3846 * @method selectCell
|
|
3847 * @param {Number} cellIndex The index of the cell to select in the current calendar.
|
|
3848 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
3849 */
|
|
3850 selectCell : function(cellIndex) {
|
|
3851
|
|
3852 var cell = this.cells[cellIndex],
|
|
3853 cellDate = this.cellDates[cellIndex],
|
|
3854 dCellDate = this._toDate(cellDate),
|
|
3855 selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
|
|
3856
|
|
3857 this.logger.log("Select: " + dCellDate, "info");
|
|
3858 if (!selectable) {this.logger.log("The cell at cellIndex:" + cellIndex + " is not a selectable cell. beforeSelect, select events not fired", "info"); }
|
|
3859
|
|
3860 if (selectable) {
|
|
3861
|
|
3862 this.beforeSelectEvent.fire();
|
|
3863
|
|
3864 var cfgSelected = DEF_CFG.SELECTED.key;
|
|
3865 var selected = this.cfg.getProperty(cfgSelected);
|
|
3866
|
|
3867 var selectDate = cellDate.concat();
|
|
3868
|
|
3869 if (this._indexOfSelectedFieldArray(selectDate) == -1) {
|
|
3870 selected[selected.length] = selectDate;
|
|
3871 }
|
|
3872 if (this.parent) {
|
|
3873 this.parent.cfg.setProperty(cfgSelected, selected);
|
|
3874 } else {
|
|
3875 this.cfg.setProperty(cfgSelected, selected);
|
|
3876 }
|
|
3877 this.renderCellStyleSelected(dCellDate,cell);
|
|
3878 this.selectEvent.fire([selectDate]);
|
|
3879
|
|
3880 this.doCellMouseOut.call(cell, null, this);
|
|
3881 }
|
|
3882
|
|
3883 return this.getSelectedDates();
|
|
3884 },
|
|
3885
|
|
3886 /**
|
|
3887 * Deselects a date or a collection of dates on the current calendar. This method, by default,
|
|
3888 * does not call the render method explicitly. Once deselection has completed, render must be
|
|
3889 * called for the changes to be reflected visually.
|
|
3890 *
|
|
3891 * The method will not attempt to deselect any dates which are OOB (out of bounds, and hence not selectable)
|
|
3892 * and the array of deselected dates passed to the deselectEvent will not contain any OOB dates.
|
|
3893 *
|
|
3894 * If all dates are OOB, beforeDeselect and deselect events will not be fired.
|
|
3895 *
|
|
3896 * @method deselect
|
|
3897 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
|
|
3898 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
|
|
3899 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
|
|
3900 * This method can also take a JavaScript Date object or an array of Date objects.
|
|
3901 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
3902 */
|
|
3903 deselect : function(date) {
|
|
3904 this.logger.log("Deselect: " + date, "info");
|
|
3905
|
|
3906 var aToBeDeselected = this._toFieldArray(date),
|
|
3907 validDates = [],
|
|
3908 selected = [],
|
|
3909 cfgSelected = DEF_CFG.SELECTED.key;
|
|
3910
|
|
3911 this.logger.log("Deselection field array: " + aToBeDeselected, "info");
|
|
3912
|
|
3913 for (var a=0; a < aToBeDeselected.length; ++a) {
|
|
3914 var toDeselect = aToBeDeselected[a];
|
|
3915
|
|
3916 if (!this.isDateOOB(this._toDate(toDeselect))) {
|
|
3917
|
|
3918 if (validDates.length === 0) {
|
|
3919 this.beforeDeselectEvent.fire();
|
|
3920 selected = this.cfg.getProperty(cfgSelected);
|
|
3921 }
|
|
3922
|
|
3923 validDates.push(toDeselect);
|
|
3924
|
|
3925 var index = this._indexOfSelectedFieldArray(toDeselect);
|
|
3926 if (index != -1) {
|
|
3927 selected.splice(index,1);
|
|
3928 }
|
|
3929 }
|
|
3930 }
|
|
3931
|
|
3932 if (validDates.length === 0) { this.logger.log("All provided dates were OOB. beforeDeselect and deselect events not fired");}
|
|
3933
|
|
3934 if (validDates.length > 0) {
|
|
3935 if (this.parent) {
|
|
3936 this.parent.cfg.setProperty(cfgSelected, selected);
|
|
3937 } else {
|
|
3938 this.cfg.setProperty(cfgSelected, selected);
|
|
3939 }
|
|
3940 this.deselectEvent.fire(validDates);
|
|
3941 }
|
|
3942
|
|
3943 return this.getSelectedDates();
|
|
3944 },
|
|
3945
|
|
3946 /**
|
|
3947 * Deselects a date on the current calendar by referencing the index of the cell that should be deselected.
|
|
3948 * This method is used to easily deselect a single cell (usually with a mouse click) without having to do
|
|
3949 * a full render. The selected style is removed from the cell directly.
|
|
3950 *
|
|
3951 * If the cell is not marked with the CSS_CELL_SELECTABLE class (as is the case by default for out of month
|
|
3952 * or out of bounds cells), the method will not attempt to deselect it and in such a case, beforeDeselect and
|
|
3953 * deselect events will not be fired.
|
|
3954 *
|
|
3955 * @method deselectCell
|
|
3956 * @param {Number} cellIndex The index of the cell to deselect in the current calendar.
|
|
3957 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
3958 */
|
|
3959 deselectCell : function(cellIndex) {
|
|
3960 var cell = this.cells[cellIndex],
|
|
3961 cellDate = this.cellDates[cellIndex],
|
|
3962 cellDateIndex = this._indexOfSelectedFieldArray(cellDate);
|
|
3963
|
|
3964 var selectable = Dom.hasClass(cell, this.Style.CSS_CELL_SELECTABLE);
|
|
3965 if (!selectable) { this.logger.log("The cell at cellIndex:" + cellIndex + " is not a selectable/deselectable cell", "info"); }
|
|
3966
|
|
3967 if (selectable) {
|
|
3968
|
|
3969 this.beforeDeselectEvent.fire();
|
|
3970
|
|
3971 var selected = this.cfg.getProperty(DEF_CFG.SELECTED.key),
|
|
3972 dCellDate = this._toDate(cellDate),
|
|
3973 selectDate = cellDate.concat();
|
|
3974
|
|
3975 if (cellDateIndex > -1) {
|
|
3976 if (this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getMonth() == dCellDate.getMonth() &&
|
|
3977 this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getFullYear() == dCellDate.getFullYear()) {
|
|
3978 Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
|
|
3979 }
|
|
3980 selected.splice(cellDateIndex, 1);
|
|
3981 }
|
|
3982
|
|
3983 if (this.parent) {
|
|
3984 this.parent.cfg.setProperty(DEF_CFG.SELECTED.key, selected);
|
|
3985 } else {
|
|
3986 this.cfg.setProperty(DEF_CFG.SELECTED.key, selected);
|
|
3987 }
|
|
3988
|
|
3989 this.deselectEvent.fire([selectDate]);
|
|
3990 }
|
|
3991
|
|
3992 return this.getSelectedDates();
|
|
3993 },
|
|
3994
|
|
3995 /**
|
|
3996 * Deselects all dates on the current calendar.
|
|
3997 * @method deselectAll
|
|
3998 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
3999 * Assuming that this function executes properly, the return value should be an empty array.
|
|
4000 * However, the empty array is returned for the sake of being able to check the selection status
|
|
4001 * of the calendar.
|
|
4002 */
|
|
4003 deselectAll : function() {
|
|
4004 this.beforeDeselectEvent.fire();
|
|
4005
|
|
4006 var cfgSelected = DEF_CFG.SELECTED.key,
|
|
4007 selected = this.cfg.getProperty(cfgSelected),
|
|
4008 count = selected.length,
|
|
4009 sel = selected.concat();
|
|
4010
|
|
4011 if (this.parent) {
|
|
4012 this.parent.cfg.setProperty(cfgSelected, []);
|
|
4013 } else {
|
|
4014 this.cfg.setProperty(cfgSelected, []);
|
|
4015 }
|
|
4016
|
|
4017 if (count > 0) {
|
|
4018 this.deselectEvent.fire(sel);
|
|
4019 }
|
|
4020
|
|
4021 return this.getSelectedDates();
|
|
4022 },
|
|
4023
|
|
4024 // END SELECTION METHODS
|
|
4025
|
|
4026 // BEGIN TYPE CONVERSION METHODS
|
|
4027
|
|
4028 /**
|
|
4029 * Converts a date (either a JavaScript Date object, or a date string) to the internal data structure
|
|
4030 * used to represent dates: [[yyyy,mm,dd],[yyyy,mm,dd]].
|
|
4031 * @method _toFieldArray
|
|
4032 * @private
|
|
4033 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
|
|
4034 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
|
|
4035 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
|
|
4036 * This method can also take a JavaScript Date object or an array of Date objects.
|
|
4037 * @return {Array[](Number[])} Array of date field arrays
|
|
4038 */
|
|
4039 _toFieldArray : function(date) {
|
|
4040 var returnDate = [];
|
|
4041
|
|
4042 if (date instanceof Date) {
|
|
4043 returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
|
|
4044 } else if (Lang.isString(date)) {
|
|
4045 returnDate = this._parseDates(date);
|
|
4046 } else if (Lang.isArray(date)) {
|
|
4047 for (var i=0;i<date.length;++i) {
|
|
4048 var d = date[i];
|
|
4049 returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
|
|
4050 }
|
|
4051 }
|
|
4052
|
|
4053 return returnDate;
|
|
4054 },
|
|
4055
|
|
4056 /**
|
|
4057 * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object. The date field array
|
|
4058 * is the format in which dates are as provided as arguments to selectEvent and deselectEvent listeners.
|
|
4059 *
|
|
4060 * @method toDate
|
|
4061 * @param {Number[]} dateFieldArray The date field array to convert to a JavaScript Date.
|
|
4062 * @return {Date} JavaScript Date object representing the date field array.
|
|
4063 */
|
|
4064 toDate : function(dateFieldArray) {
|
|
4065 return this._toDate(dateFieldArray);
|
|
4066 },
|
|
4067
|
|
4068 /**
|
|
4069 * Converts a date field array [yyyy,mm,dd] to a JavaScript Date object.
|
|
4070 * @method _toDate
|
|
4071 * @private
|
|
4072 * @deprecated Made public, toDate
|
|
4073 * @param {Number[]} dateFieldArray The date field array to convert to a JavaScript Date.
|
|
4074 * @return {Date} JavaScript Date object representing the date field array
|
|
4075 */
|
|
4076 _toDate : function(dateFieldArray) {
|
|
4077 if (dateFieldArray instanceof Date) {
|
|
4078 return dateFieldArray;
|
|
4079 } else {
|
|
4080 return DateMath.getDate(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
|
|
4081 }
|
|
4082 },
|
|
4083
|
|
4084 // END TYPE CONVERSION METHODS
|
|
4085
|
|
4086 // BEGIN UTILITY METHODS
|
|
4087
|
|
4088 /**
|
|
4089 * Determines if 2 field arrays are equal.
|
|
4090 * @method _fieldArraysAreEqual
|
|
4091 * @private
|
|
4092 * @param {Number[]} array1 The first date field array to compare
|
|
4093 * @param {Number[]} array2 The first date field array to compare
|
|
4094 * @return {Boolean} The boolean that represents the equality of the two arrays
|
|
4095 */
|
|
4096 _fieldArraysAreEqual : function(array1, array2) {
|
|
4097 var match = false;
|
|
4098
|
|
4099 if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
|
|
4100 match=true;
|
|
4101 }
|
|
4102
|
|
4103 return match;
|
|
4104 },
|
|
4105
|
|
4106 /**
|
|
4107 * Gets the index of a date field array [yyyy,mm,dd] in the current list of selected dates.
|
|
4108 * @method _indexOfSelectedFieldArray
|
|
4109 * @private
|
|
4110 * @param {Number[]} find The date field array to search for
|
|
4111 * @return {Number} The index of the date field array within the collection of selected dates.
|
|
4112 * -1 will be returned if the date is not found.
|
|
4113 */
|
|
4114 _indexOfSelectedFieldArray : function(find) {
|
|
4115 var selected = -1,
|
|
4116 seldates = this.cfg.getProperty(DEF_CFG.SELECTED.key);
|
|
4117
|
|
4118 for (var s=0;s<seldates.length;++s) {
|
|
4119 var sArray = seldates[s];
|
|
4120 if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
|
|
4121 selected = s;
|
|
4122 break;
|
|
4123 }
|
|
4124 }
|
|
4125
|
|
4126 return selected;
|
|
4127 },
|
|
4128
|
|
4129 /**
|
|
4130 * Determines whether a given date is OOM (out of month).
|
|
4131 * @method isDateOOM
|
|
4132 * @param {Date} date The JavaScript Date object for which to check the OOM status
|
|
4133 * @return {Boolean} true if the date is OOM
|
|
4134 */
|
|
4135 isDateOOM : function(date) {
|
|
4136 return (date.getMonth() != this.cfg.getProperty(DEF_CFG.PAGEDATE.key).getMonth());
|
|
4137 },
|
|
4138
|
|
4139 /**
|
|
4140 * Determines whether a given date is OOB (out of bounds - less than the mindate or more than the maxdate).
|
|
4141 *
|
|
4142 * @method isDateOOB
|
|
4143 * @param {Date} date The JavaScript Date object for which to check the OOB status
|
|
4144 * @return {Boolean} true if the date is OOB
|
|
4145 */
|
|
4146 isDateOOB : function(date) {
|
|
4147 var minDate = this.cfg.getProperty(DEF_CFG.MINDATE.key),
|
|
4148 maxDate = this.cfg.getProperty(DEF_CFG.MAXDATE.key),
|
|
4149 dm = DateMath;
|
|
4150
|
|
4151 if (minDate) {
|
|
4152 minDate = dm.clearTime(minDate);
|
|
4153 }
|
|
4154 if (maxDate) {
|
|
4155 maxDate = dm.clearTime(maxDate);
|
|
4156 }
|
|
4157
|
|
4158 var clearedDate = new Date(date.getTime());
|
|
4159 clearedDate = dm.clearTime(clearedDate);
|
|
4160
|
|
4161 return ((minDate && clearedDate.getTime() < minDate.getTime()) || (maxDate && clearedDate.getTime() > maxDate.getTime()));
|
|
4162 },
|
|
4163
|
|
4164 /**
|
|
4165 * Parses a pagedate configuration property value. The value can either be specified as a string of form "mm/yyyy" or a Date object
|
|
4166 * and is parsed into a Date object normalized to the first day of the month. If no value is passed in, the month and year from today's date are used to create the Date object
|
|
4167 * @method _parsePageDate
|
|
4168 * @private
|
|
4169 * @param {Date|String} date Pagedate value which needs to be parsed
|
|
4170 * @return {Date} The Date object representing the pagedate
|
|
4171 */
|
|
4172 _parsePageDate : function(date) {
|
|
4173 var parsedDate;
|
|
4174
|
|
4175 if (date) {
|
|
4176 if (date instanceof Date) {
|
|
4177 parsedDate = DateMath.findMonthStart(date);
|
|
4178 } else {
|
|
4179 var month, year, aMonthYear;
|
|
4180 aMonthYear = date.split(this.cfg.getProperty(DEF_CFG.DATE_FIELD_DELIMITER.key));
|
|
4181 month = parseInt(aMonthYear[this.cfg.getProperty(DEF_CFG.MY_MONTH_POSITION.key)-1], 10)-1;
|
|
4182 year = parseInt(aMonthYear[this.cfg.getProperty(DEF_CFG.MY_YEAR_POSITION.key)-1], 10) - this.Locale.YEAR_OFFSET;
|
|
4183
|
|
4184 parsedDate = DateMath.getDate(year, month, 1);
|
|
4185 }
|
|
4186 } else {
|
|
4187 parsedDate = DateMath.getDate(this.today.getFullYear(), this.today.getMonth(), 1);
|
|
4188 }
|
|
4189 return parsedDate;
|
|
4190 },
|
|
4191
|
|
4192 // END UTILITY METHODS
|
|
4193
|
|
4194 // BEGIN EVENT HANDLERS
|
|
4195
|
|
4196 /**
|
|
4197 * Event executed before a date is selected in the calendar widget.
|
|
4198 * @deprecated Event handlers for this event should be susbcribed to beforeSelectEvent.
|
|
4199 */
|
|
4200 onBeforeSelect : function() {
|
|
4201 if (this.cfg.getProperty(DEF_CFG.MULTI_SELECT.key) === false) {
|
|
4202 if (this.parent) {
|
|
4203 this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
|
|
4204 this.parent.deselectAll();
|
|
4205 } else {
|
|
4206 this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
|
|
4207 this.deselectAll();
|
|
4208 }
|
|
4209 }
|
|
4210 },
|
|
4211
|
|
4212 /**
|
|
4213 * Event executed when a date is selected in the calendar widget.
|
|
4214 * @param {Array} selected An array of date field arrays representing which date or dates were selected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
|
|
4215 * @deprecated Event handlers for this event should be susbcribed to selectEvent.
|
|
4216 */
|
|
4217 onSelect : function(selected) { },
|
|
4218
|
|
4219 /**
|
|
4220 * Event executed before a date is deselected in the calendar widget.
|
|
4221 * @deprecated Event handlers for this event should be susbcribed to beforeDeselectEvent.
|
|
4222 */
|
|
4223 onBeforeDeselect : function() { },
|
|
4224
|
|
4225 /**
|
|
4226 * Event executed when a date is deselected in the calendar widget.
|
|
4227 * @param {Array} selected An array of date field arrays representing which date or dates were deselected. Example: [ [2006,8,6],[2006,8,7],[2006,8,8] ]
|
|
4228 * @deprecated Event handlers for this event should be susbcribed to deselectEvent.
|
|
4229 */
|
|
4230 onDeselect : function(deselected) { },
|
|
4231
|
|
4232 /**
|
|
4233 * Event executed when the user navigates to a different calendar page.
|
|
4234 * @deprecated Event handlers for this event should be susbcribed to changePageEvent.
|
|
4235 */
|
|
4236 onChangePage : function() {
|
|
4237 this.render();
|
|
4238 },
|
|
4239
|
|
4240 /**
|
|
4241 * Event executed when the calendar widget is rendered.
|
|
4242 * @deprecated Event handlers for this event should be susbcribed to renderEvent.
|
|
4243 */
|
|
4244 onRender : function() { },
|
|
4245
|
|
4246 /**
|
|
4247 * Event executed when the calendar widget is reset to its original state.
|
|
4248 * @deprecated Event handlers for this event should be susbcribed to resetEvemt.
|
|
4249 */
|
|
4250 onReset : function() { this.render(); },
|
|
4251
|
|
4252 /**
|
|
4253 * Event executed when the calendar widget is completely cleared to the current month with no selections.
|
|
4254 * @deprecated Event handlers for this event should be susbcribed to clearEvent.
|
|
4255 */
|
|
4256 onClear : function() { this.render(); },
|
|
4257
|
|
4258 /**
|
|
4259 * Validates the calendar widget. This method has no default implementation
|
|
4260 * and must be extended by subclassing the widget.
|
|
4261 * @return Should return true if the widget validates, and false if
|
|
4262 * it doesn't.
|
|
4263 * @type Boolean
|
|
4264 */
|
|
4265 validate : function() { return true; },
|
|
4266
|
|
4267 // END EVENT HANDLERS
|
|
4268
|
|
4269 // BEGIN DATE PARSE METHODS
|
|
4270
|
|
4271 /**
|
|
4272 * Converts a date string to a date field array
|
|
4273 * @private
|
|
4274 * @param {String} sDate Date string. Valid formats are mm/dd and mm/dd/yyyy.
|
|
4275 * @return A date field array representing the string passed to the method
|
|
4276 * @type Array[](Number[])
|
|
4277 */
|
|
4278 _parseDate : function(sDate) {
|
|
4279 var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER),
|
|
4280 rArray;
|
|
4281
|
|
4282 if (aDate.length == 2) {
|
|
4283 rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
|
|
4284 rArray.type = Calendar.MONTH_DAY;
|
|
4285 } else {
|
|
4286 rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1] - this.Locale.YEAR_OFFSET, aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
|
|
4287 rArray.type = Calendar.DATE;
|
|
4288 }
|
|
4289
|
|
4290 for (var i=0;i<rArray.length;i++) {
|
|
4291 rArray[i] = parseInt(rArray[i], 10);
|
|
4292 }
|
|
4293
|
|
4294 return rArray;
|
|
4295 },
|
|
4296
|
|
4297 /**
|
|
4298 * Converts a multi or single-date string to an array of date field arrays
|
|
4299 * @private
|
|
4300 * @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
|
|
4301 * @return An array of date field arrays
|
|
4302 * @type Array[](Number[])
|
|
4303 */
|
|
4304 _parseDates : function(sDates) {
|
|
4305 var aReturn = [],
|
|
4306 aDates = sDates.split(this.Locale.DATE_DELIMITER);
|
|
4307
|
|
4308 for (var d=0;d<aDates.length;++d) {
|
|
4309 var sDate = aDates[d];
|
|
4310
|
|
4311 if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
|
|
4312 // This is a range
|
|
4313 var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER),
|
|
4314 dateStart = this._parseDate(aRange[0]),
|
|
4315 dateEnd = this._parseDate(aRange[1]),
|
|
4316 fullRange = this._parseRange(dateStart, dateEnd);
|
|
4317
|
|
4318 aReturn = aReturn.concat(fullRange);
|
|
4319 } else {
|
|
4320 // This is not a range
|
|
4321 var aDate = this._parseDate(sDate);
|
|
4322 aReturn.push(aDate);
|
|
4323 }
|
|
4324 }
|
|
4325 return aReturn;
|
|
4326 },
|
|
4327
|
|
4328 /**
|
|
4329 * Converts a date range to the full list of included dates
|
|
4330 * @private
|
|
4331 * @param {Number[]} startDate Date field array representing the first date in the range
|
|
4332 * @param {Number[]} endDate Date field array representing the last date in the range
|
|
4333 * @return An array of date field arrays
|
|
4334 * @type Array[](Number[])
|
|
4335 */
|
|
4336 _parseRange : function(startDate, endDate) {
|
|
4337 var dCurrent = DateMath.add(DateMath.getDate(startDate[0],startDate[1]-1,startDate[2]),DateMath.DAY,1),
|
|
4338 dEnd = DateMath.getDate(endDate[0], endDate[1]-1, endDate[2]),
|
|
4339 results = [];
|
|
4340
|
|
4341 results.push(startDate);
|
|
4342 while (dCurrent.getTime() <= dEnd.getTime()) {
|
|
4343 results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
|
|
4344 dCurrent = DateMath.add(dCurrent,DateMath.DAY,1);
|
|
4345 }
|
|
4346 return results;
|
|
4347 },
|
|
4348
|
|
4349 // END DATE PARSE METHODS
|
|
4350
|
|
4351 // BEGIN RENDERER METHODS
|
|
4352
|
|
4353 /**
|
|
4354 * Resets the render stack of the current calendar to its original pre-render value.
|
|
4355 */
|
|
4356 resetRenderers : function() {
|
|
4357 this.renderStack = this._renderStack.concat();
|
|
4358 },
|
|
4359
|
|
4360 /**
|
|
4361 * Removes all custom renderers added to the Calendar through the addRenderer, addMonthRenderer and
|
|
4362 * addWeekdayRenderer methods. Calendar's render method needs to be called after removing renderers
|
|
4363 * to re-render the Calendar without custom renderers applied.
|
|
4364 */
|
|
4365 removeRenderers : function() {
|
|
4366 this._renderStack = [];
|
|
4367 this.renderStack = [];
|
|
4368 },
|
|
4369
|
|
4370 /**
|
|
4371 * Clears the inner HTML, CSS class and style information from the specified cell.
|
|
4372 * @method clearElement
|
|
4373 * @param {HTMLTableCellElement} cell The cell to clear
|
|
4374 */
|
|
4375 clearElement : function(cell) {
|
|
4376 cell.innerHTML = " ";
|
|
4377 cell.className="";
|
|
4378 },
|
|
4379
|
|
4380 /**
|
|
4381 * Adds a renderer to the render stack. The function reference passed to this method will be executed
|
|
4382 * when a date cell matches the conditions specified in the date string for this renderer.
|
|
4383 * @method addRenderer
|
|
4384 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
|
|
4385 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
|
|
4386 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
4387 */
|
|
4388 addRenderer : function(sDates, fnRender) {
|
|
4389 var aDates = this._parseDates(sDates);
|
|
4390 for (var i=0;i<aDates.length;++i) {
|
|
4391 var aDate = aDates[i];
|
|
4392
|
|
4393 if (aDate.length == 2) { // this is either a range or a month/day combo
|
|
4394 if (aDate[0] instanceof Array) { // this is a range
|
|
4395 this._addRenderer(Calendar.RANGE,aDate,fnRender);
|
|
4396 } else { // this is a month/day combo
|
|
4397 this._addRenderer(Calendar.MONTH_DAY,aDate,fnRender);
|
|
4398 }
|
|
4399 } else if (aDate.length == 3) {
|
|
4400 this._addRenderer(Calendar.DATE,aDate,fnRender);
|
|
4401 }
|
|
4402 }
|
|
4403 },
|
|
4404
|
|
4405 /**
|
|
4406 * The private method used for adding cell renderers to the local render stack.
|
|
4407 * This method is called by other methods that set the renderer type prior to the method call.
|
|
4408 * @method _addRenderer
|
|
4409 * @private
|
|
4410 * @param {String} type The type string that indicates the type of date renderer being added.
|
|
4411 * Values are YAHOO.widget.Calendar.DATE, YAHOO.widget.Calendar.MONTH_DAY, YAHOO.widget.Calendar.WEEKDAY,
|
|
4412 * YAHOO.widget.Calendar.RANGE, YAHOO.widget.Calendar.MONTH
|
|
4413 * @param {Array} aDates An array of dates used to construct the renderer. The format varies based
|
|
4414 * on the renderer type
|
|
4415 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
4416 */
|
|
4417 _addRenderer : function(type, aDates, fnRender) {
|
|
4418 var add = [type,aDates,fnRender];
|
|
4419 this.renderStack.unshift(add);
|
|
4420 this._renderStack = this.renderStack.concat();
|
|
4421 },
|
|
4422
|
|
4423 /**
|
|
4424 * Adds a month to the render stack. The function reference passed to this method will be executed
|
|
4425 * when a date cell matches the month passed to this method.
|
|
4426 * @method addMonthRenderer
|
|
4427 * @param {Number} month The month (1-12) to associate with this renderer
|
|
4428 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
4429 */
|
|
4430 addMonthRenderer : function(month, fnRender) {
|
|
4431 this._addRenderer(Calendar.MONTH,[month],fnRender);
|
|
4432 },
|
|
4433
|
|
4434 /**
|
|
4435 * Adds a weekday to the render stack. The function reference passed to this method will be executed
|
|
4436 * when a date cell matches the weekday passed to this method.
|
|
4437 * @method addWeekdayRenderer
|
|
4438 * @param {Number} weekday The weekday (Sunday = 1, Monday = 2 ... Saturday = 7) to associate with this renderer
|
|
4439 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
4440 */
|
|
4441 addWeekdayRenderer : function(weekday, fnRender) {
|
|
4442 this._addRenderer(Calendar.WEEKDAY,[weekday],fnRender);
|
|
4443 },
|
|
4444
|
|
4445 // END RENDERER METHODS
|
|
4446
|
|
4447 // BEGIN CSS METHODS
|
|
4448
|
|
4449 /**
|
|
4450 * Removes all styles from all body cells in the current calendar table.
|
|
4451 * @method clearAllBodyCellStyles
|
|
4452 * @param {style} style The CSS class name to remove from all calendar body cells
|
|
4453 */
|
|
4454 clearAllBodyCellStyles : function(style) {
|
|
4455 for (var c=0;c<this.cells.length;++c) {
|
|
4456 Dom.removeClass(this.cells[c],style);
|
|
4457 }
|
|
4458 },
|
|
4459
|
|
4460 // END CSS METHODS
|
|
4461
|
|
4462 // BEGIN GETTER/SETTER METHODS
|
|
4463 /**
|
|
4464 * Sets the calendar's month explicitly
|
|
4465 * @method setMonth
|
|
4466 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
|
|
4467 */
|
|
4468 setMonth : function(month) {
|
|
4469 var cfgPageDate = DEF_CFG.PAGEDATE.key,
|
|
4470 current = this.cfg.getProperty(cfgPageDate);
|
|
4471 current.setMonth(parseInt(month, 10));
|
|
4472 this.cfg.setProperty(cfgPageDate, current);
|
|
4473 },
|
|
4474
|
|
4475 /**
|
|
4476 * Sets the calendar's year explicitly.
|
|
4477 * @method setYear
|
|
4478 * @param {Number} year The numeric 4-digit year
|
|
4479 */
|
|
4480 setYear : function(year) {
|
|
4481 var cfgPageDate = DEF_CFG.PAGEDATE.key,
|
|
4482 current = this.cfg.getProperty(cfgPageDate);
|
|
4483
|
|
4484 current.setFullYear(parseInt(year, 10) - this.Locale.YEAR_OFFSET);
|
|
4485 this.cfg.setProperty(cfgPageDate, current);
|
|
4486 },
|
|
4487
|
|
4488 /**
|
|
4489 * Gets the list of currently selected dates from the calendar.
|
|
4490 * @method getSelectedDates
|
|
4491 * @return {Date[]} An array of currently selected JavaScript Date objects.
|
|
4492 */
|
|
4493 getSelectedDates : function() {
|
|
4494 var returnDates = [],
|
|
4495 selected = this.cfg.getProperty(DEF_CFG.SELECTED.key);
|
|
4496
|
|
4497 for (var d=0;d<selected.length;++d) {
|
|
4498 var dateArray = selected[d];
|
|
4499
|
|
4500 var date = DateMath.getDate(dateArray[0],dateArray[1]-1,dateArray[2]);
|
|
4501 returnDates.push(date);
|
|
4502 }
|
|
4503
|
|
4504 returnDates.sort( function(a,b) { return a-b; } );
|
|
4505 return returnDates;
|
|
4506 },
|
|
4507
|
|
4508 /// END GETTER/SETTER METHODS ///
|
|
4509
|
|
4510 /**
|
|
4511 * Hides the Calendar's outer container from view.
|
|
4512 * @method hide
|
|
4513 */
|
|
4514 hide : function() {
|
|
4515 if (this.beforeHideEvent.fire()) {
|
|
4516 this.oDomContainer.style.display = "none";
|
|
4517 this.hideEvent.fire();
|
|
4518 }
|
|
4519 },
|
|
4520
|
|
4521 /**
|
|
4522 * Shows the Calendar's outer container.
|
|
4523 * @method show
|
|
4524 */
|
|
4525 show : function() {
|
|
4526 if (this.beforeShowEvent.fire()) {
|
|
4527 this.oDomContainer.style.display = "block";
|
|
4528 this.showEvent.fire();
|
|
4529 }
|
|
4530 },
|
|
4531
|
|
4532 /**
|
|
4533 * Returns a string representing the current browser.
|
|
4534 * @deprecated As of 2.3.0, environment information is available in YAHOO.env.ua
|
|
4535 * @see YAHOO.env.ua
|
|
4536 * @property browser
|
|
4537 * @type String
|
|
4538 */
|
|
4539 browser : (function() {
|
|
4540 var ua = navigator.userAgent.toLowerCase();
|
|
4541 if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
|
|
4542 return 'opera';
|
|
4543 } else if (ua.indexOf('msie 7')!=-1) { // IE7
|
|
4544 return 'ie7';
|
|
4545 } else if (ua.indexOf('msie') !=-1) { // IE
|
|
4546 return 'ie';
|
|
4547 } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
|
|
4548 return 'safari';
|
|
4549 } else if (ua.indexOf('gecko') != -1) { // Gecko
|
|
4550 return 'gecko';
|
|
4551 } else {
|
|
4552 return false;
|
|
4553 }
|
|
4554 })(),
|
|
4555 /**
|
|
4556 * Returns a string representation of the object.
|
|
4557 * @method toString
|
|
4558 * @return {String} A string representation of the Calendar object.
|
|
4559 */
|
|
4560 toString : function() {
|
|
4561 return "Calendar " + this.id;
|
|
4562 },
|
|
4563
|
|
4564 /**
|
|
4565 * Destroys the Calendar instance. The method will remove references
|
|
4566 * to HTML elements, remove any event listeners added by the Calendar,
|
|
4567 * and destroy the Config and CalendarNavigator instances it has created.
|
|
4568 *
|
|
4569 * @method destroy
|
|
4570 */
|
|
4571 destroy : function() {
|
|
4572
|
|
4573 if (this.beforeDestroyEvent.fire()) {
|
|
4574 var cal = this;
|
|
4575
|
|
4576 // Child objects
|
|
4577 if (cal.navigator) {
|
|
4578 cal.navigator.destroy();
|
|
4579 }
|
|
4580
|
|
4581 if (cal.cfg) {
|
|
4582 cal.cfg.destroy();
|
|
4583 }
|
|
4584
|
|
4585 // DOM event listeners
|
|
4586 Event.purgeElement(cal.oDomContainer, true);
|
|
4587
|
|
4588 // Generated markup/DOM - Not removing the container DIV since we didn't create it.
|
|
4589 Dom.removeClass(cal.oDomContainer, cal.Style.CSS_WITH_TITLE);
|
|
4590 Dom.removeClass(cal.oDomContainer, cal.Style.CSS_CONTAINER);
|
|
4591 Dom.removeClass(cal.oDomContainer, cal.Style.CSS_SINGLE);
|
|
4592 cal.oDomContainer.innerHTML = "";
|
|
4593
|
|
4594 // JS-to-DOM references
|
|
4595 cal.oDomContainer = null;
|
|
4596 cal.cells = null;
|
|
4597
|
|
4598 this.destroyEvent.fire();
|
|
4599 }
|
|
4600 }
|
|
4601 };
|
|
4602
|
|
4603 YAHOO.widget.Calendar = Calendar;
|
|
4604
|
|
4605 /**
|
|
4606 * @namespace YAHOO.widget
|
|
4607 * @class Calendar_Core
|
|
4608 * @extends YAHOO.widget.Calendar
|
|
4609 * @deprecated The old Calendar_Core class is no longer necessary.
|
|
4610 */
|
|
4611 YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;
|
|
4612
|
|
4613 YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;
|
|
4614
|
|
4615 })();
|
|
4616 (function() {
|
|
4617
|
|
4618 var Dom = YAHOO.util.Dom,
|
|
4619 DateMath = YAHOO.widget.DateMath,
|
|
4620 Event = YAHOO.util.Event,
|
|
4621 Lang = YAHOO.lang,
|
|
4622 Calendar = YAHOO.widget.Calendar;
|
|
4623
|
|
4624 /**
|
|
4625 * YAHOO.widget.CalendarGroup is a special container class for YAHOO.widget.Calendar. This class facilitates
|
|
4626 * the ability to have multi-page calendar views that share a single dataset and are
|
|
4627 * dependent on each other.
|
|
4628 *
|
|
4629 * The calendar group instance will refer to each of its elements using a 0-based index.
|
|
4630 * For example, to construct the placeholder for a calendar group widget with id "cal1" and
|
|
4631 * containerId of "cal1Container", the markup would be as follows:
|
|
4632 * <xmp>
|
|
4633 * <div id="cal1Container_0"></div>
|
|
4634 * <div id="cal1Container_1"></div>
|
|
4635 * </xmp>
|
|
4636 * The tables for the calendars ("cal1_0" and "cal1_1") will be inserted into those containers.
|
|
4637 *
|
|
4638 * <p>
|
|
4639 * <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
|
|
4640 * The CalendarGroup can be constructed by simply providing a container ID string,
|
|
4641 * or a reference to a container DIV HTMLElement (the element needs to exist
|
|
4642 * in the document).
|
|
4643 *
|
|
4644 * E.g.:
|
|
4645 * <xmp>
|
|
4646 * var c = new YAHOO.widget.CalendarGroup("calContainer", configOptions);
|
|
4647 * </xmp>
|
|
4648 * or:
|
|
4649 * <xmp>
|
|
4650 * var containerDiv = YAHOO.util.Dom.get("calContainer");
|
|
4651 * var c = new YAHOO.widget.CalendarGroup(containerDiv, configOptions);
|
|
4652 * </xmp>
|
|
4653 * </p>
|
|
4654 * <p>
|
|
4655 * If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
|
|
4656 * For example if an ID is not provided, and the container's ID is "calContainer", the CalendarGroup's ID will be set to "calContainer_t".
|
|
4657 * </p>
|
|
4658 *
|
|
4659 * @namespace YAHOO.widget
|
|
4660 * @class CalendarGroup
|
|
4661 * @constructor
|
|
4662 * @param {String} id optional The id of the table element that will represent the CalendarGroup widget. As of 2.4.0, this argument is optional.
|
|
4663 * @param {String | HTMLElement} container The id of the container div element that will wrap the CalendarGroup table, or a reference to a DIV element which exists in the document.
|
|
4664 * @param {Object} config optional The configuration object containing the initial configuration values for the CalendarGroup.
|
|
4665 */
|
|
4666 function CalendarGroup(id, containerId, config) {
|
|
4667 if (arguments.length > 0) {
|
|
4668 this.init.apply(this, arguments);
|
|
4669 }
|
|
4670 }
|
|
4671
|
|
4672 /**
|
|
4673 * The set of default Config property keys and values for the CalendarGroup.
|
|
4674 *
|
|
4675 * <p>
|
|
4676 * NOTE: This property is made public in order to allow users to change
|
|
4677 * the default values of configuration properties. Users should not
|
|
4678 * modify the key string, unless they are overriding the Calendar implementation
|
|
4679 * </p>
|
|
4680 *
|
|
4681 * @property YAHOO.widget.CalendarGroup.DEFAULT_CONFIG
|
|
4682 * @static
|
|
4683 * @type Object An object with key/value pairs, the key being the
|
|
4684 * uppercase configuration property name and the value being an objec
|
|
4685 * literal with a key string property, and a value property, specifying the
|
|
4686 * default value of the property
|
|
4687 */
|
|
4688
|
|
4689 /**
|
|
4690 * The set of default Config property keys and values for the CalendarGroup
|
|
4691 * @property YAHOO.widget.CalendarGroup._DEFAULT_CONFIG
|
|
4692 * @deprecated Made public. See the public DEFAULT_CONFIG property for details
|
|
4693 * @private
|
|
4694 * @static
|
|
4695 * @type Object
|
|
4696 */
|
|
4697 CalendarGroup.DEFAULT_CONFIG = CalendarGroup._DEFAULT_CONFIG = Calendar.DEFAULT_CONFIG;
|
|
4698 CalendarGroup.DEFAULT_CONFIG.PAGES = {key:"pages", value:2};
|
|
4699
|
|
4700 var DEF_CFG = CalendarGroup.DEFAULT_CONFIG;
|
|
4701
|
|
4702 CalendarGroup.prototype = {
|
|
4703
|
|
4704 /**
|
|
4705 * Initializes the calendar group. All subclasses must call this method in order for the
|
|
4706 * group to be initialized properly.
|
|
4707 * @method init
|
|
4708 * @param {String} id optional The id of the table element that will represent the CalendarGroup widget. As of 2.4.0, this argument is optional.
|
|
4709 * @param {String | HTMLElement} container The id of the container div element that will wrap the CalendarGroup table, or a reference to a DIV element which exists in the document.
|
|
4710 * @param {Object} config optional The configuration object containing the initial configuration values for the CalendarGroup.
|
|
4711 */
|
|
4712 init : function(id, container, config) {
|
|
4713
|
|
4714 // Normalize 2.4.0, pre 2.4.0 args
|
|
4715 var nArgs = this._parseArgs(arguments);
|
|
4716
|
|
4717 id = nArgs.id;
|
|
4718 container = nArgs.container;
|
|
4719 config = nArgs.config;
|
|
4720
|
|
4721 this.oDomContainer = Dom.get(container);
|
|
4722 if (!this.oDomContainer) { this.logger.log("Container not found in document.", "error"); }
|
|
4723
|
|
4724 if (!this.oDomContainer.id) {
|
|
4725 this.oDomContainer.id = Dom.generateId();
|
|
4726 }
|
|
4727 if (!id) {
|
|
4728 id = this.oDomContainer.id + "_t";
|
|
4729 }
|
|
4730
|
|
4731 /**
|
|
4732 * The unique id associated with the CalendarGroup
|
|
4733 * @property id
|
|
4734 * @type String
|
|
4735 */
|
|
4736 this.id = id;
|
|
4737
|
|
4738 /**
|
|
4739 * The unique id associated with the CalendarGroup container
|
|
4740 * @property containerId
|
|
4741 * @type String
|
|
4742 */
|
|
4743 this.containerId = this.oDomContainer.id;
|
|
4744
|
|
4745 this.logger = new YAHOO.widget.LogWriter("CalendarGroup " + this.id);
|
|
4746 this.initEvents();
|
|
4747 this.initStyles();
|
|
4748
|
|
4749 /**
|
|
4750 * The collection of Calendar pages contained within the CalendarGroup
|
|
4751 * @property pages
|
|
4752 * @type YAHOO.widget.Calendar[]
|
|
4753 */
|
|
4754 this.pages = [];
|
|
4755
|
|
4756 Dom.addClass(this.oDomContainer, CalendarGroup.CSS_CONTAINER);
|
|
4757 Dom.addClass(this.oDomContainer, CalendarGroup.CSS_MULTI_UP);
|
|
4758
|
|
4759 /**
|
|
4760 * The Config object used to hold the configuration variables for the CalendarGroup
|
|
4761 * @property cfg
|
|
4762 * @type YAHOO.util.Config
|
|
4763 */
|
|
4764 this.cfg = new YAHOO.util.Config(this);
|
|
4765
|
|
4766 /**
|
|
4767 * The local object which contains the CalendarGroup's options
|
|
4768 * @property Options
|
|
4769 * @type Object
|
|
4770 */
|
|
4771 this.Options = {};
|
|
4772
|
|
4773 /**
|
|
4774 * The local object which contains the CalendarGroup's locale settings
|
|
4775 * @property Locale
|
|
4776 * @type Object
|
|
4777 */
|
|
4778 this.Locale = {};
|
|
4779
|
|
4780 this.setupConfig();
|
|
4781
|
|
4782 if (config) {
|
|
4783 this.cfg.applyConfig(config, true);
|
|
4784 }
|
|
4785
|
|
4786 this.cfg.fireQueue();
|
|
4787
|
|
4788 // OPERA HACK FOR MISWRAPPED FLOATS
|
|
4789 if (YAHOO.env.ua.opera){
|
|
4790 this.renderEvent.subscribe(this._fixWidth, this, true);
|
|
4791 this.showEvent.subscribe(this._fixWidth, this, true);
|
|
4792 }
|
|
4793
|
|
4794 this.logger.log("Initialized " + this.pages.length + "-page CalendarGroup", "info");
|
|
4795 },
|
|
4796
|
|
4797 setupConfig : function() {
|
|
4798
|
|
4799 var cfg = this.cfg;
|
|
4800
|
|
4801 /**
|
|
4802 * The number of pages to include in the CalendarGroup. This value can only be set once, in the CalendarGroup's constructor arguments.
|
|
4803 * @config pages
|
|
4804 * @type Number
|
|
4805 * @default 2
|
|
4806 */
|
|
4807 cfg.addProperty(DEF_CFG.PAGES.key, { value:DEF_CFG.PAGES.value, validator:cfg.checkNumber, handler:this.configPages } );
|
|
4808
|
|
4809 /**
|
|
4810 * The positive or negative year offset from the Gregorian calendar year (assuming a January 1st rollover) to
|
|
4811 * be used when displaying or parsing dates. NOTE: All JS Date objects returned by methods, or expected as input by
|
|
4812 * methods will always represent the Gregorian year, in order to maintain date/month/week values.
|
|
4813 *
|
|
4814 * @config year_offset
|
|
4815 * @type Number
|
|
4816 * @default 0
|
|
4817 */
|
|
4818 cfg.addProperty(DEF_CFG.YEAR_OFFSET.key, { value:DEF_CFG.YEAR_OFFSET.value, handler: this.delegateConfig, supercedes:DEF_CFG.YEAR_OFFSET.supercedes, suppressEvent:true } );
|
|
4819
|
|
4820 /**
|
|
4821 * The date to use to represent "Today".
|
|
4822 *
|
|
4823 * @config today
|
|
4824 * @type Date
|
|
4825 * @default Today's date
|
|
4826 */
|
|
4827 cfg.addProperty(DEF_CFG.TODAY.key, { value: new Date(DEF_CFG.TODAY.value.getTime()), supercedes:DEF_CFG.TODAY.supercedes, handler: this.configToday, suppressEvent:false } );
|
|
4828
|
|
4829 /**
|
|
4830 * The month/year representing the current visible Calendar date (mm/yyyy)
|
|
4831 * @config pagedate
|
|
4832 * @type String | Date
|
|
4833 * @default Today's date
|
|
4834 */
|
|
4835 cfg.addProperty(DEF_CFG.PAGEDATE.key, { value: DEF_CFG.PAGEDATE.value || new Date(DEF_CFG.TODAY.value.getTime()), handler:this.configPageDate } );
|
|
4836
|
|
4837 /**
|
|
4838 * The date or range of dates representing the current Calendar selection
|
|
4839 *
|
|
4840 * @config selected
|
|
4841 * @type String
|
|
4842 * @default []
|
|
4843 */
|
|
4844 cfg.addProperty(DEF_CFG.SELECTED.key, { value:[], handler:this.configSelected } );
|
|
4845
|
|
4846 /**
|
|
4847 * The title to display above the CalendarGroup's month header
|
|
4848 * @config title
|
|
4849 * @type String
|
|
4850 * @default ""
|
|
4851 */
|
|
4852 cfg.addProperty(DEF_CFG.TITLE.key, { value:DEF_CFG.TITLE.value, handler:this.configTitle } );
|
|
4853
|
|
4854 /**
|
|
4855 * Whether or not a close button should be displayed for this CalendarGroup
|
|
4856 * @config close
|
|
4857 * @type Boolean
|
|
4858 * @default false
|
|
4859 */
|
|
4860 cfg.addProperty(DEF_CFG.CLOSE.key, { value:DEF_CFG.CLOSE.value, handler:this.configClose } );
|
|
4861
|
|
4862 /**
|
|
4863 * 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.
|
|
4864 * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
|
|
4865 * enabled if required.
|
|
4866 *
|
|
4867 * @config iframe
|
|
4868 * @type Boolean
|
|
4869 * @default true for IE6 and below, false for all other browsers
|
|
4870 */
|
|
4871 cfg.addProperty(DEF_CFG.IFRAME.key, { value:DEF_CFG.IFRAME.value, handler:this.configIframe, validator:cfg.checkBoolean } );
|
|
4872
|
|
4873 /**
|
|
4874 * The minimum selectable date in the current Calendar (mm/dd/yyyy)
|
|
4875 * @config mindate
|
|
4876 * @type String | Date
|
|
4877 * @default null
|
|
4878 */
|
|
4879 cfg.addProperty(DEF_CFG.MINDATE.key, { value:DEF_CFG.MINDATE.value, handler:this.delegateConfig } );
|
|
4880
|
|
4881 /**
|
|
4882 * The maximum selectable date in the current Calendar (mm/dd/yyyy)
|
|
4883 * @config maxdate
|
|
4884 * @type String | Date
|
|
4885 * @default null
|
|
4886 */
|
|
4887 cfg.addProperty(DEF_CFG.MAXDATE.key, { value:DEF_CFG.MAXDATE.value, handler:this.delegateConfig } );
|
|
4888
|
|
4889 // Options properties
|
|
4890
|
|
4891 /**
|
|
4892 * True if the Calendar should allow multiple selections. False by default.
|
|
4893 * @config MULTI_SELECT
|
|
4894 * @type Boolean
|
|
4895 * @default false
|
|
4896 */
|
|
4897 cfg.addProperty(DEF_CFG.MULTI_SELECT.key, { value:DEF_CFG.MULTI_SELECT.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
|
|
4898
|
|
4899 /**
|
|
4900 * The weekday the week begins on. Default is 0 (Sunday).
|
|
4901 * @config START_WEEKDAY
|
|
4902 * @type number
|
|
4903 * @default 0
|
|
4904 */
|
|
4905 cfg.addProperty(DEF_CFG.START_WEEKDAY.key, { value:DEF_CFG.START_WEEKDAY.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
4906
|
|
4907 /**
|
|
4908 * True if the Calendar should show weekday labels. True by default.
|
|
4909 * @config SHOW_WEEKDAYS
|
|
4910 * @type Boolean
|
|
4911 * @default true
|
|
4912 */
|
|
4913 cfg.addProperty(DEF_CFG.SHOW_WEEKDAYS.key, { value:DEF_CFG.SHOW_WEEKDAYS.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
|
|
4914
|
|
4915 /**
|
|
4916 * True if the Calendar should show week row headers. False by default.
|
|
4917 * @config SHOW_WEEK_HEADER
|
|
4918 * @type Boolean
|
|
4919 * @default false
|
|
4920 */
|
|
4921 cfg.addProperty(DEF_CFG.SHOW_WEEK_HEADER.key,{ value:DEF_CFG.SHOW_WEEK_HEADER.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
|
|
4922
|
|
4923 /**
|
|
4924 * True if the Calendar should show week row footers. False by default.
|
|
4925 * @config SHOW_WEEK_FOOTER
|
|
4926 * @type Boolean
|
|
4927 * @default false
|
|
4928 */
|
|
4929 cfg.addProperty(DEF_CFG.SHOW_WEEK_FOOTER.key,{ value:DEF_CFG.SHOW_WEEK_FOOTER.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
|
|
4930
|
|
4931 /**
|
|
4932 * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
|
|
4933 * @config HIDE_BLANK_WEEKS
|
|
4934 * @type Boolean
|
|
4935 * @default false
|
|
4936 */
|
|
4937 cfg.addProperty(DEF_CFG.HIDE_BLANK_WEEKS.key,{ value:DEF_CFG.HIDE_BLANK_WEEKS.value, handler:this.delegateConfig, validator:cfg.checkBoolean } );
|
|
4938
|
|
4939 /**
|
|
4940 * The image that should be used for the left navigation arrow.
|
|
4941 * @config NAV_ARROW_LEFT
|
|
4942 * @type String
|
|
4943 * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
|
|
4944 * @default null
|
|
4945 */
|
|
4946 cfg.addProperty(DEF_CFG.NAV_ARROW_LEFT.key, { value:DEF_CFG.NAV_ARROW_LEFT.value, handler:this.delegateConfig } );
|
|
4947
|
|
4948 /**
|
|
4949 * The image that should be used for the right navigation arrow.
|
|
4950 * @config NAV_ARROW_RIGHT
|
|
4951 * @type String
|
|
4952 * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
|
|
4953 * @default null
|
|
4954 */
|
|
4955 cfg.addProperty(DEF_CFG.NAV_ARROW_RIGHT.key, { value:DEF_CFG.NAV_ARROW_RIGHT.value, handler:this.delegateConfig } );
|
|
4956
|
|
4957 // Locale properties
|
|
4958
|
|
4959 /**
|
|
4960 * The short month labels for the current locale.
|
|
4961 * @config MONTHS_SHORT
|
|
4962 * @type String[]
|
|
4963 * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
|
4964 */
|
|
4965 cfg.addProperty(DEF_CFG.MONTHS_SHORT.key, { value:DEF_CFG.MONTHS_SHORT.value, handler:this.delegateConfig } );
|
|
4966
|
|
4967 /**
|
|
4968 * The long month labels for the current locale.
|
|
4969 * @config MONTHS_LONG
|
|
4970 * @type String[]
|
|
4971 * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
|
4972 */
|
|
4973 cfg.addProperty(DEF_CFG.MONTHS_LONG.key, { value:DEF_CFG.MONTHS_LONG.value, handler:this.delegateConfig } );
|
|
4974
|
|
4975 /**
|
|
4976 * The 1-character weekday labels for the current locale.
|
|
4977 * @config WEEKDAYS_1CHAR
|
|
4978 * @type String[]
|
|
4979 * @default ["S", "M", "T", "W", "T", "F", "S"]
|
|
4980 */
|
|
4981 cfg.addProperty(DEF_CFG.WEEKDAYS_1CHAR.key, { value:DEF_CFG.WEEKDAYS_1CHAR.value, handler:this.delegateConfig } );
|
|
4982
|
|
4983 /**
|
|
4984 * The short weekday labels for the current locale.
|
|
4985 * @config WEEKDAYS_SHORT
|
|
4986 * @type String[]
|
|
4987 * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
|
|
4988 */
|
|
4989 cfg.addProperty(DEF_CFG.WEEKDAYS_SHORT.key, { value:DEF_CFG.WEEKDAYS_SHORT.value, handler:this.delegateConfig } );
|
|
4990
|
|
4991 /**
|
|
4992 * The medium weekday labels for the current locale.
|
|
4993 * @config WEEKDAYS_MEDIUM
|
|
4994 * @type String[]
|
|
4995 * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
|
4996 */
|
|
4997 cfg.addProperty(DEF_CFG.WEEKDAYS_MEDIUM.key, { value:DEF_CFG.WEEKDAYS_MEDIUM.value, handler:this.delegateConfig } );
|
|
4998
|
|
4999 /**
|
|
5000 * The long weekday labels for the current locale.
|
|
5001 * @config WEEKDAYS_LONG
|
|
5002 * @type String[]
|
|
5003 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
|
5004 */
|
|
5005 cfg.addProperty(DEF_CFG.WEEKDAYS_LONG.key, { value:DEF_CFG.WEEKDAYS_LONG.value, handler:this.delegateConfig } );
|
|
5006
|
|
5007 /**
|
|
5008 * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
|
|
5009 * @config LOCALE_MONTHS
|
|
5010 * @type String
|
|
5011 * @default "long"
|
|
5012 */
|
|
5013 cfg.addProperty(DEF_CFG.LOCALE_MONTHS.key, { value:DEF_CFG.LOCALE_MONTHS.value, handler:this.delegateConfig } );
|
|
5014
|
|
5015 /**
|
|
5016 * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
|
|
5017 * @config LOCALE_WEEKDAYS
|
|
5018 * @type String
|
|
5019 * @default "short"
|
|
5020 */
|
|
5021 cfg.addProperty(DEF_CFG.LOCALE_WEEKDAYS.key, { value:DEF_CFG.LOCALE_WEEKDAYS.value, handler:this.delegateConfig } );
|
|
5022
|
|
5023 /**
|
|
5024 * The value used to delimit individual dates in a date string passed to various Calendar functions.
|
|
5025 * @config DATE_DELIMITER
|
|
5026 * @type String
|
|
5027 * @default ","
|
|
5028 */
|
|
5029 cfg.addProperty(DEF_CFG.DATE_DELIMITER.key, { value:DEF_CFG.DATE_DELIMITER.value, handler:this.delegateConfig } );
|
|
5030
|
|
5031 /**
|
|
5032 * The value used to delimit date fields in a date string passed to various Calendar functions.
|
|
5033 * @config DATE_FIELD_DELIMITER
|
|
5034 * @type String
|
|
5035 * @default "/"
|
|
5036 */
|
|
5037 cfg.addProperty(DEF_CFG.DATE_FIELD_DELIMITER.key,{ value:DEF_CFG.DATE_FIELD_DELIMITER.value, handler:this.delegateConfig } );
|
|
5038
|
|
5039 /**
|
|
5040 * The value used to delimit date ranges in a date string passed to various Calendar functions.
|
|
5041 * @config DATE_RANGE_DELIMITER
|
|
5042 * @type String
|
|
5043 * @default "-"
|
|
5044 */
|
|
5045 cfg.addProperty(DEF_CFG.DATE_RANGE_DELIMITER.key,{ value:DEF_CFG.DATE_RANGE_DELIMITER.value, handler:this.delegateConfig } );
|
|
5046
|
|
5047 /**
|
|
5048 * The position of the month in a month/year date string
|
|
5049 * @config MY_MONTH_POSITION
|
|
5050 * @type Number
|
|
5051 * @default 1
|
|
5052 */
|
|
5053 cfg.addProperty(DEF_CFG.MY_MONTH_POSITION.key, { value:DEF_CFG.MY_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5054
|
|
5055 /**
|
|
5056 * The position of the year in a month/year date string
|
|
5057 * @config MY_YEAR_POSITION
|
|
5058 * @type Number
|
|
5059 * @default 2
|
|
5060 */
|
|
5061 cfg.addProperty(DEF_CFG.MY_YEAR_POSITION.key, { value:DEF_CFG.MY_YEAR_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5062
|
|
5063 /**
|
|
5064 * The position of the month in a month/day date string
|
|
5065 * @config MD_MONTH_POSITION
|
|
5066 * @type Number
|
|
5067 * @default 1
|
|
5068 */
|
|
5069 cfg.addProperty(DEF_CFG.MD_MONTH_POSITION.key, { value:DEF_CFG.MD_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5070
|
|
5071 /**
|
|
5072 * The position of the day in a month/year date string
|
|
5073 * @config MD_DAY_POSITION
|
|
5074 * @type Number
|
|
5075 * @default 2
|
|
5076 */
|
|
5077 cfg.addProperty(DEF_CFG.MD_DAY_POSITION.key, { value:DEF_CFG.MD_DAY_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5078
|
|
5079 /**
|
|
5080 * The position of the month in a month/day/year date string
|
|
5081 * @config MDY_MONTH_POSITION
|
|
5082 * @type Number
|
|
5083 * @default 1
|
|
5084 */
|
|
5085 cfg.addProperty(DEF_CFG.MDY_MONTH_POSITION.key, { value:DEF_CFG.MDY_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5086
|
|
5087 /**
|
|
5088 * The position of the day in a month/day/year date string
|
|
5089 * @config MDY_DAY_POSITION
|
|
5090 * @type Number
|
|
5091 * @default 2
|
|
5092 */
|
|
5093 cfg.addProperty(DEF_CFG.MDY_DAY_POSITION.key, { value:DEF_CFG.MDY_DAY_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5094
|
|
5095 /**
|
|
5096 * The position of the year in a month/day/year date string
|
|
5097 * @config MDY_YEAR_POSITION
|
|
5098 * @type Number
|
|
5099 * @default 3
|
|
5100 */
|
|
5101 cfg.addProperty(DEF_CFG.MDY_YEAR_POSITION.key, { value:DEF_CFG.MDY_YEAR_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5102
|
|
5103 /**
|
|
5104 * The position of the month in the month year label string used as the Calendar header
|
|
5105 * @config MY_LABEL_MONTH_POSITION
|
|
5106 * @type Number
|
|
5107 * @default 1
|
|
5108 */
|
|
5109 cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_POSITION.key, { value:DEF_CFG.MY_LABEL_MONTH_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5110
|
|
5111 /**
|
|
5112 * The position of the year in the month year label string used as the Calendar header
|
|
5113 * @config MY_LABEL_YEAR_POSITION
|
|
5114 * @type Number
|
|
5115 * @default 2
|
|
5116 */
|
|
5117 cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_POSITION.key, { value:DEF_CFG.MY_LABEL_YEAR_POSITION.value, handler:this.delegateConfig, validator:cfg.checkNumber } );
|
|
5118
|
|
5119 /**
|
|
5120 * The suffix used after the month when rendering the Calendar header
|
|
5121 * @config MY_LABEL_MONTH_SUFFIX
|
|
5122 * @type String
|
|
5123 * @default " "
|
|
5124 */
|
|
5125 cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_SUFFIX.key, { value:DEF_CFG.MY_LABEL_MONTH_SUFFIX.value, handler:this.delegateConfig } );
|
|
5126
|
|
5127 /**
|
|
5128 * The suffix used after the year when rendering the Calendar header
|
|
5129 * @config MY_LABEL_YEAR_SUFFIX
|
|
5130 * @type String
|
|
5131 * @default ""
|
|
5132 */
|
|
5133 cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_SUFFIX.key, { value:DEF_CFG.MY_LABEL_YEAR_SUFFIX.value, handler:this.delegateConfig } );
|
|
5134
|
|
5135 /**
|
|
5136 * Configuration for the Month Year Navigation UI. By default it is disabled
|
|
5137 * @config NAV
|
|
5138 * @type Object
|
|
5139 * @default null
|
|
5140 */
|
|
5141 cfg.addProperty(DEF_CFG.NAV.key, { value:DEF_CFG.NAV.value, handler:this.configNavigator } );
|
|
5142
|
|
5143 /**
|
|
5144 * The map of UI strings which the CalendarGroup UI uses.
|
|
5145 *
|
|
5146 * @config strings
|
|
5147 * @type {Object}
|
|
5148 * @default An object with the properties shown below:
|
|
5149 * <dl>
|
|
5150 * <dt>previousMonth</dt><dd><em>String</em> : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".</dd>
|
|
5151 * <dt>nextMonth</dt><dd><em>String</em> : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".</dd>
|
|
5152 * <dt>close</dt><dd><em>String</em> : The string to use for the close button label. Defaults to "Close".</dd>
|
|
5153 * </dl>
|
|
5154 */
|
|
5155 cfg.addProperty(DEF_CFG.STRINGS.key, {
|
|
5156 value:DEF_CFG.STRINGS.value,
|
|
5157 handler:this.configStrings,
|
|
5158 validator: function(val) {
|
|
5159 return Lang.isObject(val);
|
|
5160 },
|
|
5161 supercedes: DEF_CFG.STRINGS.supercedes
|
|
5162 });
|
|
5163 },
|
|
5164
|
|
5165 /**
|
|
5166 * Initializes CalendarGroup's built-in CustomEvents
|
|
5167 * @method initEvents
|
|
5168 */
|
|
5169 initEvents : function() {
|
|
5170
|
|
5171 var me = this,
|
|
5172 strEvent = "Event",
|
|
5173 CE = YAHOO.util.CustomEvent;
|
|
5174
|
|
5175 /**
|
|
5176 * Proxy subscriber to subscribe to the CalendarGroup's child Calendars' CustomEvents
|
|
5177 * @method sub
|
|
5178 * @private
|
|
5179 * @param {Function} fn The function to subscribe to this CustomEvent
|
|
5180 * @param {Object} obj The CustomEvent's scope object
|
|
5181 * @param {Boolean} bOverride Whether or not to apply scope correction
|
|
5182 */
|
|
5183 var sub = function(fn, obj, bOverride) {
|
|
5184 for (var p=0;p<me.pages.length;++p) {
|
|
5185 var cal = me.pages[p];
|
|
5186 cal[this.type + strEvent].subscribe(fn, obj, bOverride);
|
|
5187 }
|
|
5188 };
|
|
5189
|
|
5190 /**
|
|
5191 * Proxy unsubscriber to unsubscribe from the CalendarGroup's child Calendars' CustomEvents
|
|
5192 * @method unsub
|
|
5193 * @private
|
|
5194 * @param {Function} fn The function to subscribe to this CustomEvent
|
|
5195 * @param {Object} obj The CustomEvent's scope object
|
|
5196 */
|
|
5197 var unsub = function(fn, obj) {
|
|
5198 for (var p=0;p<me.pages.length;++p) {
|
|
5199 var cal = me.pages[p];
|
|
5200 cal[this.type + strEvent].unsubscribe(fn, obj);
|
|
5201 }
|
|
5202 };
|
|
5203
|
|
5204 var defEvents = Calendar._EVENT_TYPES;
|
|
5205
|
|
5206 /**
|
|
5207 * Fired before a date selection is made
|
|
5208 * @event beforeSelectEvent
|
|
5209 */
|
|
5210 me.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
|
|
5211 me.beforeSelectEvent.subscribe = sub; me.beforeSelectEvent.unsubscribe = unsub;
|
|
5212
|
|
5213 /**
|
|
5214 * Fired when a date selection is made
|
|
5215 * @event selectEvent
|
|
5216 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
|
|
5217 */
|
|
5218 me.selectEvent = new CE(defEvents.SELECT);
|
|
5219 me.selectEvent.subscribe = sub; me.selectEvent.unsubscribe = unsub;
|
|
5220
|
|
5221 /**
|
|
5222 * Fired before a date or set of dates is deselected
|
|
5223 * @event beforeDeselectEvent
|
|
5224 */
|
|
5225 me.beforeDeselectEvent = new CE(defEvents.BEFORE_DESELECT);
|
|
5226 me.beforeDeselectEvent.subscribe = sub; me.beforeDeselectEvent.unsubscribe = unsub;
|
|
5227
|
|
5228 /**
|
|
5229 * Fired when a date or set of dates has been deselected
|
|
5230 * @event deselectEvent
|
|
5231 * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
|
|
5232 */
|
|
5233 me.deselectEvent = new CE(defEvents.DESELECT);
|
|
5234 me.deselectEvent.subscribe = sub; me.deselectEvent.unsubscribe = unsub;
|
|
5235
|
|
5236 /**
|
|
5237 * Fired when the Calendar page is changed
|
|
5238 * @event changePageEvent
|
|
5239 */
|
|
5240 me.changePageEvent = new CE(defEvents.CHANGE_PAGE);
|
|
5241 me.changePageEvent.subscribe = sub; me.changePageEvent.unsubscribe = unsub;
|
|
5242
|
|
5243 /**
|
|
5244 * Fired before the Calendar is rendered
|
|
5245 * @event beforeRenderEvent
|
|
5246 */
|
|
5247 me.beforeRenderEvent = new CE(defEvents.BEFORE_RENDER);
|
|
5248 me.beforeRenderEvent.subscribe = sub; me.beforeRenderEvent.unsubscribe = unsub;
|
|
5249
|
|
5250 /**
|
|
5251 * Fired when the Calendar is rendered
|
|
5252 * @event renderEvent
|
|
5253 */
|
|
5254 me.renderEvent = new CE(defEvents.RENDER);
|
|
5255 me.renderEvent.subscribe = sub; me.renderEvent.unsubscribe = unsub;
|
|
5256
|
|
5257 /**
|
|
5258 * Fired when the Calendar is reset
|
|
5259 * @event resetEvent
|
|
5260 */
|
|
5261 me.resetEvent = new CE(defEvents.RESET);
|
|
5262 me.resetEvent.subscribe = sub; me.resetEvent.unsubscribe = unsub;
|
|
5263
|
|
5264 /**
|
|
5265 * Fired when the Calendar is cleared
|
|
5266 * @event clearEvent
|
|
5267 */
|
|
5268 me.clearEvent = new CE(defEvents.CLEAR);
|
|
5269 me.clearEvent.subscribe = sub; me.clearEvent.unsubscribe = unsub;
|
|
5270
|
|
5271 /**
|
|
5272 * Fired just before the CalendarGroup is to be shown
|
|
5273 * @event beforeShowEvent
|
|
5274 */
|
|
5275 me.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
|
|
5276
|
|
5277 /**
|
|
5278 * Fired after the CalendarGroup is shown
|
|
5279 * @event showEvent
|
|
5280 */
|
|
5281 me.showEvent = new CE(defEvents.SHOW);
|
|
5282
|
|
5283 /**
|
|
5284 * Fired just before the CalendarGroup is to be hidden
|
|
5285 * @event beforeHideEvent
|
|
5286 */
|
|
5287 me.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
|
|
5288
|
|
5289 /**
|
|
5290 * Fired after the CalendarGroup is hidden
|
|
5291 * @event hideEvent
|
|
5292 */
|
|
5293 me.hideEvent = new CE(defEvents.HIDE);
|
|
5294
|
|
5295 /**
|
|
5296 * Fired just before the CalendarNavigator is to be shown
|
|
5297 * @event beforeShowNavEvent
|
|
5298 */
|
|
5299 me.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
|
|
5300
|
|
5301 /**
|
|
5302 * Fired after the CalendarNavigator is shown
|
|
5303 * @event showNavEvent
|
|
5304 */
|
|
5305 me.showNavEvent = new CE(defEvents.SHOW_NAV);
|
|
5306
|
|
5307 /**
|
|
5308 * Fired just before the CalendarNavigator is to be hidden
|
|
5309 * @event beforeHideNavEvent
|
|
5310 */
|
|
5311 me.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
|
|
5312
|
|
5313 /**
|
|
5314 * Fired after the CalendarNavigator is hidden
|
|
5315 * @event hideNavEvent
|
|
5316 */
|
|
5317 me.hideNavEvent = new CE(defEvents.HIDE_NAV);
|
|
5318
|
|
5319 /**
|
|
5320 * Fired just before the CalendarNavigator is to be rendered
|
|
5321 * @event beforeRenderNavEvent
|
|
5322 */
|
|
5323 me.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
|
|
5324
|
|
5325 /**
|
|
5326 * Fired after the CalendarNavigator is rendered
|
|
5327 * @event renderNavEvent
|
|
5328 */
|
|
5329 me.renderNavEvent = new CE(defEvents.RENDER_NAV);
|
|
5330
|
|
5331 /**
|
|
5332 * Fired just before the CalendarGroup is to be destroyed
|
|
5333 * @event beforeDestroyEvent
|
|
5334 */
|
|
5335 me.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
|
|
5336
|
|
5337 /**
|
|
5338 * Fired after the CalendarGroup is destroyed. This event should be used
|
|
5339 * for notification only. When this event is fired, important CalendarGroup instance
|
|
5340 * properties, dom references and event listeners have already been
|
|
5341 * removed/dereferenced, and hence the CalendarGroup instance is not in a usable
|
|
5342 * state.
|
|
5343 *
|
|
5344 * @event destroyEvent
|
|
5345 */
|
|
5346 me.destroyEvent = new CE(defEvents.DESTROY);
|
|
5347 },
|
|
5348
|
|
5349 /**
|
|
5350 * The default Config handler for the "pages" property
|
|
5351 * @method configPages
|
|
5352 * @param {String} type The CustomEvent type (usually the property name)
|
|
5353 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
|
|
5354 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
|
|
5355 */
|
|
5356 configPages : function(type, args, obj) {
|
|
5357 var pageCount = args[0],
|
|
5358 cfgPageDate = DEF_CFG.PAGEDATE.key,
|
|
5359 sep = "_",
|
|
5360 caldate,
|
|
5361 firstPageDate = null,
|
|
5362 groupCalClass = "groupcal",
|
|
5363 firstClass = "first-of-type",
|
|
5364 lastClass = "last-of-type";
|
|
5365
|
|
5366 for (var p=0;p<pageCount;++p) {
|
|
5367 var calId = this.id + sep + p,
|
|
5368 calContainerId = this.containerId + sep + p,
|
|
5369 childConfig = this.cfg.getConfig();
|
|
5370
|
|
5371 childConfig.close = false;
|
|
5372 childConfig.title = false;
|
|
5373 childConfig.navigator = null;
|
|
5374
|
|
5375 if (p > 0) {
|
|
5376 caldate = new Date(firstPageDate);
|
|
5377 this._setMonthOnDate(caldate, caldate.getMonth() + p);
|
|
5378 childConfig.pageDate = caldate;
|
|
5379 }
|
|
5380
|
|
5381 var cal = this.constructChild(calId, calContainerId, childConfig);
|
|
5382
|
|
5383 Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
|
|
5384 Dom.addClass(cal.oDomContainer, groupCalClass);
|
|
5385
|
|
5386 if (p===0) {
|
|
5387 firstPageDate = cal.cfg.getProperty(cfgPageDate);
|
|
5388 Dom.addClass(cal.oDomContainer, firstClass);
|
|
5389 }
|
|
5390
|
|
5391 if (p==(pageCount-1)) {
|
|
5392 Dom.addClass(cal.oDomContainer, lastClass);
|
|
5393 }
|
|
5394
|
|
5395 cal.parent = this;
|
|
5396 cal.index = p;
|
|
5397
|
|
5398 this.pages[this.pages.length] = cal;
|
|
5399 }
|
|
5400 },
|
|
5401
|
|
5402 /**
|
|
5403 * The default Config handler for the "pagedate" property
|
|
5404 * @method configPageDate
|
|
5405 * @param {String} type The CustomEvent type (usually the property name)
|
|
5406 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
|
|
5407 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
|
|
5408 */
|
|
5409 configPageDate : function(type, args, obj) {
|
|
5410 var val = args[0],
|
|
5411 firstPageDate;
|
|
5412
|
|
5413 var cfgPageDate = DEF_CFG.PAGEDATE.key;
|
|
5414
|
|
5415 for (var p=0;p<this.pages.length;++p) {
|
|
5416 var cal = this.pages[p];
|
|
5417 if (p === 0) {
|
|
5418 firstPageDate = cal._parsePageDate(val);
|
|
5419 cal.cfg.setProperty(cfgPageDate, firstPageDate);
|
|
5420 } else {
|
|
5421 var pageDate = new Date(firstPageDate);
|
|
5422 this._setMonthOnDate(pageDate, pageDate.getMonth() + p);
|
|
5423 cal.cfg.setProperty(cfgPageDate, pageDate);
|
|
5424 }
|
|
5425 }
|
|
5426 },
|
|
5427
|
|
5428 /**
|
|
5429 * The default Config handler for the CalendarGroup "selected" property
|
|
5430 * @method configSelected
|
|
5431 * @param {String} type The CustomEvent type (usually the property name)
|
|
5432 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
|
|
5433 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
|
|
5434 */
|
|
5435 configSelected : function(type, args, obj) {
|
|
5436 var cfgSelected = DEF_CFG.SELECTED.key;
|
|
5437 this.delegateConfig(type, args, obj);
|
|
5438 var selected = (this.pages.length > 0) ? this.pages[0].cfg.getProperty(cfgSelected) : [];
|
|
5439 this.cfg.setProperty(cfgSelected, selected, true);
|
|
5440 },
|
|
5441
|
|
5442
|
|
5443 /**
|
|
5444 * Delegates a configuration property to the CustomEvents associated with the CalendarGroup's children
|
|
5445 * @method delegateConfig
|
|
5446 * @param {String} type The CustomEvent type (usually the property name)
|
|
5447 * @param {Object[]} args The CustomEvent arguments. For configuration handlers, args[0] will equal the newly applied value for the property.
|
|
5448 * @param {Object} obj The scope object. For configuration handlers, this will usually equal the owner.
|
|
5449 */
|
|
5450 delegateConfig : function(type, args, obj) {
|
|
5451 var val = args[0];
|
|
5452 var cal;
|
|
5453
|
|
5454 for (var p=0;p<this.pages.length;p++) {
|
|
5455 cal = this.pages[p];
|
|
5456 cal.cfg.setProperty(type, val);
|
|
5457 }
|
|
5458 },
|
|
5459
|
|
5460 /**
|
|
5461 * Adds a function to all child Calendars within this CalendarGroup.
|
|
5462 * @method setChildFunction
|
|
5463 * @param {String} fnName The name of the function
|
|
5464 * @param {Function} fn The function to apply to each Calendar page object
|
|
5465 */
|
|
5466 setChildFunction : function(fnName, fn) {
|
|
5467 var pageCount = this.cfg.getProperty(DEF_CFG.PAGES.key);
|
|
5468
|
|
5469 for (var p=0;p<pageCount;++p) {
|
|
5470 this.pages[p][fnName] = fn;
|
|
5471 }
|
|
5472 },
|
|
5473
|
|
5474 /**
|
|
5475 * Calls a function within all child Calendars within this CalendarGroup.
|
|
5476 * @method callChildFunction
|
|
5477 * @param {String} fnName The name of the function
|
|
5478 * @param {Array} args The arguments to pass to the function
|
|
5479 */
|
|
5480 callChildFunction : function(fnName, args) {
|
|
5481 var pageCount = this.cfg.getProperty(DEF_CFG.PAGES.key);
|
|
5482
|
|
5483 for (var p=0;p<pageCount;++p) {
|
|
5484 var page = this.pages[p];
|
|
5485 if (page[fnName]) {
|
|
5486 var fn = page[fnName];
|
|
5487 fn.call(page, args);
|
|
5488 }
|
|
5489 }
|
|
5490 },
|
|
5491
|
|
5492 /**
|
|
5493 * Constructs a child calendar. This method can be overridden if a subclassed version of the default
|
|
5494 * calendar is to be used.
|
|
5495 * @method constructChild
|
|
5496 * @param {String} id The id of the table element that will represent the calendar widget
|
|
5497 * @param {String} containerId The id of the container div element that will wrap the calendar table
|
|
5498 * @param {Object} config The configuration object containing the Calendar's arguments
|
|
5499 * @return {YAHOO.widget.Calendar} The YAHOO.widget.Calendar instance that is constructed
|
|
5500 */
|
|
5501 constructChild : function(id,containerId,config) {
|
|
5502 var container = document.getElementById(containerId);
|
|
5503 if (! container) {
|
|
5504 container = document.createElement("div");
|
|
5505 container.id = containerId;
|
|
5506 this.oDomContainer.appendChild(container);
|
|
5507 }
|
|
5508 return new Calendar(id,containerId,config);
|
|
5509 },
|
|
5510
|
|
5511 /**
|
|
5512 * Sets the calendar group's month explicitly. This month will be set into the first
|
|
5513 * page of the multi-page calendar, and all other months will be iterated appropriately.
|
|
5514 * @method setMonth
|
|
5515 * @param {Number} month The numeric month, from 0 (January) to 11 (December)
|
|
5516 */
|
|
5517 setMonth : function(month) {
|
|
5518 month = parseInt(month, 10);
|
|
5519 var currYear;
|
|
5520
|
|
5521 var cfgPageDate = DEF_CFG.PAGEDATE.key;
|
|
5522
|
|
5523 for (var p=0; p<this.pages.length; ++p) {
|
|
5524 var cal = this.pages[p];
|
|
5525 var pageDate = cal.cfg.getProperty(cfgPageDate);
|
|
5526 if (p === 0) {
|
|
5527 currYear = pageDate.getFullYear();
|
|
5528 } else {
|
|
5529 pageDate.setFullYear(currYear);
|
|
5530 }
|
|
5531 this._setMonthOnDate(pageDate, month+p);
|
|
5532 cal.cfg.setProperty(cfgPageDate, pageDate);
|
|
5533 }
|
|
5534 },
|
|
5535
|
|
5536 /**
|
|
5537 * Sets the calendar group's year explicitly. This year will be set into the first
|
|
5538 * page of the multi-page calendar, and all other months will be iterated appropriately.
|
|
5539 * @method setYear
|
|
5540 * @param {Number} year The numeric 4-digit year
|
|
5541 */
|
|
5542 setYear : function(year) {
|
|
5543
|
|
5544 var cfgPageDate = DEF_CFG.PAGEDATE.key;
|
|
5545
|
|
5546 year = parseInt(year, 10);
|
|
5547 for (var p=0;p<this.pages.length;++p) {
|
|
5548 var cal = this.pages[p];
|
|
5549 var pageDate = cal.cfg.getProperty(cfgPageDate);
|
|
5550
|
|
5551 if ((pageDate.getMonth()+1) == 1 && p>0) {
|
|
5552 year+=1;
|
|
5553 }
|
|
5554 cal.setYear(year);
|
|
5555 }
|
|
5556 },
|
|
5557
|
|
5558 /**
|
|
5559 * Calls the render function of all child calendars within the group.
|
|
5560 * @method render
|
|
5561 */
|
|
5562 render : function() {
|
|
5563 this.renderHeader();
|
|
5564 for (var p=0;p<this.pages.length;++p) {
|
|
5565 var cal = this.pages[p];
|
|
5566 cal.render();
|
|
5567 }
|
|
5568 this.renderFooter();
|
|
5569 },
|
|
5570
|
|
5571 /**
|
|
5572 * Selects a date or a collection of dates on the current calendar. This method, by default,
|
|
5573 * does not call the render method explicitly. Once selection has completed, render must be
|
|
5574 * called for the changes to be reflected visually.
|
|
5575 * @method select
|
|
5576 * @param {String/Date/Date[]} date The date string of dates to select in the current calendar. Valid formats are
|
|
5577 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
|
|
5578 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
|
|
5579 * This method can also take a JavaScript Date object or an array of Date objects.
|
|
5580 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
5581 */
|
|
5582 select : function(date) {
|
|
5583 for (var p=0;p<this.pages.length;++p) {
|
|
5584 var cal = this.pages[p];
|
|
5585 cal.select(date);
|
|
5586 }
|
|
5587 return this.getSelectedDates();
|
|
5588 },
|
|
5589
|
|
5590 /**
|
|
5591 * Selects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
|
|
5592 * The value of the MULTI_SELECT Configuration attribute will determine the set of dates which get selected.
|
|
5593 * <ul>
|
|
5594 * <li>If MULTI_SELECT is false, selectCell will select the cell at the specified index for only the last displayed Calendar page.</li>
|
|
5595 * <li>If MULTI_SELECT is true, selectCell will select the cell at the specified index, on each displayed Calendar page.</li>
|
|
5596 * </ul>
|
|
5597 * @method selectCell
|
|
5598 * @param {Number} cellIndex The index of the cell to be selected.
|
|
5599 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
5600 */
|
|
5601 selectCell : function(cellIndex) {
|
|
5602 for (var p=0;p<this.pages.length;++p) {
|
|
5603 var cal = this.pages[p];
|
|
5604 cal.selectCell(cellIndex);
|
|
5605 }
|
|
5606 return this.getSelectedDates();
|
|
5607 },
|
|
5608
|
|
5609 /**
|
|
5610 * Deselects a date or a collection of dates on the current calendar. This method, by default,
|
|
5611 * does not call the render method explicitly. Once deselection has completed, render must be
|
|
5612 * called for the changes to be reflected visually.
|
|
5613 * @method deselect
|
|
5614 * @param {String/Date/Date[]} date The date string of dates to deselect in the current calendar. Valid formats are
|
|
5615 * individual date(s) (12/24/2005,12/26/2005) or date range(s) (12/24/2005-1/1/2006).
|
|
5616 * Multiple comma-delimited dates can also be passed to this method (12/24/2005,12/11/2005-12/13/2005).
|
|
5617 * This method can also take a JavaScript Date object or an array of Date objects.
|
|
5618 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
5619 */
|
|
5620 deselect : function(date) {
|
|
5621 for (var p=0;p<this.pages.length;++p) {
|
|
5622 var cal = this.pages[p];
|
|
5623 cal.deselect(date);
|
|
5624 }
|
|
5625 return this.getSelectedDates();
|
|
5626 },
|
|
5627
|
|
5628 /**
|
|
5629 * Deselects all dates on the current calendar.
|
|
5630 * @method deselectAll
|
|
5631 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
5632 * Assuming that this function executes properly, the return value should be an empty array.
|
|
5633 * However, the empty array is returned for the sake of being able to check the selection status
|
|
5634 * of the calendar.
|
|
5635 */
|
|
5636 deselectAll : function() {
|
|
5637 for (var p=0;p<this.pages.length;++p) {
|
|
5638 var cal = this.pages[p];
|
|
5639 cal.deselectAll();
|
|
5640 }
|
|
5641 return this.getSelectedDates();
|
|
5642 },
|
|
5643
|
|
5644 /**
|
|
5645 * Deselects dates in the CalendarGroup based on the cell index provided. This method is used to select cells without having to do a full render. The selected style is applied to the cells directly.
|
|
5646 * deselectCell will deselect the cell at the specified index on each displayed Calendar page.
|
|
5647 *
|
|
5648 * @method deselectCell
|
|
5649 * @param {Number} cellIndex The index of the cell to deselect.
|
|
5650 * @return {Date[]} Array of JavaScript Date objects representing all individual dates that are currently selected.
|
|
5651 */
|
|
5652 deselectCell : function(cellIndex) {
|
|
5653 for (var p=0;p<this.pages.length;++p) {
|
|
5654 var cal = this.pages[p];
|
|
5655 cal.deselectCell(cellIndex);
|
|
5656 }
|
|
5657 return this.getSelectedDates();
|
|
5658 },
|
|
5659
|
|
5660 /**
|
|
5661 * Resets the calendar widget to the originally selected month and year, and
|
|
5662 * sets the calendar to the initial selection(s).
|
|
5663 * @method reset
|
|
5664 */
|
|
5665 reset : function() {
|
|
5666 for (var p=0;p<this.pages.length;++p) {
|
|
5667 var cal = this.pages[p];
|
|
5668 cal.reset();
|
|
5669 }
|
|
5670 },
|
|
5671
|
|
5672 /**
|
|
5673 * Clears the selected dates in the current calendar widget and sets the calendar
|
|
5674 * to the current month and year.
|
|
5675 * @method clear
|
|
5676 */
|
|
5677 clear : function() {
|
|
5678 for (var p=0;p<this.pages.length;++p) {
|
|
5679 var cal = this.pages[p];
|
|
5680 cal.clear();
|
|
5681 }
|
|
5682
|
|
5683 this.cfg.setProperty(DEF_CFG.SELECTED.key, []);
|
|
5684 this.cfg.setProperty(DEF_CFG.PAGEDATE.key, new Date(this.pages[0].today.getTime()));
|
|
5685 this.render();
|
|
5686 },
|
|
5687
|
|
5688 /**
|
|
5689 * Navigates to the next month page in the calendar widget.
|
|
5690 * @method nextMonth
|
|
5691 */
|
|
5692 nextMonth : function() {
|
|
5693 for (var p=0;p<this.pages.length;++p) {
|
|
5694 var cal = this.pages[p];
|
|
5695 cal.nextMonth();
|
|
5696 }
|
|
5697 },
|
|
5698
|
|
5699 /**
|
|
5700 * Navigates to the previous month page in the calendar widget.
|
|
5701 * @method previousMonth
|
|
5702 */
|
|
5703 previousMonth : function() {
|
|
5704 for (var p=this.pages.length-1;p>=0;--p) {
|
|
5705 var cal = this.pages[p];
|
|
5706 cal.previousMonth();
|
|
5707 }
|
|
5708 },
|
|
5709
|
|
5710 /**
|
|
5711 * Navigates to the next year in the currently selected month in the calendar widget.
|
|
5712 * @method nextYear
|
|
5713 */
|
|
5714 nextYear : function() {
|
|
5715 for (var p=0;p<this.pages.length;++p) {
|
|
5716 var cal = this.pages[p];
|
|
5717 cal.nextYear();
|
|
5718 }
|
|
5719 },
|
|
5720
|
|
5721 /**
|
|
5722 * Navigates to the previous year in the currently selected month in the calendar widget.
|
|
5723 * @method previousYear
|
|
5724 */
|
|
5725 previousYear : function() {
|
|
5726 for (var p=0;p<this.pages.length;++p) {
|
|
5727 var cal = this.pages[p];
|
|
5728 cal.previousYear();
|
|
5729 }
|
|
5730 },
|
|
5731
|
|
5732 /**
|
|
5733 * Gets the list of currently selected dates from the calendar.
|
|
5734 * @return An array of currently selected JavaScript Date objects.
|
|
5735 * @type Date[]
|
|
5736 */
|
|
5737 getSelectedDates : function() {
|
|
5738 var returnDates = [];
|
|
5739 var selected = this.cfg.getProperty(DEF_CFG.SELECTED.key);
|
|
5740 for (var d=0;d<selected.length;++d) {
|
|
5741 var dateArray = selected[d];
|
|
5742
|
|
5743 var date = DateMath.getDate(dateArray[0],dateArray[1]-1,dateArray[2]);
|
|
5744 returnDates.push(date);
|
|
5745 }
|
|
5746
|
|
5747 returnDates.sort( function(a,b) { return a-b; } );
|
|
5748 return returnDates;
|
|
5749 },
|
|
5750
|
|
5751 /**
|
|
5752 * Adds a renderer to the render stack. The function reference passed to this method will be executed
|
|
5753 * when a date cell matches the conditions specified in the date string for this renderer.
|
|
5754 * @method addRenderer
|
|
5755 * @param {String} sDates A date string to associate with the specified renderer. Valid formats
|
|
5756 * include date (12/24/2005), month/day (12/24), and range (12/1/2004-1/1/2005)
|
|
5757 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
5758 */
|
|
5759 addRenderer : function(sDates, fnRender) {
|
|
5760 for (var p=0;p<this.pages.length;++p) {
|
|
5761 var cal = this.pages[p];
|
|
5762 cal.addRenderer(sDates, fnRender);
|
|
5763 }
|
|
5764 },
|
|
5765
|
|
5766 /**
|
|
5767 * Adds a month to the render stack. The function reference passed to this method will be executed
|
|
5768 * when a date cell matches the month passed to this method.
|
|
5769 * @method addMonthRenderer
|
|
5770 * @param {Number} month The month (1-12) to associate with this renderer
|
|
5771 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
5772 */
|
|
5773 addMonthRenderer : function(month, fnRender) {
|
|
5774 for (var p=0;p<this.pages.length;++p) {
|
|
5775 var cal = this.pages[p];
|
|
5776 cal.addMonthRenderer(month, fnRender);
|
|
5777 }
|
|
5778 },
|
|
5779
|
|
5780 /**
|
|
5781 * Adds a weekday to the render stack. The function reference passed to this method will be executed
|
|
5782 * when a date cell matches the weekday passed to this method.
|
|
5783 * @method addWeekdayRenderer
|
|
5784 * @param {Number} weekday The weekday (1-7) to associate with this renderer. 1=Sunday, 2=Monday etc.
|
|
5785 * @param {Function} fnRender The function executed to render cells that match the render rules for this renderer.
|
|
5786 */
|
|
5787 addWeekdayRenderer : function(weekday, fnRender) {
|
|
5788 for (var p=0;p<this.pages.length;++p) {
|
|
5789 var cal = this.pages[p];
|
|
5790 cal.addWeekdayRenderer(weekday, fnRender);
|
|
5791 }
|
|
5792 },
|
|
5793
|
|
5794 /**
|
|
5795 * Removes all custom renderers added to the CalendarGroup through the addRenderer, addMonthRenderer and
|
|
5796 * addWeekRenderer methods. CalendarGroup's render method needs to be called to after removing renderers
|
|
5797 * to see the changes applied.
|
|
5798 *
|
|
5799 * @method removeRenderers
|
|
5800 */
|
|
5801 removeRenderers : function() {
|
|
5802 this.callChildFunction("removeRenderers");
|
|
5803 },
|
|
5804
|
|
5805 /**
|
|
5806 * Renders the header for the CalendarGroup.
|
|
5807 * @method renderHeader
|
|
5808 */
|
|
5809 renderHeader : function() {
|
|
5810 // EMPTY DEFAULT IMPL
|
|
5811 },
|
|
5812
|
|
5813 /**
|
|
5814 * Renders a footer for the 2-up calendar container. By default, this method is
|
|
5815 * unimplemented.
|
|
5816 * @method renderFooter
|
|
5817 */
|
|
5818 renderFooter : function() {
|
|
5819 // EMPTY DEFAULT IMPL
|
|
5820 },
|
|
5821
|
|
5822 /**
|
|
5823 * Adds the designated number of months to the current calendar month, and sets the current
|
|
5824 * calendar page date to the new month.
|
|
5825 * @method addMonths
|
|
5826 * @param {Number} count The number of months to add to the current calendar
|
|
5827 */
|
|
5828 addMonths : function(count) {
|
|
5829 this.callChildFunction("addMonths", count);
|
|
5830 },
|
|
5831
|
|
5832 /**
|
|
5833 * Subtracts the designated number of months from the current calendar month, and sets the current
|
|
5834 * calendar page date to the new month.
|
|
5835 * @method subtractMonths
|
|
5836 * @param {Number} count The number of months to subtract from the current calendar
|
|
5837 */
|
|
5838 subtractMonths : function(count) {
|
|
5839 this.callChildFunction("subtractMonths", count);
|
|
5840 },
|
|
5841
|
|
5842 /**
|
|
5843 * Adds the designated number of years to the current calendar, and sets the current
|
|
5844 * calendar page date to the new month.
|
|
5845 * @method addYears
|
|
5846 * @param {Number} count The number of years to add to the current calendar
|
|
5847 */
|
|
5848 addYears : function(count) {
|
|
5849 this.callChildFunction("addYears", count);
|
|
5850 },
|
|
5851
|
|
5852 /**
|
|
5853 * Subtcats the designated number of years from the current calendar, and sets the current
|
|
5854 * calendar page date to the new month.
|
|
5855 * @method subtractYears
|
|
5856 * @param {Number} count The number of years to subtract from the current calendar
|
|
5857 */
|
|
5858 subtractYears : function(count) {
|
|
5859 this.callChildFunction("subtractYears", count);
|
|
5860 },
|
|
5861
|
|
5862 /**
|
|
5863 * Returns the Calendar page instance which has a pagedate (month/year) matching the given date.
|
|
5864 * Returns null if no match is found.
|
|
5865 *
|
|
5866 * @method getCalendarPage
|
|
5867 * @param {Date} date The JavaScript Date object for which a Calendar page is to be found.
|
|
5868 * @return {Calendar} The Calendar page instance representing the month to which the date
|
|
5869 * belongs.
|
|
5870 */
|
|
5871 getCalendarPage : function(date) {
|
|
5872 var cal = null;
|
|
5873 if (date) {
|
|
5874 var y = date.getFullYear(),
|
|
5875 m = date.getMonth();
|
|
5876
|
|
5877 var pages = this.pages;
|
|
5878 for (var i = 0; i < pages.length; ++i) {
|
|
5879 var pageDate = pages[i].cfg.getProperty("pagedate");
|
|
5880 if (pageDate.getFullYear() === y && pageDate.getMonth() === m) {
|
|
5881 cal = pages[i];
|
|
5882 break;
|
|
5883 }
|
|
5884 }
|
|
5885 }
|
|
5886 return cal;
|
|
5887 },
|
|
5888
|
|
5889 /**
|
|
5890 * Sets the month on a Date object, taking into account year rollover if the month is less than 0 or greater than 11.
|
|
5891 * The Date object passed in is modified. It should be cloned before passing it into this method if the original value needs to be maintained
|
|
5892 * @method _setMonthOnDate
|
|
5893 * @private
|
|
5894 * @param {Date} date The Date object on which to set the month index
|
|
5895 * @param {Number} iMonth The month index to set
|
|
5896 */
|
|
5897 _setMonthOnDate : function(date, iMonth) {
|
|
5898 // Bug in Safari 1.3, 2.0 (WebKit build < 420), Date.setMonth does not work consistently if iMonth is not 0-11
|
|
5899 if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420 && (iMonth < 0 || iMonth > 11)) {
|
|
5900 var newDate = DateMath.add(date, DateMath.MONTH, iMonth-date.getMonth());
|
|
5901 date.setTime(newDate.getTime());
|
|
5902 } else {
|
|
5903 date.setMonth(iMonth);
|
|
5904 }
|
|
5905 },
|
|
5906
|
|
5907 /**
|
|
5908 * Fixes the width of the CalendarGroup container element, to account for miswrapped floats
|
|
5909 * @method _fixWidth
|
|
5910 * @private
|
|
5911 */
|
|
5912 _fixWidth : function() {
|
|
5913 var w = 0;
|
|
5914 for (var p=0;p<this.pages.length;++p) {
|
|
5915 var cal = this.pages[p];
|
|
5916 w += cal.oDomContainer.offsetWidth;
|
|
5917 }
|
|
5918 if (w > 0) {
|
|
5919 this.oDomContainer.style.width = w + "px";
|
|
5920 }
|
|
5921 },
|
|
5922
|
|
5923 /**
|
|
5924 * Returns a string representation of the object.
|
|
5925 * @method toString
|
|
5926 * @return {String} A string representation of the CalendarGroup object.
|
|
5927 */
|
|
5928 toString : function() {
|
|
5929 return "CalendarGroup " + this.id;
|
|
5930 },
|
|
5931
|
|
5932 /**
|
|
5933 * Destroys the CalendarGroup instance. The method will remove references
|
|
5934 * to HTML elements, remove any event listeners added by the CalendarGroup.
|
|
5935 *
|
|
5936 * It will also destroy the Config and CalendarNavigator instances created by the
|
|
5937 * CalendarGroup and the individual Calendar instances created for each page.
|
|
5938 *
|
|
5939 * @method destroy
|
|
5940 */
|
|
5941 destroy : function() {
|
|
5942
|
|
5943 if (this.beforeDestroyEvent.fire()) {
|
|
5944
|
|
5945 var cal = this;
|
|
5946
|
|
5947 // Child objects
|
|
5948 if (cal.navigator) {
|
|
5949 cal.navigator.destroy();
|
|
5950 }
|
|
5951
|
|
5952 if (cal.cfg) {
|
|
5953 cal.cfg.destroy();
|
|
5954 }
|
|
5955
|
|
5956 // DOM event listeners
|
|
5957 Event.purgeElement(cal.oDomContainer, true);
|
|
5958
|
|
5959 // Generated markup/DOM - Not removing the container DIV since we didn't create it.
|
|
5960 Dom.removeClass(cal.oDomContainer, CalendarGroup.CSS_CONTAINER);
|
|
5961 Dom.removeClass(cal.oDomContainer, CalendarGroup.CSS_MULTI_UP);
|
|
5962
|
|
5963 for (var i = 0, l = cal.pages.length; i < l; i++) {
|
|
5964 cal.pages[i].destroy();
|
|
5965 cal.pages[i] = null;
|
|
5966 }
|
|
5967
|
|
5968 cal.oDomContainer.innerHTML = "";
|
|
5969
|
|
5970 // JS-to-DOM references
|
|
5971 cal.oDomContainer = null;
|
|
5972
|
|
5973 this.destroyEvent.fire();
|
|
5974 }
|
|
5975 }
|
|
5976 };
|
|
5977
|
|
5978 /**
|
|
5979 * CSS class representing the container for the calendar
|
|
5980 * @property YAHOO.widget.CalendarGroup.CSS_CONTAINER
|
|
5981 * @static
|
|
5982 * @final
|
|
5983 * @type String
|
|
5984 */
|
|
5985 CalendarGroup.CSS_CONTAINER = "yui-calcontainer";
|
|
5986
|
|
5987 /**
|
|
5988 * CSS class representing the container for the calendar
|
|
5989 * @property YAHOO.widget.CalendarGroup.CSS_MULTI_UP
|
|
5990 * @static
|
|
5991 * @final
|
|
5992 * @type String
|
|
5993 */
|
|
5994 CalendarGroup.CSS_MULTI_UP = "multi";
|
|
5995
|
|
5996 /**
|
|
5997 * CSS class representing the title for the 2-up calendar
|
|
5998 * @property YAHOO.widget.CalendarGroup.CSS_2UPTITLE
|
|
5999 * @static
|
|
6000 * @final
|
|
6001 * @type String
|
|
6002 */
|
|
6003 CalendarGroup.CSS_2UPTITLE = "title";
|
|
6004
|
|
6005 /**
|
|
6006 * CSS class representing the close icon for the 2-up calendar
|
|
6007 * @property YAHOO.widget.CalendarGroup.CSS_2UPCLOSE
|
|
6008 * @static
|
|
6009 * @final
|
|
6010 * @deprecated Along with Calendar.IMG_ROOT and NAV_ARROW_LEFT, NAV_ARROW_RIGHT configuration properties.
|
|
6011 * Calendar's <a href="YAHOO.widget.Calendar.html#Style.CSS_CLOSE">Style.CSS_CLOSE</a> property now represents the CSS class used to render the close icon
|
|
6012 * @type String
|
|
6013 */
|
|
6014 CalendarGroup.CSS_2UPCLOSE = "close-icon";
|
|
6015
|
|
6016 YAHOO.lang.augmentProto(CalendarGroup, Calendar, "buildDayLabel",
|
|
6017 "buildMonthLabel",
|
|
6018 "renderOutOfBoundsDate",
|
|
6019 "renderRowHeader",
|
|
6020 "renderRowFooter",
|
|
6021 "renderCellDefault",
|
|
6022 "styleCellDefault",
|
|
6023 "renderCellStyleHighlight1",
|
|
6024 "renderCellStyleHighlight2",
|
|
6025 "renderCellStyleHighlight3",
|
|
6026 "renderCellStyleHighlight4",
|
|
6027 "renderCellStyleToday",
|
|
6028 "renderCellStyleSelected",
|
|
6029 "renderCellNotThisMonth",
|
|
6030 "renderBodyCellRestricted",
|
|
6031 "initStyles",
|
|
6032 "configTitle",
|
|
6033 "configClose",
|
|
6034 "configIframe",
|
|
6035 "configStrings",
|
|
6036 "configToday",
|
|
6037 "configNavigator",
|
|
6038 "createTitleBar",
|
|
6039 "createCloseButton",
|
|
6040 "removeTitleBar",
|
|
6041 "removeCloseButton",
|
|
6042 "hide",
|
|
6043 "show",
|
|
6044 "toDate",
|
|
6045 "_toDate",
|
|
6046 "_parseArgs",
|
|
6047 "browser");
|
|
6048
|
|
6049 YAHOO.widget.CalGrp = CalendarGroup;
|
|
6050 YAHOO.widget.CalendarGroup = CalendarGroup;
|
|
6051
|
|
6052 /**
|
|
6053 * @class YAHOO.widget.Calendar2up
|
|
6054 * @extends YAHOO.widget.CalendarGroup
|
|
6055 * @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
|
|
6056 */
|
|
6057 YAHOO.widget.Calendar2up = function(id, containerId, config) {
|
|
6058 this.init(id, containerId, config);
|
|
6059 };
|
|
6060
|
|
6061 YAHOO.extend(YAHOO.widget.Calendar2up, CalendarGroup);
|
|
6062
|
|
6063 /**
|
|
6064 * @deprecated The old Calendar2up class is no longer necessary, since CalendarGroup renders in a 2up view by default.
|
|
6065 */
|
|
6066 YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;
|
|
6067
|
|
6068 })();
|
|
6069 /**
|
|
6070 * The CalendarNavigator is used along with a Calendar/CalendarGroup to
|
|
6071 * provide a Month/Year popup navigation control, allowing the user to navigate
|
|
6072 * to a specific month/year in the Calendar/CalendarGroup without having to
|
|
6073 * scroll through months sequentially
|
|
6074 *
|
|
6075 * @namespace YAHOO.widget
|
|
6076 * @class CalendarNavigator
|
|
6077 * @constructor
|
|
6078 * @param {Calendar|CalendarGroup} cal The instance of the Calendar or CalendarGroup to which this CalendarNavigator should be attached.
|
|
6079 */
|
|
6080 YAHOO.widget.CalendarNavigator = function(cal) {
|
|
6081 this.init(cal);
|
|
6082 };
|
|
6083
|
|
6084 (function() {
|
|
6085 // Setup static properties (inside anon fn, so that we can use shortcuts)
|
|
6086 var CN = YAHOO.widget.CalendarNavigator;
|
|
6087
|
|
6088 /**
|
|
6089 * YAHOO.widget.CalendarNavigator.CLASSES contains constants
|
|
6090 * for the class values applied to the CalendarNaviatgator's
|
|
6091 * DOM elements
|
|
6092 * @property YAHOO.widget.CalendarNavigator.CLASSES
|
|
6093 * @type Object
|
|
6094 * @static
|
|
6095 */
|
|
6096 CN.CLASSES = {
|
|
6097 /**
|
|
6098 * Class applied to the Calendar Navigator's bounding box
|
|
6099 * @property YAHOO.widget.CalendarNavigator.CLASSES.NAV
|
|
6100 * @type String
|
|
6101 * @static
|
|
6102 */
|
|
6103 NAV :"yui-cal-nav",
|
|
6104 /**
|
|
6105 * Class applied to the Calendar/CalendarGroup's bounding box to indicate
|
|
6106 * the Navigator is currently visible
|
|
6107 * @property YAHOO.widget.CalendarNavigator.CLASSES.NAV_VISIBLE
|
|
6108 * @type String
|
|
6109 * @static
|
|
6110 */
|
|
6111 NAV_VISIBLE: "yui-cal-nav-visible",
|
|
6112 /**
|
|
6113 * Class applied to the Navigator mask's bounding box
|
|
6114 * @property YAHOO.widget.CalendarNavigator.CLASSES.MASK
|
|
6115 * @type String
|
|
6116 * @static
|
|
6117 */
|
|
6118 MASK : "yui-cal-nav-mask",
|
|
6119 /**
|
|
6120 * Class applied to the year label/control bounding box
|
|
6121 * @property YAHOO.widget.CalendarNavigator.CLASSES.YEAR
|
|
6122 * @type String
|
|
6123 * @static
|
|
6124 */
|
|
6125 YEAR : "yui-cal-nav-y",
|
|
6126 /**
|
|
6127 * Class applied to the month label/control bounding box
|
|
6128 * @property YAHOO.widget.CalendarNavigator.CLASSES.MONTH
|
|
6129 * @type String
|
|
6130 * @static
|
|
6131 */
|
|
6132 MONTH : "yui-cal-nav-m",
|
|
6133 /**
|
|
6134 * Class applied to the submit/cancel button's bounding box
|
|
6135 * @property YAHOO.widget.CalendarNavigator.CLASSES.BUTTONS
|
|
6136 * @type String
|
|
6137 * @static
|
|
6138 */
|
|
6139 BUTTONS : "yui-cal-nav-b",
|
|
6140 /**
|
|
6141 * Class applied to buttons wrapping element
|
|
6142 * @property YAHOO.widget.CalendarNavigator.CLASSES.BUTTON
|
|
6143 * @type String
|
|
6144 * @static
|
|
6145 */
|
|
6146 BUTTON : "yui-cal-nav-btn",
|
|
6147 /**
|
|
6148 * Class applied to the validation error area's bounding box
|
|
6149 * @property YAHOO.widget.CalendarNavigator.CLASSES.ERROR
|
|
6150 * @type String
|
|
6151 * @static
|
|
6152 */
|
|
6153 ERROR : "yui-cal-nav-e",
|
|
6154 /**
|
|
6155 * Class applied to the year input control
|
|
6156 * @property YAHOO.widget.CalendarNavigator.CLASSES.YEAR_CTRL
|
|
6157 * @type String
|
|
6158 * @static
|
|
6159 */
|
|
6160 YEAR_CTRL : "yui-cal-nav-yc",
|
|
6161 /**
|
|
6162 * Class applied to the month input control
|
|
6163 * @property YAHOO.widget.CalendarNavigator.CLASSES.MONTH_CTRL
|
|
6164 * @type String
|
|
6165 * @static
|
|
6166 */
|
|
6167 MONTH_CTRL : "yui-cal-nav-mc",
|
|
6168 /**
|
|
6169 * Class applied to controls with invalid data (e.g. a year input field with invalid an year)
|
|
6170 * @property YAHOO.widget.CalendarNavigator.CLASSES.INVALID
|
|
6171 * @type String
|
|
6172 * @static
|
|
6173 */
|
|
6174 INVALID : "yui-invalid",
|
|
6175 /**
|
|
6176 * Class applied to default controls
|
|
6177 * @property YAHOO.widget.CalendarNavigator.CLASSES.DEFAULT
|
|
6178 * @type String
|
|
6179 * @static
|
|
6180 */
|
|
6181 DEFAULT : "yui-default"
|
|
6182 };
|
|
6183
|
|
6184 /**
|
|
6185 * Object literal containing the default configuration values for the CalendarNavigator
|
|
6186 * The configuration object is expected to follow the format below, with the properties being
|
|
6187 * case sensitive.
|
|
6188 * <dl>
|
|
6189 * <dt>strings</dt>
|
|
6190 * <dd><em>Object</em> : An object with the properties shown below, defining the string labels to use in the Navigator's UI
|
|
6191 * <dl>
|
|
6192 * <dt>month</dt><dd><em>String</em> : The string to use for the month label. Defaults to "Month".</dd>
|
|
6193 * <dt>year</dt><dd><em>String</em> : The string to use for the year label. Defaults to "Year".</dd>
|
|
6194 * <dt>submit</dt><dd><em>String</em> : The string to use for the submit button label. Defaults to "Okay".</dd>
|
|
6195 * <dt>cancel</dt><dd><em>String</em> : The string to use for the cancel button label. Defaults to "Cancel".</dd>
|
|
6196 * <dt>invalidYear</dt><dd><em>String</em> : The string to use for invalid year values. Defaults to "Year needs to be a number".</dd>
|
|
6197 * </dl>
|
|
6198 * </dd>
|
|
6199 * <dt>monthFormat</dt><dd><em>String</em> : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG</dd>
|
|
6200 * <dt>initialFocus</dt><dd><em>String</em> : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"</dd>
|
|
6201 * </dl>
|
|
6202 * @property DEFAULT_CONFIG
|
|
6203 * @type Object
|
|
6204 * @static
|
|
6205 */
|
|
6206 CN.DEFAULT_CONFIG = {
|
|
6207 strings : {
|
|
6208 month: "Month",
|
|
6209 year: "Year",
|
|
6210 submit: "Okay",
|
|
6211 cancel: "Cancel",
|
|
6212 invalidYear : "Year needs to be a number"
|
|
6213 },
|
|
6214 monthFormat: YAHOO.widget.Calendar.LONG,
|
|
6215 initialFocus: "year"
|
|
6216 };
|
|
6217
|
|
6218 /**
|
|
6219 * Object literal containing the default configuration values for the CalendarNavigator
|
|
6220 * @property _DEFAULT_CFG
|
|
6221 * @protected
|
|
6222 * @deprecated Made public. See the public DEFAULT_CONFIG property
|
|
6223 * @type Object
|
|
6224 * @static
|
|
6225 */
|
|
6226 CN._DEFAULT_CFG = CN.DEFAULT_CONFIG;
|
|
6227
|
|
6228
|
|
6229 /**
|
|
6230 * The suffix added to the Calendar/CalendarGroup's ID, to generate
|
|
6231 * a unique ID for the Navigator and it's bounding box.
|
|
6232 * @property YAHOO.widget.CalendarNavigator.ID_SUFFIX
|
|
6233 * @static
|
|
6234 * @type String
|
|
6235 * @final
|
|
6236 */
|
|
6237 CN.ID_SUFFIX = "_nav";
|
|
6238 /**
|
|
6239 * The suffix added to the Navigator's ID, to generate
|
|
6240 * a unique ID for the month control.
|
|
6241 * @property YAHOO.widget.CalendarNavigator.MONTH_SUFFIX
|
|
6242 * @static
|
|
6243 * @type String
|
|
6244 * @final
|
|
6245 */
|
|
6246 CN.MONTH_SUFFIX = "_month";
|
|
6247 /**
|
|
6248 * The suffix added to the Navigator's ID, to generate
|
|
6249 * a unique ID for the year control.
|
|
6250 * @property YAHOO.widget.CalendarNavigator.YEAR_SUFFIX
|
|
6251 * @static
|
|
6252 * @type String
|
|
6253 * @final
|
|
6254 */
|
|
6255 CN.YEAR_SUFFIX = "_year";
|
|
6256 /**
|
|
6257 * The suffix added to the Navigator's ID, to generate
|
|
6258 * a unique ID for the error bounding box.
|
|
6259 * @property YAHOO.widget.CalendarNavigator.ERROR_SUFFIX
|
|
6260 * @static
|
|
6261 * @type String
|
|
6262 * @final
|
|
6263 */
|
|
6264 CN.ERROR_SUFFIX = "_error";
|
|
6265 /**
|
|
6266 * The suffix added to the Navigator's ID, to generate
|
|
6267 * a unique ID for the "Cancel" button.
|
|
6268 * @property YAHOO.widget.CalendarNavigator.CANCEL_SUFFIX
|
|
6269 * @static
|
|
6270 * @type String
|
|
6271 * @final
|
|
6272 */
|
|
6273 CN.CANCEL_SUFFIX = "_cancel";
|
|
6274 /**
|
|
6275 * The suffix added to the Navigator's ID, to generate
|
|
6276 * a unique ID for the "Submit" button.
|
|
6277 * @property YAHOO.widget.CalendarNavigator.SUBMIT_SUFFIX
|
|
6278 * @static
|
|
6279 * @type String
|
|
6280 * @final
|
|
6281 */
|
|
6282 CN.SUBMIT_SUFFIX = "_submit";
|
|
6283
|
|
6284 /**
|
|
6285 * The number of digits to which the year input control is to be limited.
|
|
6286 * @property YAHOO.widget.CalendarNavigator.YR_MAX_DIGITS
|
|
6287 * @static
|
|
6288 * @type Number
|
|
6289 */
|
|
6290 CN.YR_MAX_DIGITS = 4;
|
|
6291
|
|
6292 /**
|
|
6293 * The amount by which to increment the current year value,
|
|
6294 * when the arrow up/down key is pressed on the year control
|
|
6295 * @property YAHOO.widget.CalendarNavigator.YR_MINOR_INC
|
|
6296 * @static
|
|
6297 * @type Number
|
|
6298 */
|
|
6299 CN.YR_MINOR_INC = 1;
|
|
6300
|
|
6301 /**
|
|
6302 * The amount by which to increment the current year value,
|
|
6303 * when the page up/down key is pressed on the year control
|
|
6304 * @property YAHOO.widget.CalendarNavigator.YR_MAJOR_INC
|
|
6305 * @static
|
|
6306 * @type Number
|
|
6307 */
|
|
6308 CN.YR_MAJOR_INC = 10;
|
|
6309
|
|
6310 /**
|
|
6311 * Artificial delay (in ms) between the time the Navigator is hidden
|
|
6312 * and the Calendar/CalendarGroup state is updated. Allows the user
|
|
6313 * the see the Calendar/CalendarGroup page changing. If set to 0
|
|
6314 * the Calendar/CalendarGroup page will be updated instantly
|
|
6315 * @property YAHOO.widget.CalendarNavigator.UPDATE_DELAY
|
|
6316 * @static
|
|
6317 * @type Number
|
|
6318 */
|
|
6319 CN.UPDATE_DELAY = 50;
|
|
6320
|
|
6321 /**
|
|
6322 * Regular expression used to validate the year input
|
|
6323 * @property YAHOO.widget.CalendarNavigator.YR_PATTERN
|
|
6324 * @static
|
|
6325 * @type RegExp
|
|
6326 */
|
|
6327 CN.YR_PATTERN = /^\d+$/;
|
|
6328 /**
|
|
6329 * Regular expression used to trim strings
|
|
6330 * @property YAHOO.widget.CalendarNavigator.TRIM
|
|
6331 * @static
|
|
6332 * @type RegExp
|
|
6333 */
|
|
6334 CN.TRIM = /^\s*(.*?)\s*$/;
|
|
6335 })();
|
|
6336
|
|
6337 YAHOO.widget.CalendarNavigator.prototype = {
|
|
6338
|
|
6339 /**
|
|
6340 * The unique ID for this CalendarNavigator instance
|
|
6341 * @property id
|
|
6342 * @type String
|
|
6343 */
|
|
6344 id : null,
|
|
6345
|
|
6346 /**
|
|
6347 * The Calendar/CalendarGroup instance to which the navigator belongs
|
|
6348 * @property cal
|
|
6349 * @type {Calendar|CalendarGroup}
|
|
6350 */
|
|
6351 cal : null,
|
|
6352
|
|
6353 /**
|
|
6354 * Reference to the HTMLElement used to render the navigator's bounding box
|
|
6355 * @property navEl
|
|
6356 * @type HTMLElement
|
|
6357 */
|
|
6358 navEl : null,
|
|
6359
|
|
6360 /**
|
|
6361 * Reference to the HTMLElement used to render the navigator's mask
|
|
6362 * @property maskEl
|
|
6363 * @type HTMLElement
|
|
6364 */
|
|
6365 maskEl : null,
|
|
6366
|
|
6367 /**
|
|
6368 * Reference to the HTMLElement used to input the year
|
|
6369 * @property yearEl
|
|
6370 * @type HTMLElement
|
|
6371 */
|
|
6372 yearEl : null,
|
|
6373
|
|
6374 /**
|
|
6375 * Reference to the HTMLElement used to input the month
|
|
6376 * @property monthEl
|
|
6377 * @type HTMLElement
|
|
6378 */
|
|
6379 monthEl : null,
|
|
6380
|
|
6381 /**
|
|
6382 * Reference to the HTMLElement used to display validation errors
|
|
6383 * @property errorEl
|
|
6384 * @type HTMLElement
|
|
6385 */
|
|
6386 errorEl : null,
|
|
6387
|
|
6388 /**
|
|
6389 * Reference to the HTMLElement used to update the Calendar/Calendar group
|
|
6390 * with the month/year values
|
|
6391 * @property submitEl
|
|
6392 * @type HTMLElement
|
|
6393 */
|
|
6394 submitEl : null,
|
|
6395
|
|
6396 /**
|
|
6397 * Reference to the HTMLElement used to hide the navigator without updating the
|
|
6398 * Calendar/Calendar group
|
|
6399 * @property cancelEl
|
|
6400 * @type HTMLElement
|
|
6401 */
|
|
6402 cancelEl : null,
|
|
6403
|
|
6404 /**
|
|
6405 * Reference to the first focusable control in the navigator (by default monthEl)
|
|
6406 * @property firstCtrl
|
|
6407 * @type HTMLElement
|
|
6408 */
|
|
6409 firstCtrl : null,
|
|
6410
|
|
6411 /**
|
|
6412 * Reference to the last focusable control in the navigator (by default cancelEl)
|
|
6413 * @property lastCtrl
|
|
6414 * @type HTMLElement
|
|
6415 */
|
|
6416 lastCtrl : null,
|
|
6417
|
|
6418 /**
|
|
6419 * The document containing the Calendar/Calendar group instance
|
|
6420 * @protected
|
|
6421 * @property _doc
|
|
6422 * @type HTMLDocument
|
|
6423 */
|
|
6424 _doc : null,
|
|
6425
|
|
6426 /**
|
|
6427 * Internal state property for the current year displayed in the navigator
|
|
6428 * @protected
|
|
6429 * @property _year
|
|
6430 * @type Number
|
|
6431 */
|
|
6432 _year: null,
|
|
6433
|
|
6434 /**
|
|
6435 * Internal state property for the current month index displayed in the navigator
|
|
6436 * @protected
|
|
6437 * @property _month
|
|
6438 * @type Number
|
|
6439 */
|
|
6440 _month: 0,
|
|
6441
|
|
6442 /**
|
|
6443 * Private internal state property which indicates whether or not the
|
|
6444 * Navigator has been rendered.
|
|
6445 * @private
|
|
6446 * @property __rendered
|
|
6447 * @type Boolean
|
|
6448 */
|
|
6449 __rendered: false,
|
|
6450
|
|
6451 /**
|
|
6452 * Init lifecycle method called as part of construction
|
|
6453 *
|
|
6454 * @method init
|
|
6455 * @param {Calendar} cal The instance of the Calendar or CalendarGroup to which this CalendarNavigator should be attached
|
|
6456 */
|
|
6457 init : function(cal) {
|
|
6458 var calBox = cal.oDomContainer;
|
|
6459
|
|
6460 this.cal = cal;
|
|
6461 this.id = calBox.id + YAHOO.widget.CalendarNavigator.ID_SUFFIX;
|
|
6462 this._doc = calBox.ownerDocument;
|
|
6463
|
|
6464 /**
|
|
6465 * Private flag, to identify IE Quirks
|
|
6466 * @private
|
|
6467 * @property __isIEQuirks
|
|
6468 */
|
|
6469 var ie = YAHOO.env.ua.ie;
|
|
6470 this.__isIEQuirks = (ie && ((ie <= 6) || (this._doc.compatMode == "BackCompat")));
|
|
6471 },
|
|
6472
|
|
6473 /**
|
|
6474 * Displays the navigator and mask, updating the input controls to reflect the
|
|
6475 * currently set month and year. The show method will invoke the render method
|
|
6476 * if the navigator has not been renderered already, allowing for lazy rendering
|
|
6477 * of the control.
|
|
6478 *
|
|
6479 * The show method will fire the Calendar/CalendarGroup's beforeShowNav and showNav events
|
|
6480 *
|
|
6481 * @method show
|
|
6482 */
|
|
6483 show : function() {
|
|
6484 var CLASSES = YAHOO.widget.CalendarNavigator.CLASSES;
|
|
6485
|
|
6486 if (this.cal.beforeShowNavEvent.fire()) {
|
|
6487 if (!this.__rendered) {
|
|
6488 this.render();
|
|
6489 }
|
|
6490 this.clearErrors();
|
|
6491
|
|
6492 this._updateMonthUI();
|
|
6493 this._updateYearUI();
|
|
6494 this._show(this.navEl, true);
|
|
6495
|
|
6496 this.setInitialFocus();
|
|
6497 this.showMask();
|
|
6498
|
|
6499 YAHOO.util.Dom.addClass(this.cal.oDomContainer, CLASSES.NAV_VISIBLE);
|
|
6500 this.cal.showNavEvent.fire();
|
|
6501 }
|
|
6502 },
|
|
6503
|
|
6504 /**
|
|
6505 * Hides the navigator and mask
|
|
6506 *
|
|
6507 * The show method will fire the Calendar/CalendarGroup's beforeHideNav event and hideNav events
|
|
6508 * @method hide
|
|
6509 */
|
|
6510 hide : function() {
|
|
6511 var CLASSES = YAHOO.widget.CalendarNavigator.CLASSES;
|
|
6512
|
|
6513 if (this.cal.beforeHideNavEvent.fire()) {
|
|
6514 this._show(this.navEl, false);
|
|
6515 this.hideMask();
|
|
6516 YAHOO.util.Dom.removeClass(this.cal.oDomContainer, CLASSES.NAV_VISIBLE);
|
|
6517 this.cal.hideNavEvent.fire();
|
|
6518 }
|
|
6519 },
|
|
6520
|
|
6521
|
|
6522 /**
|
|
6523 * Displays the navigator's mask element
|
|
6524 *
|
|
6525 * @method showMask
|
|
6526 */
|
|
6527 showMask : function() {
|
|
6528 this._show(this.maskEl, true);
|
|
6529 if (this.__isIEQuirks) {
|
|
6530 this._syncMask();
|
|
6531 }
|
|
6532 },
|
|
6533
|
|
6534 /**
|
|
6535 * Hides the navigator's mask element
|
|
6536 *
|
|
6537 * @method hideMask
|
|
6538 */
|
|
6539 hideMask : function() {
|
|
6540 this._show(this.maskEl, false);
|
|
6541 },
|
|
6542
|
|
6543 /**
|
|
6544 * Returns the current month set on the navigator
|
|
6545 *
|
|
6546 * Note: This may not be the month set in the UI, if
|
|
6547 * the UI contains an invalid value.
|
|
6548 *
|
|
6549 * @method getMonth
|
|
6550 * @return {Number} The Navigator's current month index
|
|
6551 */
|
|
6552 getMonth: function() {
|
|
6553 return this._month;
|
|
6554 },
|
|
6555
|
|
6556 /**
|
|
6557 * Returns the current year set on the navigator
|
|
6558 *
|
|
6559 * Note: This may not be the year set in the UI, if
|
|
6560 * the UI contains an invalid value.
|
|
6561 *
|
|
6562 * @method getYear
|
|
6563 * @return {Number} The Navigator's current year value
|
|
6564 */
|
|
6565 getYear: function() {
|
|
6566 return this._year;
|
|
6567 },
|
|
6568
|
|
6569 /**
|
|
6570 * Sets the current month on the Navigator, and updates the UI
|
|
6571 *
|
|
6572 * @method setMonth
|
|
6573 * @param {Number} nMonth The month index, from 0 (Jan) through 11 (Dec).
|
|
6574 */
|
|
6575 setMonth : function(nMonth) {
|
|
6576 if (nMonth >= 0 && nMonth < 12) {
|
|
6577 this._month = nMonth;
|
|
6578 }
|
|
6579 this._updateMonthUI();
|
|
6580 },
|
|
6581
|
|
6582 /**
|
|
6583 * Sets the current year on the Navigator, and updates the UI. If the
|
|
6584 * provided year is invalid, it will not be set.
|
|
6585 *
|
|
6586 * @method setYear
|
|
6587 * @param {Number} nYear The full year value to set the Navigator to.
|
|
6588 */
|
|
6589 setYear : function(nYear) {
|
|
6590 var yrPattern = YAHOO.widget.CalendarNavigator.YR_PATTERN;
|
|
6591 if (YAHOO.lang.isNumber(nYear) && yrPattern.test(nYear+"")) {
|
|
6592 this._year = nYear;
|
|
6593 }
|
|
6594 this._updateYearUI();
|
|
6595 },
|
|
6596
|
|
6597 /**
|
|
6598 * Renders the HTML for the navigator, adding it to the
|
|
6599 * document and attaches event listeners if it has not
|
|
6600 * already been rendered.
|
|
6601 *
|
|
6602 * @method render
|
|
6603 */
|
|
6604 render: function() {
|
|
6605 this.cal.beforeRenderNavEvent.fire();
|
|
6606 if (!this.__rendered) {
|
|
6607 this.createNav();
|
|
6608 this.createMask();
|
|
6609 this.applyListeners();
|
|
6610 this.__rendered = true;
|
|
6611 }
|
|
6612 this.cal.renderNavEvent.fire();
|
|
6613 },
|
|
6614
|
|
6615 /**
|
|
6616 * Creates the navigator's containing HTMLElement, it's contents, and appends
|
|
6617 * the containg element to the Calendar/CalendarGroup's container.
|
|
6618 *
|
|
6619 * @method createNav
|
|
6620 */
|
|
6621 createNav : function() {
|
|
6622 var NAV = YAHOO.widget.CalendarNavigator;
|
|
6623 var doc = this._doc;
|
|
6624
|
|
6625 var d = doc.createElement("div");
|
|
6626 d.className = NAV.CLASSES.NAV;
|
|
6627
|
|
6628 var htmlBuf = this.renderNavContents([]);
|
|
6629
|
|
6630 d.innerHTML = htmlBuf.join('');
|
|
6631 this.cal.oDomContainer.appendChild(d);
|
|
6632
|
|
6633 this.navEl = d;
|
|
6634
|
|
6635 this.yearEl = doc.getElementById(this.id + NAV.YEAR_SUFFIX);
|
|
6636 this.monthEl = doc.getElementById(this.id + NAV.MONTH_SUFFIX);
|
|
6637 this.errorEl = doc.getElementById(this.id + NAV.ERROR_SUFFIX);
|
|
6638 this.submitEl = doc.getElementById(this.id + NAV.SUBMIT_SUFFIX);
|
|
6639 this.cancelEl = doc.getElementById(this.id + NAV.CANCEL_SUFFIX);
|
|
6640
|
|
6641 if (YAHOO.env.ua.gecko && this.yearEl && this.yearEl.type == "text") {
|
|
6642 // Avoid XUL error on focus, select [ https://bugzilla.mozilla.org/show_bug.cgi?id=236791,
|
|
6643 // supposedly fixed in 1.8.1, but there are reports of it still being around for methods other than blur ]
|
|
6644 this.yearEl.setAttribute("autocomplete", "off");
|
|
6645 }
|
|
6646
|
|
6647 this._setFirstLastElements();
|
|
6648 },
|
|
6649
|
|
6650 /**
|
|
6651 * Creates the Mask HTMLElement and appends it to the Calendar/CalendarGroups
|
|
6652 * container.
|
|
6653 *
|
|
6654 * @method createMask
|
|
6655 */
|
|
6656 createMask : function() {
|
|
6657 var C = YAHOO.widget.CalendarNavigator.CLASSES;
|
|
6658
|
|
6659 var d = this._doc.createElement("div");
|
|
6660 d.className = C.MASK;
|
|
6661
|
|
6662 this.cal.oDomContainer.appendChild(d);
|
|
6663 this.maskEl = d;
|
|
6664 },
|
|
6665
|
|
6666 /**
|
|
6667 * Used to set the width/height of the mask in pixels to match the Calendar Container.
|
|
6668 * Currently only used for IE6 or IE in quirks mode. The other A-Grade browser are handled using CSS (width/height 100%).
|
|
6669 * <p>
|
|
6670 * The method is also registered as an HTMLElement resize listener on the Calendars container element.
|
|
6671 * </p>
|
|
6672 * @protected
|
|
6673 * @method _syncMask
|
|
6674 */
|
|
6675 _syncMask : function() {
|
|
6676 var c = this.cal.oDomContainer;
|
|
6677 if (c && this.maskEl) {
|
|
6678 var r = YAHOO.util.Dom.getRegion(c);
|
|
6679 YAHOO.util.Dom.setStyle(this.maskEl, "width", r.right - r.left + "px");
|
|
6680 YAHOO.util.Dom.setStyle(this.maskEl, "height", r.bottom - r.top + "px");
|
|
6681 }
|
|
6682 },
|
|
6683
|
|
6684 /**
|
|
6685 * Renders the contents of the navigator
|
|
6686 *
|
|
6687 * @method renderNavContents
|
|
6688 *
|
|
6689 * @param {Array} html The HTML buffer to append the HTML to.
|
|
6690 * @return {Array} A reference to the buffer passed in.
|
|
6691 */
|
|
6692 renderNavContents : function(html) {
|
|
6693 var NAV = YAHOO.widget.CalendarNavigator,
|
|
6694 C = NAV.CLASSES,
|
|
6695 h = html; // just to use a shorter name
|
|
6696
|
|
6697 h[h.length] = '<div class="' + C.MONTH + '">';
|
|
6698 this.renderMonth(h);
|
|
6699 h[h.length] = '</div>';
|
|
6700 h[h.length] = '<div class="' + C.YEAR + '">';
|
|
6701 this.renderYear(h);
|
|
6702 h[h.length] = '</div>';
|
|
6703 h[h.length] = '<div class="' + C.BUTTONS + '">';
|
|
6704 this.renderButtons(h);
|
|
6705 h[h.length] = '</div>';
|
|
6706 h[h.length] = '<div class="' + C.ERROR + '" id="' + this.id + NAV.ERROR_SUFFIX + '"></div>';
|
|
6707
|
|
6708 return h;
|
|
6709 },
|
|
6710
|
|
6711 /**
|
|
6712 * Renders the month label and control for the navigator
|
|
6713 *
|
|
6714 * @method renderNavContents
|
|
6715 * @param {Array} html The HTML buffer to append the HTML to.
|
|
6716 * @return {Array} A reference to the buffer passed in.
|
|
6717 */
|
|
6718 renderMonth : function(html) {
|
|
6719 var NAV = YAHOO.widget.CalendarNavigator,
|
|
6720 C = NAV.CLASSES;
|
|
6721
|
|
6722 var id = this.id + NAV.MONTH_SUFFIX,
|
|
6723 mf = this.__getCfg("monthFormat"),
|
|
6724 months = this.cal.cfg.getProperty((mf == YAHOO.widget.Calendar.SHORT) ? "MONTHS_SHORT" : "MONTHS_LONG"),
|
|
6725 h = html;
|
|
6726
|
|
6727 if (months && months.length > 0) {
|
|
6728 h[h.length] = '<label for="' + id + '">';
|
|
6729 h[h.length] = this.__getCfg("month", true);
|
|
6730 h[h.length] = '</label>';
|
|
6731 h[h.length] = '<select name="' + id + '" id="' + id + '" class="' + C.MONTH_CTRL + '">';
|
|
6732 for (var i = 0; i < months.length; i++) {
|
|
6733 h[h.length] = '<option value="' + i + '">';
|
|
6734 h[h.length] = months[i];
|
|
6735 h[h.length] = '</option>';
|
|
6736 }
|
|
6737 h[h.length] = '</select>';
|
|
6738 }
|
|
6739 return h;
|
|
6740 },
|
|
6741
|
|
6742 /**
|
|
6743 * Renders the year label and control for the navigator
|
|
6744 *
|
|
6745 * @method renderYear
|
|
6746 * @param {Array} html The HTML buffer to append the HTML to.
|
|
6747 * @return {Array} A reference to the buffer passed in.
|
|
6748 */
|
|
6749 renderYear : function(html) {
|
|
6750 var NAV = YAHOO.widget.CalendarNavigator,
|
|
6751 C = NAV.CLASSES;
|
|
6752
|
|
6753 var id = this.id + NAV.YEAR_SUFFIX,
|
|
6754 size = NAV.YR_MAX_DIGITS,
|
|
6755 h = html;
|
|
6756
|
|
6757 h[h.length] = '<label for="' + id + '">';
|
|
6758 h[h.length] = this.__getCfg("year", true);
|
|
6759 h[h.length] = '</label>';
|
|
6760 h[h.length] = '<input type="text" name="' + id + '" id="' + id + '" class="' + C.YEAR_CTRL + '" maxlength="' + size + '"/>';
|
|
6761 return h;
|
|
6762 },
|
|
6763
|
|
6764 /**
|
|
6765 * Renders the submit/cancel buttons for the navigator
|
|
6766 *
|
|
6767 * @method renderButton
|
|
6768 * @return {String} The HTML created for the Button UI
|
|
6769 */
|
|
6770 renderButtons : function(html) {
|
|
6771 var C = YAHOO.widget.CalendarNavigator.CLASSES;
|
|
6772 var h = html;
|
|
6773
|
|
6774 h[h.length] = '<span class="' + C.BUTTON + ' ' + C.DEFAULT + '">';
|
|
6775 h[h.length] = '<button type="button" id="' + this.id + '_submit' + '">';
|
|
6776 h[h.length] = this.__getCfg("submit", true);
|
|
6777 h[h.length] = '</button>';
|
|
6778 h[h.length] = '</span>';
|
|
6779 h[h.length] = '<span class="' + C.BUTTON +'">';
|
|
6780 h[h.length] = '<button type="button" id="' + this.id + '_cancel' + '">';
|
|
6781 h[h.length] = this.__getCfg("cancel", true);
|
|
6782 h[h.length] = '</button>';
|
|
6783 h[h.length] = '</span>';
|
|
6784
|
|
6785 return h;
|
|
6786 },
|
|
6787
|
|
6788 /**
|
|
6789 * Attaches DOM event listeners to the rendered elements
|
|
6790 * <p>
|
|
6791 * The method will call applyKeyListeners, to setup keyboard specific
|
|
6792 * listeners
|
|
6793 * </p>
|
|
6794 * @method applyListeners
|
|
6795 */
|
|
6796 applyListeners : function() {
|
|
6797 var E = YAHOO.util.Event;
|
|
6798
|
|
6799 function yearUpdateHandler() {
|
|
6800 if (this.validate()) {
|
|
6801 this.setYear(this._getYearFromUI());
|
|
6802 }
|
|
6803 }
|
|
6804
|
|
6805 function monthUpdateHandler() {
|
|
6806 this.setMonth(this._getMonthFromUI());
|
|
6807 }
|
|
6808
|
|
6809 E.on(this.submitEl, "click", this.submit, this, true);
|
|
6810 E.on(this.cancelEl, "click", this.cancel, this, true);
|
|
6811 E.on(this.yearEl, "blur", yearUpdateHandler, this, true);
|
|
6812 E.on(this.monthEl, "change", monthUpdateHandler, this, true);
|
|
6813
|
|
6814 if (this.__isIEQuirks) {
|
|
6815 YAHOO.util.Event.on(this.cal.oDomContainer, "resize", this._syncMask, this, true);
|
|
6816 }
|
|
6817
|
|
6818 this.applyKeyListeners();
|
|
6819 },
|
|
6820
|
|
6821 /**
|
|
6822 * Removes/purges DOM event listeners from the rendered elements
|
|
6823 *
|
|
6824 * @method purgeListeners
|
|
6825 */
|
|
6826 purgeListeners : function() {
|
|
6827 var E = YAHOO.util.Event;
|
|
6828 E.removeListener(this.submitEl, "click", this.submit);
|
|
6829 E.removeListener(this.cancelEl, "click", this.cancel);
|
|
6830 E.removeListener(this.yearEl, "blur");
|
|
6831 E.removeListener(this.monthEl, "change");
|
|
6832 if (this.__isIEQuirks) {
|
|
6833 E.removeListener(this.cal.oDomContainer, "resize", this._syncMask);
|
|
6834 }
|
|
6835
|
|
6836 this.purgeKeyListeners();
|
|
6837 },
|
|
6838
|
|
6839 /**
|
|
6840 * Attaches DOM listeners for keyboard support.
|
|
6841 * Tab/Shift-Tab looping, Enter Key Submit on Year element,
|
|
6842 * Up/Down/PgUp/PgDown year increment on Year element
|
|
6843 * <p>
|
|
6844 * NOTE: MacOSX Safari 2.x doesn't let you tab to buttons and
|
|
6845 * MacOSX Gecko does not let you tab to buttons or select controls,
|
|
6846 * so for these browsers, Tab/Shift-Tab looping is limited to the
|
|
6847 * elements which can be reached using the tab key.
|
|
6848 * </p>
|
|
6849 * @method applyKeyListeners
|
|
6850 */
|
|
6851 applyKeyListeners : function() {
|
|
6852 var E = YAHOO.util.Event,
|
|
6853 ua = YAHOO.env.ua;
|
|
6854
|
|
6855 // IE/Safari 3.1 doesn't fire keypress for arrow/pg keys (non-char keys)
|
|
6856 var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
|
|
6857
|
|
6858 // - IE/Safari 3.1 doesn't fire keypress for non-char keys
|
|
6859 // - Opera doesn't allow us to cancel keydown or keypress for tab, but
|
|
6860 // changes focus successfully on keydown (keypress is too late to change focus - opera's already moved on).
|
|
6861 var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
|
|
6862
|
|
6863 // Everyone likes keypress for Enter (char keys) - whoo hoo!
|
|
6864 E.on(this.yearEl, "keypress", this._handleEnterKey, this, true);
|
|
6865
|
|
6866 E.on(this.yearEl, arrowEvt, this._handleDirectionKeys, this, true);
|
|
6867 E.on(this.lastCtrl, tabEvt, this._handleTabKey, this, true);
|
|
6868 E.on(this.firstCtrl, tabEvt, this._handleShiftTabKey, this, true);
|
|
6869 },
|
|
6870
|
|
6871 /**
|
|
6872 * Removes/purges DOM listeners for keyboard support
|
|
6873 *
|
|
6874 * @method purgeKeyListeners
|
|
6875 */
|
|
6876 purgeKeyListeners : function() {
|
|
6877 var E = YAHOO.util.Event,
|
|
6878 ua = YAHOO.env.ua;
|
|
6879
|
|
6880 var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
|
|
6881 var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
|
|
6882
|
|
6883 E.removeListener(this.yearEl, "keypress", this._handleEnterKey);
|
|
6884 E.removeListener(this.yearEl, arrowEvt, this._handleDirectionKeys);
|
|
6885 E.removeListener(this.lastCtrl, tabEvt, this._handleTabKey);
|
|
6886 E.removeListener(this.firstCtrl, tabEvt, this._handleShiftTabKey);
|
|
6887 },
|
|
6888
|
|
6889 /**
|
|
6890 * Updates the Calendar/CalendarGroup's pagedate with the currently set month and year if valid.
|
|
6891 * <p>
|
|
6892 * If the currently set month/year is invalid, a validation error will be displayed and the
|
|
6893 * Calendar/CalendarGroup's pagedate will not be updated.
|
|
6894 * </p>
|
|
6895 * @method submit
|
|
6896 */
|
|
6897 submit : function() {
|
|
6898 if (this.validate()) {
|
|
6899 this.hide();
|
|
6900
|
|
6901 this.setMonth(this._getMonthFromUI());
|
|
6902 this.setYear(this._getYearFromUI());
|
|
6903
|
|
6904 var cal = this.cal;
|
|
6905
|
|
6906 // Artificial delay, just to help the user see something changed
|
|
6907 var delay = YAHOO.widget.CalendarNavigator.UPDATE_DELAY;
|
|
6908 if (delay > 0) {
|
|
6909 var nav = this;
|
|
6910 window.setTimeout(function(){ nav._update(cal); }, delay);
|
|
6911 } else {
|
|
6912 this._update(cal);
|
|
6913 }
|
|
6914 }
|
|
6915 },
|
|
6916
|
|
6917 /**
|
|
6918 * Updates the Calendar rendered state, based on the state of the CalendarNavigator
|
|
6919 * @method _update
|
|
6920 * @param cal The Calendar instance to update
|
|
6921 * @protected
|
|
6922 */
|
|
6923 _update : function(cal) {
|
|
6924 var date = YAHOO.widget.DateMath.getDate(this.getYear() - cal.cfg.getProperty("YEAR_OFFSET"), this.getMonth(), 1);
|
|
6925 cal.cfg.setProperty("pagedate", date);
|
|
6926 cal.render();
|
|
6927 },
|
|
6928
|
|
6929 /**
|
|
6930 * Hides the navigator and mask, without updating the Calendar/CalendarGroup's state
|
|
6931 *
|
|
6932 * @method cancel
|
|
6933 */
|
|
6934 cancel : function() {
|
|
6935 this.hide();
|
|
6936 },
|
|
6937
|
|
6938 /**
|
|
6939 * Validates the current state of the UI controls
|
|
6940 *
|
|
6941 * @method validate
|
|
6942 * @return {Boolean} true, if the current UI state contains valid values, false if not
|
|
6943 */
|
|
6944 validate : function() {
|
|
6945 if (this._getYearFromUI() !== null) {
|
|
6946 this.clearErrors();
|
|
6947 return true;
|
|
6948 } else {
|
|
6949 this.setYearError();
|
|
6950 this.setError(this.__getCfg("invalidYear", true));
|
|
6951 return false;
|
|
6952 }
|
|
6953 },
|
|
6954
|
|
6955 /**
|
|
6956 * Displays an error message in the Navigator's error panel
|
|
6957 * @method setError
|
|
6958 * @param {String} msg The error message to display
|
|
6959 */
|
|
6960 setError : function(msg) {
|
|
6961 if (this.errorEl) {
|
|
6962 this.errorEl.innerHTML = msg;
|
|
6963 this._show(this.errorEl, true);
|
|
6964 }
|
|
6965 },
|
|
6966
|
|
6967 /**
|
|
6968 * Clears the navigator's error message and hides the error panel
|
|
6969 * @method clearError
|
|
6970 */
|
|
6971 clearError : function() {
|
|
6972 if (this.errorEl) {
|
|
6973 this.errorEl.innerHTML = "";
|
|
6974 this._show(this.errorEl, false);
|
|
6975 }
|
|
6976 },
|
|
6977
|
|
6978 /**
|
|
6979 * Displays the validation error UI for the year control
|
|
6980 * @method setYearError
|
|
6981 */
|
|
6982 setYearError : function() {
|
|
6983 YAHOO.util.Dom.addClass(this.yearEl, YAHOO.widget.CalendarNavigator.CLASSES.INVALID);
|
|
6984 },
|
|
6985
|
|
6986 /**
|
|
6987 * Removes the validation error UI for the year control
|
|
6988 * @method clearYearError
|
|
6989 */
|
|
6990 clearYearError : function() {
|
|
6991 YAHOO.util.Dom.removeClass(this.yearEl, YAHOO.widget.CalendarNavigator.CLASSES.INVALID);
|
|
6992 },
|
|
6993
|
|
6994 /**
|
|
6995 * Clears all validation and error messages in the UI
|
|
6996 * @method clearErrors
|
|
6997 */
|
|
6998 clearErrors : function() {
|
|
6999 this.clearError();
|
|
7000 this.clearYearError();
|
|
7001 },
|
|
7002
|
|
7003 /**
|
|
7004 * Sets the initial focus, based on the configured value
|
|
7005 * @method setInitialFocus
|
|
7006 */
|
|
7007 setInitialFocus : function() {
|
|
7008 var el = this.submitEl,
|
|
7009 f = this.__getCfg("initialFocus");
|
|
7010
|
|
7011 if (f && f.toLowerCase) {
|
|
7012 f = f.toLowerCase();
|
|
7013 if (f == "year") {
|
|
7014 el = this.yearEl;
|
|
7015 try {
|
|
7016 this.yearEl.select();
|
|
7017 } catch (selErr) {
|
|
7018 // Ignore;
|
|
7019 }
|
|
7020 } else if (f == "month") {
|
|
7021 el = this.monthEl;
|
|
7022 }
|
|
7023 }
|
|
7024
|
|
7025 if (el && YAHOO.lang.isFunction(el.focus)) {
|
|
7026 try {
|
|
7027 el.focus();
|
|
7028 } catch (focusErr) {
|
|
7029 // TODO: Fall back if focus fails?
|
|
7030 }
|
|
7031 }
|
|
7032 },
|
|
7033
|
|
7034 /**
|
|
7035 * Removes all renderered HTML elements for the Navigator from
|
|
7036 * the DOM, purges event listeners and clears (nulls) any property
|
|
7037 * references to HTML references
|
|
7038 * @method erase
|
|
7039 */
|
|
7040 erase : function() {
|
|
7041 if (this.__rendered) {
|
|
7042 this.purgeListeners();
|
|
7043
|
|
7044 // Clear out innerHTML references
|
|
7045 this.yearEl = null;
|
|
7046 this.monthEl = null;
|
|
7047 this.errorEl = null;
|
|
7048 this.submitEl = null;
|
|
7049 this.cancelEl = null;
|
|
7050 this.firstCtrl = null;
|
|
7051 this.lastCtrl = null;
|
|
7052 if (this.navEl) {
|
|
7053 this.navEl.innerHTML = "";
|
|
7054 }
|
|
7055
|
|
7056 var p = this.navEl.parentNode;
|
|
7057 if (p) {
|
|
7058 p.removeChild(this.navEl);
|
|
7059 }
|
|
7060 this.navEl = null;
|
|
7061
|
|
7062 var pm = this.maskEl.parentNode;
|
|
7063 if (pm) {
|
|
7064 pm.removeChild(this.maskEl);
|
|
7065 }
|
|
7066 this.maskEl = null;
|
|
7067 this.__rendered = false;
|
|
7068 }
|
|
7069 },
|
|
7070
|
|
7071 /**
|
|
7072 * Destroys the Navigator object and any HTML references
|
|
7073 * @method destroy
|
|
7074 */
|
|
7075 destroy : function() {
|
|
7076 this.erase();
|
|
7077 this._doc = null;
|
|
7078 this.cal = null;
|
|
7079 this.id = null;
|
|
7080 },
|
|
7081
|
|
7082 /**
|
|
7083 * Protected implementation to handle how UI elements are
|
|
7084 * hidden/shown.
|
|
7085 *
|
|
7086 * @method _show
|
|
7087 * @protected
|
|
7088 */
|
|
7089 _show : function(el, bShow) {
|
|
7090 if (el) {
|
|
7091 YAHOO.util.Dom.setStyle(el, "display", (bShow) ? "block" : "none");
|
|
7092 }
|
|
7093 },
|
|
7094
|
|
7095 /**
|
|
7096 * Returns the month value (index), from the month UI element
|
|
7097 * @protected
|
|
7098 * @method _getMonthFromUI
|
|
7099 * @return {Number} The month index, or 0 if a UI element for the month
|
|
7100 * is not found
|
|
7101 */
|
|
7102 _getMonthFromUI : function() {
|
|
7103 if (this.monthEl) {
|
|
7104 return this.monthEl.selectedIndex;
|
|
7105 } else {
|
|
7106 return 0; // Default to Jan
|
|
7107 }
|
|
7108 },
|
|
7109
|
|
7110 /**
|
|
7111 * Returns the year value, from the Navitator's year UI element
|
|
7112 * @protected
|
|
7113 * @method _getYearFromUI
|
|
7114 * @return {Number} The year value set in the UI, if valid. null is returned if
|
|
7115 * the UI does not contain a valid year value.
|
|
7116 */
|
|
7117 _getYearFromUI : function() {
|
|
7118 var NAV = YAHOO.widget.CalendarNavigator;
|
|
7119
|
|
7120 var yr = null;
|
|
7121 if (this.yearEl) {
|
|
7122 var value = this.yearEl.value;
|
|
7123 value = value.replace(NAV.TRIM, "$1");
|
|
7124
|
|
7125 if (NAV.YR_PATTERN.test(value)) {
|
|
7126 yr = parseInt(value, 10);
|
|
7127 }
|
|
7128 }
|
|
7129 return yr;
|
|
7130 },
|
|
7131
|
|
7132 /**
|
|
7133 * Updates the Navigator's year UI, based on the year value set on the Navigator object
|
|
7134 * @protected
|
|
7135 * @method _updateYearUI
|
|
7136 */
|
|
7137 _updateYearUI : function() {
|
|
7138 if (this.yearEl && this._year !== null) {
|
|
7139 this.yearEl.value = this._year;
|
|
7140 }
|
|
7141 },
|
|
7142
|
|
7143 /**
|
|
7144 * Updates the Navigator's month UI, based on the month value set on the Navigator object
|
|
7145 * @protected
|
|
7146 * @method _updateMonthUI
|
|
7147 */
|
|
7148 _updateMonthUI : function() {
|
|
7149 if (this.monthEl) {
|
|
7150 this.monthEl.selectedIndex = this._month;
|
|
7151 }
|
|
7152 },
|
|
7153
|
|
7154 /**
|
|
7155 * Sets up references to the first and last focusable element in the Navigator's UI
|
|
7156 * in terms of tab order (Naviagator's firstEl and lastEl properties). The references
|
|
7157 * are used to control modality by looping around from the first to the last control
|
|
7158 * and visa versa for tab/shift-tab navigation.
|
|
7159 * <p>
|
|
7160 * See <a href="#applyKeyListeners">applyKeyListeners</a>
|
|
7161 * </p>
|
|
7162 * @protected
|
|
7163 * @method _setFirstLastElements
|
|
7164 */
|
|
7165 _setFirstLastElements : function() {
|
|
7166 this.firstCtrl = this.monthEl;
|
|
7167 this.lastCtrl = this.cancelEl;
|
|
7168
|
|
7169 // Special handling for MacOSX.
|
|
7170 // - Safari 2.x can't focus on buttons
|
|
7171 // - Gecko can't focus on select boxes or buttons
|
|
7172 if (this.__isMac) {
|
|
7173 if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420){
|
|
7174 this.firstCtrl = this.monthEl;
|
|
7175 this.lastCtrl = this.yearEl;
|
|
7176 }
|
|
7177 if (YAHOO.env.ua.gecko) {
|
|
7178 this.firstCtrl = this.yearEl;
|
|
7179 this.lastCtrl = this.yearEl;
|
|
7180 }
|
|
7181 }
|
|
7182 },
|
|
7183
|
|
7184 /**
|
|
7185 * Default Keyboard event handler to capture Enter
|
|
7186 * on the Navigator's year control (yearEl)
|
|
7187 *
|
|
7188 * @method _handleEnterKey
|
|
7189 * @protected
|
|
7190 * @param {Event} e The DOM event being handled
|
|
7191 */
|
|
7192 _handleEnterKey : function(e) {
|
|
7193 var KEYS = YAHOO.util.KeyListener.KEY;
|
|
7194
|
|
7195 if (YAHOO.util.Event.getCharCode(e) == KEYS.ENTER) {
|
|
7196 YAHOO.util.Event.preventDefault(e);
|
|
7197 this.submit();
|
|
7198 }
|
|
7199 },
|
|
7200
|
|
7201 /**
|
|
7202 * Default Keyboard event handler to capture up/down/pgup/pgdown
|
|
7203 * on the Navigator's year control (yearEl).
|
|
7204 *
|
|
7205 * @method _handleDirectionKeys
|
|
7206 * @protected
|
|
7207 * @param {Event} e The DOM event being handled
|
|
7208 */
|
|
7209 _handleDirectionKeys : function(e) {
|
|
7210 var E = YAHOO.util.Event,
|
|
7211 KEYS = YAHOO.util.KeyListener.KEY,
|
|
7212 NAV = YAHOO.widget.CalendarNavigator;
|
|
7213
|
|
7214 var value = (this.yearEl.value) ? parseInt(this.yearEl.value, 10) : null;
|
|
7215 if (isFinite(value)) {
|
|
7216 var dir = false;
|
|
7217 switch(E.getCharCode(e)) {
|
|
7218 case KEYS.UP:
|
|
7219 this.yearEl.value = value + NAV.YR_MINOR_INC;
|
|
7220 dir = true;
|
|
7221 break;
|
|
7222 case KEYS.DOWN:
|
|
7223 this.yearEl.value = Math.max(value - NAV.YR_MINOR_INC, 0);
|
|
7224 dir = true;
|
|
7225 break;
|
|
7226 case KEYS.PAGE_UP:
|
|
7227 this.yearEl.value = value + NAV.YR_MAJOR_INC;
|
|
7228 dir = true;
|
|
7229 break;
|
|
7230 case KEYS.PAGE_DOWN:
|
|
7231 this.yearEl.value = Math.max(value - NAV.YR_MAJOR_INC, 0);
|
|
7232 dir = true;
|
|
7233 break;
|
|
7234 default:
|
|
7235 break;
|
|
7236 }
|
|
7237 if (dir) {
|
|
7238 E.preventDefault(e);
|
|
7239 try {
|
|
7240 this.yearEl.select();
|
|
7241 } catch(err) {
|
|
7242 // Ignore
|
|
7243 }
|
|
7244 }
|
|
7245 }
|
|
7246 },
|
|
7247
|
|
7248 /**
|
|
7249 * Default Keyboard event handler to capture Tab
|
|
7250 * on the last control (lastCtrl) in the Navigator.
|
|
7251 *
|
|
7252 * @method _handleTabKey
|
|
7253 * @protected
|
|
7254 * @param {Event} e The DOM event being handled
|
|
7255 */
|
|
7256 _handleTabKey : function(e) {
|
|
7257 var E = YAHOO.util.Event,
|
|
7258 KEYS = YAHOO.util.KeyListener.KEY;
|
|
7259
|
|
7260 if (E.getCharCode(e) == KEYS.TAB && !e.shiftKey) {
|
|
7261 try {
|
|
7262 E.preventDefault(e);
|
|
7263 this.firstCtrl.focus();
|
|
7264 } catch (err) {
|
|
7265 // Ignore - mainly for focus edge cases
|
|
7266 }
|
|
7267 }
|
|
7268 },
|
|
7269
|
|
7270 /**
|
|
7271 * Default Keyboard event handler to capture Shift-Tab
|
|
7272 * on the first control (firstCtrl) in the Navigator.
|
|
7273 *
|
|
7274 * @method _handleShiftTabKey
|
|
7275 * @protected
|
|
7276 * @param {Event} e The DOM event being handled
|
|
7277 */
|
|
7278 _handleShiftTabKey : function(e) {
|
|
7279 var E = YAHOO.util.Event,
|
|
7280 KEYS = YAHOO.util.KeyListener.KEY;
|
|
7281
|
|
7282 if (e.shiftKey && E.getCharCode(e) == KEYS.TAB) {
|
|
7283 try {
|
|
7284 E.preventDefault(e);
|
|
7285 this.lastCtrl.focus();
|
|
7286 } catch (err) {
|
|
7287 // Ignore - mainly for focus edge cases
|
|
7288 }
|
|
7289 }
|
|
7290 },
|
|
7291
|
|
7292 /**
|
|
7293 * Retrieve Navigator configuration values from
|
|
7294 * the parent Calendar/CalendarGroup's config value.
|
|
7295 * <p>
|
|
7296 * If it has not been set in the user provided configuration, the method will
|
|
7297 * return the default value of the configuration property, as set in DEFAULT_CONFIG
|
|
7298 * </p>
|
|
7299 * @private
|
|
7300 * @method __getCfg
|
|
7301 * @param {String} Case sensitive property name.
|
|
7302 * @param {Boolean} true, if the property is a string property, false if not.
|
|
7303 * @return The value of the configuration property
|
|
7304 */
|
|
7305 __getCfg : function(prop, bIsStr) {
|
|
7306 var DEF_CFG = YAHOO.widget.CalendarNavigator.DEFAULT_CONFIG;
|
|
7307 var cfg = this.cal.cfg.getProperty("navigator");
|
|
7308
|
|
7309 if (bIsStr) {
|
|
7310 return (cfg !== true && cfg.strings && cfg.strings[prop]) ? cfg.strings[prop] : DEF_CFG.strings[prop];
|
|
7311 } else {
|
|
7312 return (cfg !== true && cfg[prop]) ? cfg[prop] : DEF_CFG[prop];
|
|
7313 }
|
|
7314 },
|
|
7315
|
|
7316 /**
|
|
7317 * Private flag, to identify MacOS
|
|
7318 * @private
|
|
7319 * @property __isMac
|
|
7320 */
|
|
7321 __isMac : (navigator.userAgent.toLowerCase().indexOf("macintosh") != -1)
|
|
7322
|
|
7323 };
|
|
7324 YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.8.0r4", build: "2449"});
|