/src/main/resources/org/apache/struts2/static/calendar/calendar.js

http://struts2yuiplugin.googlecode.com/ · JavaScript · 7148 lines · 3010 code · 916 blank · 3222 comment · 553 complexity · c1f4fbc5d520aed1d29fc19fd4378d7a MD5 · raw file

Large files are truncated click here to view the full file

  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.7.0
  6. */
  7. (function () {
  8. /**
  9. * Config is a utility used within an Object to allow the implementer to
  10. * maintain a list of local configuration properties and listen for changes
  11. * to those properties dynamically using CustomEvent. The initial values are
  12. * also maintained so that the configuration can be reset at any given point
  13. * to its initial state.
  14. * @namespace YAHOO.util
  15. * @class Config
  16. * @constructor
  17. * @param {Object} owner The owner Object to which this Config Object belongs
  18. */
  19. YAHOO.util.Config = function (owner) {
  20. if (owner) {
  21. this.init(owner);
  22. }
  23. };
  24. var Lang = YAHOO.lang,
  25. CustomEvent = YAHOO.util.CustomEvent,
  26. Config = YAHOO.util.Config;
  27. /**
  28. * Constant representing the CustomEvent type for the config changed event.
  29. * @property YAHOO.util.Config.CONFIG_CHANGED_EVENT
  30. * @private
  31. * @static
  32. * @final
  33. */
  34. Config.CONFIG_CHANGED_EVENT = "configChanged";
  35. /**
  36. * Constant representing the boolean type string
  37. * @property YAHOO.util.Config.BOOLEAN_TYPE
  38. * @private
  39. * @static
  40. * @final
  41. */
  42. Config.BOOLEAN_TYPE = "boolean";
  43. Config.prototype = {
  44. /**
  45. * Object reference to the owner of this Config Object
  46. * @property owner
  47. * @type Object
  48. */
  49. owner: null,
  50. /**
  51. * Boolean flag that specifies whether a queue is currently
  52. * being executed
  53. * @property queueInProgress
  54. * @type Boolean
  55. */
  56. queueInProgress: false,
  57. /**
  58. * Maintains the local collection of configuration property objects and
  59. * their specified values
  60. * @property config
  61. * @private
  62. * @type Object
  63. */
  64. config: null,
  65. /**
  66. * Maintains the local collection of configuration property objects as
  67. * they were initially applied.
  68. * This object is used when resetting a property.
  69. * @property initialConfig
  70. * @private
  71. * @type Object
  72. */
  73. initialConfig: null,
  74. /**
  75. * Maintains the local, normalized CustomEvent queue
  76. * @property eventQueue
  77. * @private
  78. * @type Object
  79. */
  80. eventQueue: null,
  81. /**
  82. * Custom Event, notifying subscribers when Config properties are set
  83. * (setProperty is called without the silent flag
  84. * @event configChangedEvent
  85. */
  86. configChangedEvent: null,
  87. /**
  88. * Initializes the configuration Object and all of its local members.
  89. * @method init
  90. * @param {Object} owner The owner Object to which this Config
  91. * Object belongs
  92. */
  93. init: function (owner) {
  94. this.owner = owner;
  95. this.configChangedEvent =
  96. this.createEvent(Config.CONFIG_CHANGED_EVENT);
  97. this.configChangedEvent.signature = CustomEvent.LIST;
  98. this.queueInProgress = false;
  99. this.config = {};
  100. this.initialConfig = {};
  101. this.eventQueue = [];
  102. },
  103. /**
  104. * Validates that the value passed in is a Boolean.
  105. * @method checkBoolean
  106. * @param {Object} val The value to validate
  107. * @return {Boolean} true, if the value is valid
  108. */
  109. checkBoolean: function (val) {
  110. return (typeof val == Config.BOOLEAN_TYPE);
  111. },
  112. /**
  113. * Validates that the value passed in is a number.
  114. * @method checkNumber
  115. * @param {Object} val The value to validate
  116. * @return {Boolean} true, if the value is valid
  117. */
  118. checkNumber: function (val) {
  119. return (!isNaN(val));
  120. },
  121. /**
  122. * Fires a configuration property event using the specified value.
  123. * @method fireEvent
  124. * @private
  125. * @param {String} key The configuration property's name
  126. * @param {value} Object The value of the correct type for the property
  127. */
  128. fireEvent: function ( key, value ) {
  129. var property = this.config[key];
  130. if (property && property.event) {
  131. property.event.fire(value);
  132. }
  133. },
  134. /**
  135. * Adds a property to the Config Object's private config hash.
  136. * @method addProperty
  137. * @param {String} key The configuration property's name
  138. * @param {Object} propertyObject The Object containing all of this
  139. * property's arguments
  140. */
  141. addProperty: function ( key, propertyObject ) {
  142. key = key.toLowerCase();
  143. this.config[key] = propertyObject;
  144. propertyObject.event = this.createEvent(key, { scope: this.owner });
  145. propertyObject.event.signature = CustomEvent.LIST;
  146. propertyObject.key = key;
  147. if (propertyObject.handler) {
  148. propertyObject.event.subscribe(propertyObject.handler,
  149. this.owner);
  150. }
  151. this.setProperty(key, propertyObject.value, true);
  152. if (! propertyObject.suppressEvent) {
  153. this.queueProperty(key, propertyObject.value);
  154. }
  155. },
  156. /**
  157. * Returns a key-value configuration map of the values currently set in
  158. * the Config Object.
  159. * @method getConfig
  160. * @return {Object} The current config, represented in a key-value map
  161. */
  162. getConfig: function () {
  163. var cfg = {},
  164. currCfg = this.config,
  165. prop,
  166. property;
  167. for (prop in currCfg) {
  168. if (Lang.hasOwnProperty(currCfg, prop)) {
  169. property = currCfg[prop];
  170. if (property && property.event) {
  171. cfg[prop] = property.value;
  172. }
  173. }
  174. }
  175. return cfg;
  176. },
  177. /**
  178. * Returns the value of specified property.
  179. * @method getProperty
  180. * @param {String} key The name of the property
  181. * @return {Object} The value of the specified property
  182. */
  183. getProperty: function (key) {
  184. var property = this.config[key.toLowerCase()];
  185. if (property && property.event) {
  186. return property.value;
  187. } else {
  188. return undefined;
  189. }
  190. },
  191. /**
  192. * Resets the specified property's value to its initial value.
  193. * @method resetProperty
  194. * @param {String} key The name of the property
  195. * @return {Boolean} True is the property was reset, false if not
  196. */
  197. resetProperty: function (key) {
  198. key = key.toLowerCase();
  199. var property = this.config[key];
  200. if (property && property.event) {
  201. if (this.initialConfig[key] &&
  202. !Lang.isUndefined(this.initialConfig[key])) {
  203. this.setProperty(key, this.initialConfig[key]);
  204. return true;
  205. }
  206. } else {
  207. return false;
  208. }
  209. },
  210. /**
  211. * Sets the value of a property. If the silent property is passed as
  212. * true, the property's event will not be fired.
  213. * @method setProperty
  214. * @param {String} key The name of the property
  215. * @param {String} value The value to set the property to
  216. * @param {Boolean} silent Whether the value should be set silently,
  217. * without firing the property event.
  218. * @return {Boolean} True, if the set was successful, false if it failed.
  219. */
  220. setProperty: function (key, value, silent) {
  221. var property;
  222. key = key.toLowerCase();
  223. if (this.queueInProgress && ! silent) {
  224. // Currently running through a queue...
  225. this.queueProperty(key,value);
  226. return true;
  227. } else {
  228. property = this.config[key];
  229. if (property && property.event) {
  230. if (property.validator && !property.validator(value)) {
  231. return false;
  232. } else {
  233. property.value = value;
  234. if (! silent) {
  235. this.fireEvent(key, value);
  236. this.configChangedEvent.fire([key, value]);
  237. }
  238. return true;
  239. }
  240. } else {
  241. return false;
  242. }
  243. }
  244. },
  245. /**
  246. * Sets the value of a property and queues its event to execute. If the
  247. * event is already scheduled to execute, it is
  248. * moved from its current position to the end of the queue.
  249. * @method queueProperty
  250. * @param {String} key The name of the property
  251. * @param {String} value The value to set the property to
  252. * @return {Boolean} true, if the set was successful, false if
  253. * it failed.
  254. */
  255. queueProperty: function (key, value) {
  256. key = key.toLowerCase();
  257. var property = this.config[key],
  258. foundDuplicate = false,
  259. iLen,
  260. queueItem,
  261. queueItemKey,
  262. queueItemValue,
  263. sLen,
  264. supercedesCheck,
  265. qLen,
  266. queueItemCheck,
  267. queueItemCheckKey,
  268. queueItemCheckValue,
  269. i,
  270. s,
  271. q;
  272. if (property && property.event) {
  273. if (!Lang.isUndefined(value) && property.validator &&
  274. !property.validator(value)) { // validator
  275. return false;
  276. } else {
  277. if (!Lang.isUndefined(value)) {
  278. property.value = value;
  279. } else {
  280. value = property.value;
  281. }
  282. foundDuplicate = false;
  283. iLen = this.eventQueue.length;
  284. for (i = 0; i < iLen; i++) {
  285. queueItem = this.eventQueue[i];
  286. if (queueItem) {
  287. queueItemKey = queueItem[0];
  288. queueItemValue = queueItem[1];
  289. if (queueItemKey == key) {
  290. /*
  291. found a dupe... push to end of queue, null
  292. current item, and break
  293. */
  294. this.eventQueue[i] = null;
  295. this.eventQueue.push(
  296. [key, (!Lang.isUndefined(value) ?
  297. value : queueItemValue)]);
  298. foundDuplicate = true;
  299. break;
  300. }
  301. }
  302. }
  303. // this is a refire, or a new property in the queue
  304. if (! foundDuplicate && !Lang.isUndefined(value)) {
  305. this.eventQueue.push([key, value]);
  306. }
  307. }
  308. if (property.supercedes) {
  309. sLen = property.supercedes.length;
  310. for (s = 0; s < sLen; s++) {
  311. supercedesCheck = property.supercedes[s];
  312. qLen = this.eventQueue.length;
  313. for (q = 0; q < qLen; q++) {
  314. queueItemCheck = this.eventQueue[q];
  315. if (queueItemCheck) {
  316. queueItemCheckKey = queueItemCheck[0];
  317. queueItemCheckValue = queueItemCheck[1];
  318. if (queueItemCheckKey ==
  319. supercedesCheck.toLowerCase() ) {
  320. this.eventQueue.push([queueItemCheckKey,
  321. queueItemCheckValue]);
  322. this.eventQueue[q] = null;
  323. break;
  324. }
  325. }
  326. }
  327. }
  328. }
  329. return true;
  330. } else {
  331. return false;
  332. }
  333. },
  334. /**
  335. * Fires the event for a property using the property's current value.
  336. * @method refireEvent
  337. * @param {String} key The name of the property
  338. */
  339. refireEvent: function (key) {
  340. key = key.toLowerCase();
  341. var property = this.config[key];
  342. if (property && property.event &&
  343. !Lang.isUndefined(property.value)) {
  344. if (this.queueInProgress) {
  345. this.queueProperty(key);
  346. } else {
  347. this.fireEvent(key, property.value);
  348. }
  349. }
  350. },
  351. /**
  352. * Applies a key-value Object literal to the configuration, replacing
  353. * any existing values, and queueing the property events.
  354. * Although the values will be set, fireQueue() must be called for their
  355. * associated events to execute.
  356. * @method applyConfig
  357. * @param {Object} userConfig The configuration Object literal
  358. * @param {Boolean} init When set to true, the initialConfig will
  359. * be set to the userConfig passed in, so that calling a reset will
  360. * reset the properties to the passed values.
  361. */
  362. applyConfig: function (userConfig, init) {
  363. var sKey,
  364. oConfig;
  365. if (init) {
  366. oConfig = {};
  367. for (sKey in userConfig) {
  368. if (Lang.hasOwnProperty(userConfig, sKey)) {
  369. oConfig[sKey.toLowerCase()] = userConfig[sKey];
  370. }
  371. }
  372. this.initialConfig = oConfig;
  373. }
  374. for (sKey in userConfig) {
  375. if (Lang.hasOwnProperty(userConfig, sKey)) {
  376. this.queueProperty(sKey, userConfig[sKey]);
  377. }
  378. }
  379. },
  380. /**
  381. * Refires the events for all configuration properties using their
  382. * current values.
  383. * @method refresh
  384. */
  385. refresh: function () {
  386. var prop;
  387. for (prop in this.config) {
  388. if (Lang.hasOwnProperty(this.config, prop)) {
  389. this.refireEvent(prop);
  390. }
  391. }
  392. },
  393. /**
  394. * Fires the normalized list of queued property change events
  395. * @method fireQueue
  396. */
  397. fireQueue: function () {
  398. var i,
  399. queueItem,
  400. key,
  401. value,
  402. property;
  403. this.queueInProgress = true;
  404. for (i = 0;i < this.eventQueue.length; i++) {
  405. queueItem = this.eventQueue[i];
  406. if (queueItem) {
  407. key = queueItem[0];
  408. value = queueItem[1];
  409. property = this.config[key];
  410. property.value = value;
  411. // Clear out queue entry, to avoid it being
  412. // re-added to the queue by any queueProperty/supercedes
  413. // calls which are invoked during fireEvent
  414. this.eventQueue[i] = null;
  415. this.fireEvent(key,value);
  416. }
  417. }
  418. this.queueInProgress = false;
  419. this.eventQueue = [];
  420. },
  421. /**
  422. * Subscribes an external handler to the change event for any
  423. * given property.
  424. * @method subscribeToConfigEvent
  425. * @param {String} key The property name
  426. * @param {Function} handler The handler function to use subscribe to
  427. * the property's event
  428. * @param {Object} obj The Object to use for scoping the event handler
  429. * (see CustomEvent documentation)
  430. * @param {Boolean} override Optional. If true, will override "this"
  431. * within the handler to map to the scope Object passed into the method.
  432. * @return {Boolean} True, if the subscription was successful,
  433. * otherwise false.
  434. */
  435. subscribeToConfigEvent: function (key, handler, obj, override) {
  436. var property = this.config[key.toLowerCase()];
  437. if (property && property.event) {
  438. if (!Config.alreadySubscribed(property.event, handler, obj)) {
  439. property.event.subscribe(handler, obj, override);
  440. }
  441. return true;
  442. } else {
  443. return false;
  444. }
  445. },
  446. /**
  447. * Unsubscribes an external handler from the change event for any
  448. * given property.
  449. * @method unsubscribeFromConfigEvent
  450. * @param {String} key The property name
  451. * @param {Function} handler The handler function to use subscribe to
  452. * the property's event
  453. * @param {Object} obj The Object to use for scoping the event
  454. * handler (see CustomEvent documentation)
  455. * @return {Boolean} True, if the unsubscription was successful,
  456. * otherwise false.
  457. */
  458. unsubscribeFromConfigEvent: function (key, handler, obj) {
  459. var property = this.config[key.toLowerCase()];
  460. if (property && property.event) {
  461. return property.event.unsubscribe(handler, obj);
  462. } else {
  463. return false;
  464. }
  465. },
  466. /**
  467. * Returns a string representation of the Config object
  468. * @method toString
  469. * @return {String} The Config object in string format.
  470. */
  471. toString: function () {
  472. var output = "Config";
  473. if (this.owner) {
  474. output += " [" + this.owner.toString() + "]";
  475. }
  476. return output;
  477. },
  478. /**
  479. * Returns a string representation of the Config object's current
  480. * CustomEvent queue
  481. * @method outputEventQueue
  482. * @return {String} The string list of CustomEvents currently queued
  483. * for execution
  484. */
  485. outputEventQueue: function () {
  486. var output = "",
  487. queueItem,
  488. q,
  489. nQueue = this.eventQueue.length;
  490. for (q = 0; q < nQueue; q++) {
  491. queueItem = this.eventQueue[q];
  492. if (queueItem) {
  493. output += queueItem[0] + "=" + queueItem[1] + ", ";
  494. }
  495. }
  496. return output;
  497. },
  498. /**
  499. * Sets all properties to null, unsubscribes all listeners from each
  500. * property's change event and all listeners from the configChangedEvent.
  501. * @method destroy
  502. */
  503. destroy: function () {
  504. var oConfig = this.config,
  505. sProperty,
  506. oProperty;
  507. for (sProperty in oConfig) {
  508. if (Lang.hasOwnProperty(oConfig, sProperty)) {
  509. oProperty = oConfig[sProperty];
  510. oProperty.event.unsubscribeAll();
  511. oProperty.event = null;
  512. }
  513. }
  514. this.configChangedEvent.unsubscribeAll();
  515. this.configChangedEvent = null;
  516. this.owner = null;
  517. this.config = null;
  518. this.initialConfig = null;
  519. this.eventQueue = null;
  520. }
  521. };
  522. /**
  523. * Checks to determine if a particular function/Object pair are already
  524. * subscribed to the specified CustomEvent
  525. * @method YAHOO.util.Config.alreadySubscribed
  526. * @static
  527. * @param {YAHOO.util.CustomEvent} evt The CustomEvent for which to check
  528. * the subscriptions
  529. * @param {Function} fn The function to look for in the subscribers list
  530. * @param {Object} obj The execution scope Object for the subscription
  531. * @return {Boolean} true, if the function/Object pair is already subscribed
  532. * to the CustomEvent passed in
  533. */
  534. Config.alreadySubscribed = function (evt, fn, obj) {
  535. var nSubscribers = evt.subscribers.length,
  536. subsc,
  537. i;
  538. if (nSubscribers > 0) {
  539. i = nSubscribers - 1;
  540. do {
  541. subsc = evt.subscribers[i];
  542. if (subsc && subsc.obj == obj && subsc.fn == fn) {
  543. return true;
  544. }
  545. }
  546. while (i--);
  547. }
  548. return false;
  549. };
  550. YAHOO.lang.augmentProto(Config, YAHOO.util.EventProvider);
  551. }());
  552. /**
  553. * YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
  554. * used for adding, subtracting, and comparing dates.
  555. * @namespace YAHOO.widget
  556. * @class DateMath
  557. */
  558. YAHOO.widget.DateMath = {
  559. /**
  560. * Constant field representing Day
  561. * @property DAY
  562. * @static
  563. * @final
  564. * @type String
  565. */
  566. DAY : "D",
  567. /**
  568. * Constant field representing Week
  569. * @property WEEK
  570. * @static
  571. * @final
  572. * @type String
  573. */
  574. WEEK : "W",
  575. /**
  576. * Constant field representing Year
  577. * @property YEAR
  578. * @static
  579. * @final
  580. * @type String
  581. */
  582. YEAR : "Y",
  583. /**
  584. * Constant field representing Month
  585. * @property MONTH
  586. * @static
  587. * @final
  588. * @type String
  589. */
  590. MONTH : "M",
  591. /**
  592. * Constant field representing one day, in milliseconds
  593. * @property ONE_DAY_MS
  594. * @static
  595. * @final
  596. * @type Number
  597. */
  598. ONE_DAY_MS : 1000*60*60*24,
  599. /**
  600. * Constant field representing the date in first week of January
  601. * which identifies the first week of the year.
  602. * <p>
  603. * In the U.S, Jan 1st is normally used based on a Sunday start of week.
  604. * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
  605. * </p>
  606. * @property WEEK_ONE_JAN_DATE
  607. * @static
  608. * @type Number
  609. */
  610. WEEK_ONE_JAN_DATE : 1,
  611. /**
  612. * Adds the specified amount of time to the this instance.
  613. * @method add
  614. * @param {Date} date The JavaScript Date object to perform addition on
  615. * @param {String} field The field constant to be used for performing addition.
  616. * @param {Number} amount The number of units (measured in the field constant) to add to the date.
  617. * @return {Date} The resulting Date object
  618. */
  619. add : function(date, field, amount) {
  620. var d = new Date(date.getTime());
  621. switch (field) {
  622. case this.MONTH:
  623. var newMonth = date.getMonth() + amount;
  624. var years = 0;
  625. if (newMonth < 0) {
  626. while (newMonth < 0) {
  627. newMonth += 12;
  628. years -= 1;
  629. }
  630. } else if (newMonth > 11) {
  631. while (newMonth > 11) {
  632. newMonth -= 12;
  633. years += 1;
  634. }
  635. }
  636. d.setMonth(newMonth);
  637. d.setFullYear(date.getFullYear() + years);
  638. break;
  639. case this.DAY:
  640. this._addDays(d, amount);
  641. // d.setDate(date.getDate() + amount);
  642. break;
  643. case this.YEAR:
  644. d.setFullYear(date.getFullYear() + amount);
  645. break;
  646. case this.WEEK:
  647. this._addDays(d, (amount * 7));
  648. // d.setDate(date.getDate() + (amount * 7));
  649. break;
  650. }
  651. return d;
  652. },
  653. /**
  654. * Private helper method to account for bug in Safari 2 (webkit < 420)
  655. * when Date.setDate(n) is called with n less than -128 or greater than 127.
  656. * <p>
  657. * Fix approach and original findings are available here:
  658. * http://brianary.blogspot.com/2006/03/safari-date-bug.html
  659. * </p>
  660. * @method _addDays
  661. * @param {Date} d JavaScript date object
  662. * @param {Number} nDays The number of days to add to the date object (can be negative)
  663. * @private
  664. */
  665. _addDays : function(d, nDays) {
  666. if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
  667. if (nDays < 0) {
  668. // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
  669. for(var min = -128; nDays < min; nDays -= min) {
  670. d.setDate(d.getDate() + min);
  671. }
  672. } else {
  673. // Ensure we don't go above 96 + 31 = 127
  674. for(var max = 96; nDays > max; nDays -= max) {
  675. d.setDate(d.getDate() + max);
  676. }
  677. }
  678. // nDays should be remainder between -128 and 96
  679. }
  680. d.setDate(d.getDate() + nDays);
  681. },
  682. /**
  683. * Subtracts the specified amount of time from the this instance.
  684. * @method subtract
  685. * @param {Date} date The JavaScript Date object to perform subtraction on
  686. * @param {Number} field The this field constant to be used for performing subtraction.
  687. * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
  688. * @return {Date} The resulting Date object
  689. */
  690. subtract : function(date, field, amount) {
  691. return this.add(date, field, (amount*-1));
  692. },
  693. /**
  694. * Determines whether a given date is before another date on the calendar.
  695. * @method before
  696. * @param {Date} date The Date object to compare with the compare argument
  697. * @param {Date} compareTo The Date object to use for the comparison
  698. * @return {Boolean} true if the date occurs before the compared date; false if not.
  699. */
  700. before : function(date, compareTo) {
  701. var ms = compareTo.getTime();
  702. if (date.getTime() < ms) {
  703. return true;
  704. } else {
  705. return false;
  706. }
  707. },
  708. /**
  709. * Determines whether a given date is after another date on the calendar.
  710. * @method after
  711. * @param {Date} date The Date object to compare with the compare argument
  712. * @param {Date} compareTo The Date object to use for the comparison
  713. * @return {Boolean} true if the date occurs after the compared date; false if not.
  714. */
  715. after : function(date, compareTo) {
  716. var ms = compareTo.getTime();
  717. if (date.getTime() > ms) {
  718. return true;
  719. } else {
  720. return false;
  721. }
  722. },
  723. /**
  724. * Determines whether a given date is between two other dates on the calendar.
  725. * @method between
  726. * @param {Date} date The date to check for
  727. * @param {Date} dateBegin The start of the range
  728. * @param {Date} dateEnd The end of the range
  729. * @return {Boolean} true if the date occurs between the compared dates; false if not.
  730. */
  731. between : function(date, dateBegin, dateEnd) {
  732. if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
  733. return true;
  734. } else {
  735. return false;
  736. }
  737. },
  738. /**
  739. * Retrieves a JavaScript Date object representing January 1 of any given year.
  740. * @method getJan1
  741. * @param {Number} calendarYear The calendar year for which to retrieve January 1
  742. * @return {Date} January 1 of the calendar year specified.
  743. */
  744. getJan1 : function(calendarYear) {
  745. return this.getDate(calendarYear,0,1);
  746. },
  747. /**
  748. * Calculates the number of days the specified date is from January 1 of the specified calendar year.
  749. * Passing January 1 to this function would return an offset value of zero.
  750. * @method getDayOffset
  751. * @param {Date} date The JavaScript date for which to find the offset
  752. * @param {Number} calendarYear The calendar year to use for determining the offset
  753. * @return {Number} The number of days since January 1 of the given year
  754. */
  755. getDayOffset : function(date, calendarYear) {
  756. var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
  757. // Find the number of days the passed in date is away from the calendar year start
  758. var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
  759. return dayOffset;
  760. },
  761. /**
  762. * Calculates the week number for the given date. Can currently support standard
  763. * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
  764. * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
  765. *
  766. * @method getWeekNumber
  767. * @param {Date} date The JavaScript date for which to find the week number
  768. * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
  769. * Defaults to 0
  770. * @param {Number} janDate The date in the first week of January which defines week one for the year
  771. * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
  772. * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
  773. *
  774. * @return {Number} The number of the week containing the given date.
  775. */
  776. getWeekNumber : function(date, firstDayOfWeek, janDate) {
  777. // Setup Defaults
  778. firstDayOfWeek = firstDayOfWeek || 0;
  779. janDate = janDate || this.WEEK_ONE_JAN_DATE;
  780. var targetDate = this.clearTime(date),
  781. startOfWeek,
  782. endOfWeek;
  783. if (targetDate.getDay() === firstDayOfWeek) {
  784. startOfWeek = targetDate;
  785. } else {
  786. startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
  787. }
  788. var startYear = startOfWeek.getFullYear(),
  789. startTime = startOfWeek.getTime();
  790. // DST shouldn't be a problem here, math is quicker than setDate();
  791. endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
  792. var weekNum;
  793. if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
  794. // If years don't match, endOfWeek is in Jan. and if the
  795. // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
  796. weekNum = 1;
  797. } else {
  798. // Get the 1st day of the 1st week, and
  799. // find how many days away we are from it.
  800. var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
  801. weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
  802. // Round days to smoothen out 1 hr DST diff
  803. var daysDiff = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
  804. // Calc. Full Weeks
  805. var rem = daysDiff % 7;
  806. var weeksDiff = (daysDiff - rem)/7;
  807. weekNum = weeksDiff + 1;
  808. }
  809. return weekNum;
  810. },
  811. /**
  812. * Get the first day of the week, for the give date.
  813. * @param {Date} dt The date in the week for which the first day is required.
  814. * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
  815. * @return {Date} The first day of the week
  816. */
  817. getFirstDayOfWeek : function (dt, startOfWeek) {
  818. startOfWeek = startOfWeek || 0;
  819. var dayOfWeekIndex = dt.getDay(),
  820. dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
  821. return this.subtract(dt, this.DAY, dayOfWeek);
  822. },
  823. /**
  824. * Determines if a given week overlaps two different years.
  825. * @method isYearOverlapWeek
  826. * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
  827. * @return {Boolean} true if the date overlaps two different years.
  828. */
  829. isYearOverlapWeek : function(weekBeginDate) {
  830. var overlaps = false;
  831. var nextWeek = this.add(weekBeginDate, this.DAY, 6);
  832. if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
  833. overlaps = true;
  834. }
  835. return overlaps;
  836. },
  837. /**
  838. * Determines if a given week overlaps two different months.
  839. * @method isMonthOverlapWeek
  840. * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
  841. * @return {Boolean} true if the date overlaps two different months.
  842. */
  843. isMonthOverlapWeek : function(weekBeginDate) {
  844. var overlaps = false;
  845. var nextWeek = this.add(weekBeginDate, this.DAY, 6);
  846. if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
  847. overlaps = true;
  848. }
  849. return overlaps;
  850. },
  851. /**
  852. * Gets the first day of a month containing a given date.
  853. * @method findMonthStart
  854. * @param {Date} date The JavaScript Date used to calculate the month start
  855. * @return {Date} The JavaScript Date representing the first day of the month
  856. */
  857. findMonthStart : function(date) {
  858. var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
  859. return start;
  860. },
  861. /**
  862. * Gets the last day of a month containing a given date.
  863. * @method findMonthEnd
  864. * @param {Date} date The JavaScript Date used to calculate the month end
  865. * @return {Date} The JavaScript Date representing the last day of the month
  866. */
  867. findMonthEnd : function(date) {
  868. var start = this.findMonthStart(date);
  869. var nextMonth = this.add(start, this.MONTH, 1);
  870. var end = this.subtract(nextMonth, this.DAY, 1);
  871. return end;
  872. },
  873. /**
  874. * Clears the time fields from a given date, effectively setting the time to 12 noon.
  875. * @method clearTime
  876. * @param {Date} date The JavaScript Date for which the time fields will be cleared
  877. * @return {Date} The JavaScript Date cleared of all time fields
  878. */
  879. clearTime : function(date) {
  880. date.setHours(12,0,0,0);
  881. return date;
  882. },
  883. /**
  884. * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
  885. * 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
  886. * set the year to 19xx if a year (xx) which is less than 100 is provided.
  887. * <p>
  888. * <em>NOTE:</em>Validation on argument values is not performed. It is the caller's responsibility to ensure
  889. * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
  890. * </p>
  891. * @method getDate
  892. * @param {Number} y Year.
  893. * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
  894. * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
  895. * @return {Date} The JavaScript date object with year, month, date set as provided.
  896. */
  897. getDate : function(y, m, d) {
  898. var dt = null;
  899. if (YAHOO.lang.isUndefined(d)) {
  900. d = 1;
  901. }
  902. if (y >= 100) {
  903. dt = new Date(y, m, d);
  904. } else {
  905. dt = new Date();
  906. dt.setFullYear(y);
  907. dt.setMonth(m);
  908. dt.setDate(d);
  909. dt.setHours(0,0,0,0);
  910. }
  911. return dt;
  912. }
  913. };
  914. /**
  915. * 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
  916. * multi-month interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
  917. * @module calendar
  918. * @title Calendar
  919. * @namespace YAHOO.widget
  920. * @requires yahoo,dom,event
  921. */
  922. (function(){
  923. var Dom = YAHOO.util.Dom,
  924. Event = YAHOO.util.Event,
  925. Lang = YAHOO.lang,
  926. DateMath = YAHOO.widget.DateMath;
  927. /**
  928. * Calendar is the base class for the Calendar widget. In its most basic
  929. * implementation, it has the ability to render a calendar widget on the page
  930. * that can be manipulated to select a single date, move back and forth between
  931. * months and years.
  932. * <p>To construct the placeholder for the calendar widget, the code is as
  933. * follows:
  934. * <xmp>
  935. * <div id="calContainer"></div>
  936. * </xmp>
  937. * </p>
  938. * <p>
  939. * <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
  940. * The Calendar can be constructed by simply providing a container ID string,
  941. * or a reference to a container DIV HTMLElement (the element needs to exist
  942. * in the document).
  943. *
  944. * E.g.:
  945. * <xmp>
  946. * var c = new YAHOO.widget.Calendar("calContainer", configOptions);
  947. * </xmp>
  948. * or:
  949. * <xmp>
  950. * var containerDiv = YAHOO.util.Dom.get("calContainer");
  951. * var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
  952. * </xmp>
  953. * </p>
  954. * <p>
  955. * If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
  956. * 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".
  957. * </p>
  958. *
  959. * @namespace YAHOO.widget
  960. * @class Calendar
  961. * @constructor
  962. * @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.
  963. * @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.
  964. * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
  965. */
  966. function Calendar(id, containerId, config) {
  967. this.init.apply(this, arguments);
  968. }
  969. /**
  970. * The path to be used for images loaded for the Calendar
  971. * @property YAHOO.widget.Calendar.IMG_ROOT
  972. * @static
  973. * @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
  974. * @type String
  975. */
  976. Calendar.IMG_ROOT = null;
  977. /**
  978. * Type constant used for renderers to represent an individual date (M/D/Y)
  979. * @property YAHOO.widget.Calendar.DATE
  980. * @static
  981. * @final
  982. * @type String
  983. */
  984. Calendar.DATE = "D";
  985. /**
  986. * Type constant used for renderers to represent an individual date across any year (M/D)
  987. * @property YAHOO.widget.Calendar.MONTH_DAY
  988. * @static
  989. * @final
  990. * @type String
  991. */
  992. Calendar.MONTH_DAY = "MD";
  993. /**
  994. * Type constant used for renderers to represent a weekday
  995. * @property YAHOO.widget.Calendar.WEEKDAY
  996. * @static
  997. * @final
  998. * @type String
  999. */
  1000. Calendar.WEEKDAY = "WD";
  1001. /**
  1002. * Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
  1003. * @property YAHOO.widget.Calendar.RANGE
  1004. * @static
  1005. * @final
  1006. * @type String
  1007. */
  1008. Calendar.RANGE = "R";
  1009. /**
  1010. * Type constant used for renderers to represent a month across any year
  1011. * @property YAHOO.widget.Calendar.MONTH
  1012. * @static
  1013. * @final
  1014. * @type String
  1015. */
  1016. Calendar.MONTH = "M";
  1017. /**
  1018. * Constant that represents the total number of date cells that are displayed in a given month
  1019. * @property YAHOO.widget.Calendar.DISPLAY_DAYS
  1020. * @static
  1021. * @final
  1022. * @type Number
  1023. */
  1024. Calendar.DISPLAY_DAYS = 42;
  1025. /**
  1026. * Constant used for halting the execution of the remainder of the render stack
  1027. * @property YAHOO.widget.Calendar.STOP_RENDER
  1028. * @static
  1029. * @final
  1030. * @type String
  1031. */
  1032. Calendar.STOP_RENDER = "S";
  1033. /**
  1034. * Constant used to represent short date field string formats (e.g. Tu or Feb)
  1035. * @property YAHOO.widget.Calendar.SHORT
  1036. * @static
  1037. * @final
  1038. * @type String
  1039. */
  1040. Calendar.SHORT = "short";
  1041. /**
  1042. * Constant used to represent long date field string formats (e.g. Monday or February)
  1043. * @property YAHOO.widget.Calendar.LONG
  1044. * @static
  1045. * @final
  1046. * @type String
  1047. */
  1048. Calendar.LONG = "long";
  1049. /**
  1050. * Constant used to represent medium date field string formats (e.g. Mon)
  1051. * @property YAHOO.widget.Calendar.MEDIUM
  1052. * @static
  1053. * @final
  1054. * @type String
  1055. */
  1056. Calendar.MEDIUM = "medium";
  1057. /**
  1058. * Constant used to represent single character date field string formats (e.g. M, T, W)
  1059. * @property YAHOO.widget.Calendar.ONE_CHAR
  1060. * @static
  1061. * @final
  1062. * @type String
  1063. */
  1064. Calendar.ONE_CHAR = "1char";
  1065. /**
  1066. * The set of default Config property keys and values for the Calendar
  1067. * @property YAHOO.widget.Calendar._DEFAULT_CONFIG
  1068. * @final
  1069. * @static
  1070. * @private
  1071. * @type Object
  1072. */
  1073. Calendar._DEFAULT_CONFIG = {
  1074. // Default values for pagedate and selected are not class level constants - they are set during instance creation
  1075. PAGEDATE : {key:"pagedate", value:null},
  1076. SELECTED : {key:"selected", value:null},
  1077. TITLE : {key:"title", value:""},
  1078. CLOSE : {key:"close", value:false},
  1079. IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
  1080. MINDATE : {key:"mindate", value:null},
  1081. MAXDATE : {key:"maxdate", value:null},
  1082. MULTI_SELECT : {key:"multi_select", value:false},
  1083. START_WEEKDAY : {key:"start_weekday", value:0},
  1084. SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
  1085. SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
  1086. SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
  1087. HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
  1088. NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
  1089. NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
  1090. MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
  1091. MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
  1092. WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
  1093. WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
  1094. WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
  1095. WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
  1096. LOCALE_MONTHS:{key:"locale_months", value:"long"},
  1097. LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
  1098. DATE_DELIMITER:{key:"date_delimiter", value:","},
  1099. DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
  1100. DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
  1101. MY_MONTH_POSITION:{key:"my_month_position", value:1},
  1102. MY_YEAR_POSITION:{key:"my_year_position", value:2},
  1103. MD_MONTH_POSITION:{key:"md_month_position", value:1},
  1104. MD_DAY_POSITION:{key:"md_day_position", value:2},
  1105. MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
  1106. MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
  1107. MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
  1108. MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
  1109. MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
  1110. MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
  1111. MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""},
  1112. NAV: {key:"navigator", value: null},
  1113. STRINGS : {
  1114. key:"strings",
  1115. value: {
  1116. previousMonth : "Previous Month",
  1117. nextMonth : "Next Month",
  1118. close: "Close"
  1119. },
  1120. supercedes : ["close", "title"]
  1121. }
  1122. };
  1123. var DEF_CFG = Calendar._DEFAULT_CONFIG;
  1124. /**
  1125. * The set of Custom Event types supported by the Calendar
  1126. * @property YAHOO.widget.Calendar._EVENT_TYPES
  1127. * @final
  1128. * @static
  1129. * @private
  1130. * @type Object
  1131. */
  1132. Calendar._EVENT_TYPES = {
  1133. BEFORE_SELECT : "beforeSelect",
  1134. SELECT : "select",
  1135. BEFORE_DESELECT : "beforeDeselect",
  1136. DESELECT : "deselect",
  1137. CHANGE_PAGE : "changePage",
  1138. BEFORE_RENDER : "beforeRender",
  1139. RENDER : "render",
  1140. BEFORE_DESTROY : "beforeDestroy",
  1141. DESTROY : "destroy",
  1142. RESET : "reset",
  1143. CLEAR : "clear",
  1144. BEFORE_HIDE : "beforeHide",
  1145. HIDE : "hide",
  1146. BEFORE_SHOW : "beforeShow",
  1147. SHOW : "show",
  1148. BEFORE_HIDE_NAV : "beforeHideNav",
  1149. HIDE_NAV : "hideNav",
  1150. BEFORE_SHOW_NAV : "beforeShowNav",
  1151. SHOW_NAV : "showNav",
  1152. BEFORE_RENDER_NAV : "beforeRenderNav",
  1153. RENDER_NAV : "renderNav"
  1154. };
  1155. /**
  1156. * The set of default style constants for the Calendar
  1157. * @property YAHOO.widget.Calendar._STYLES
  1158. * @final
  1159. * @static
  1160. * @private
  1161. * @type Object
  1162. */
  1163. Calendar._STYLES = {
  1164. CSS_ROW_HEADER: "calrowhead",
  1165. CSS_ROW_FOOTER: "calrowfoot",
  1166. CSS_CELL : "calcell",
  1167. CSS_CELL_SELECTOR : "selector",
  1168. CSS_CELL_SELECTED : "selected",
  1169. CSS_CELL_SELECTABLE : "selectable",
  1170. CSS_CELL_RESTRICTED : "restricted",
  1171. CSS_CELL_TODAY : "today",
  1172. CSS_CELL_OOM : "oom",
  1173. CSS_CELL_OOB : "previous",
  1174. CSS_HEADER : "calheader",
  1175. CSS_HEADER_TEXT : "calhead",
  1176. CSS_BODY : "calbody",
  1177. CSS_WEEKDAY_CELL : "calweekdaycell",
  1178. CSS_WEEKDAY_ROW : "calweekdayrow",
  1179. CSS_FOOTER : "calfoot",
  1180. CSS_CALENDAR : "yui-calendar",
  1181. CSS_SINGLE : "single",
  1182. CSS_CONTAINER : "yui-calcontainer",
  1183. CSS_NAV_LEFT : "calnavleft",
  1184. CSS_NAV_RIGHT : "calnavright",
  1185. CSS_NAV : "calnav",
  1186. CSS_CLOSE : "calclose",
  1187. CSS_CELL_TOP : "calcelltop",
  1188. CSS_CELL_LEFT : "calcellleft",
  1189. CSS_CELL_RIGHT : "calcellright",
  1190. CSS_CELL_BOTTOM : "calcellbottom",
  1191. CSS_CELL_HOVER : "calcellhover",
  1192. CSS_CELL_HIGHLIGHT1 : "highlight1",
  1193. CSS_CELL_HIGHLIGHT2 : "highlight2",
  1194. CSS_CELL_HIGHLIGHT3 : "highlight3",
  1195. CSS_CELL_HIGHLIGHT4 : "highlight4"
  1196. };
  1197. Calendar.prototype = {
  1198. /**
  1199. * The configuration object used to set up the calendars various locale and style options.
  1200. * @property Config
  1201. * @private
  1202. * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
  1203. * @type Object
  1204. */
  1205. Config : null,
  1206. /**
  1207. * The parent CalendarGroup, only to be set explicitly by the parent group
  1208. * @property parent
  1209. * @type CalendarGroup
  1210. */
  1211. parent : null,
  1212. /**
  1213. * The index of this item in the parent group
  1214. * @property index
  1215. * @type Number
  1216. */
  1217. index : -1,
  1218. /**
  1219. * The collection of calendar table cells
  1220. * @property cells
  1221. * @type HTMLTableCellElement[]
  1222. */
  1223. cells : null,
  1224. /**
  1225. * 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].
  1226. * @property cellDates
  1227. * @type Array[](Number[])
  1228. */
  1229. cellDates : null,
  1230. /**
  1231. * The id that uniquely identifies this Calendar.
  1232. * @property id
  1233. * @type String
  1234. */
  1235. id : null,
  1236. /**
  1237. * The unique id associated with the Calendar's container
  1238. * @property containerId
  1239. * @type String
  1240. */
  1241. containerId: null,
  1242. /**
  1243. * 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.
  1244. * @property oDomContainer
  1245. * @type HTMLElement
  1246. */
  1247. oDomContainer : null,
  1248. /**
  1249. * A Date object representing today's date.
  1250. * @property today
  1251. * @type Date
  1252. */
  1253. today : null,
  1254. /**
  1255. * The list of render functions, along with required parameters, used to render cells.
  1256. * @property renderStack
  1257. * @type Array[]
  1258. */
  1259. renderStack : null,
  1260. /**
  1261. * A copy of the initial render functions created before rendering.
  1262. * @property _renderStack
  1263. * @private
  1264. * @type Array
  1265. */
  1266. _renderStack : null,
  1267. /**
  1268. * A reference to the CalendarNavigator instance created for this Calendar.
  1269. * Will be null if the "navigator" configuration property has not been set
  1270. * @property oNavigator
  1271. * @type CalendarNavigator
  1272. */
  1273. oNavigator : null,
  1274. /**
  1275. * The private list of initially selected dates.
  1276. * @property _selectedDates
  1277. * @private
  1278. * @type Array
  1279. */
  1280. _selectedDates : null,
  1281. /**
  1282. * A map of DOM event handlers to attach to cells associated with specific CSS class names
  1283. * @property domEventMap
  1284. * @type Object
  1285. */
  1286. domEventMap : null,
  1287. /**
  1288. * Protected helper used to parse Calendar constructor/init arguments.
  1289. *
  1290. * As of 2.4.0, Calendar supports a simpler constructor
  1291. * signature. This method reconciles arguments
  1292. * received in the pre 2.4.0 and 2.4.0 formats.
  1293. *
  1294. * @protected
  1295. * @method _parseArgs
  1296. * @param {Array} Function "arguments" array
  1297. * @return {Object} Object with id, container, config properties containing
  1298. * the reconciled argument values.
  1299. **/
  1300. _parseArgs : function(args) {
  1301. /*
  1302. 2.4.0 Constructors signatures
  1303. new Calendar(String)
  1304. new Calendar(HTMLElement)
  1305. new Calendar(String, ConfigObject)
  1306. new Calendar(HTMLElement, ConfigObject)
  1307. Pre 2.4.0 Constructor signatures
  1308. new Calendar(String, String)
  1309. new Calendar(String, HTMLElement)
  1310. new Calendar(String, String, ConfigObject)
  1311. new Calendar(String, HTMLElement, ConfigObject)
  1312. */
  1313. var nArgs = {id:null, container:null, config:null};
  1314. if (args && args.length && args.length > 0) {
  1315. switch (args.length) {
  1316. case 1:
  1317. nArgs.id = null;
  1318. nArgs.container = args[0];
  1319. nArgs.config = null;
  1320. break;
  1321. case 2:
  1322. if (Lang.isObject(args[1]) && !args[1].tagName && !(args[1] instanceof String)) {
  1323. nArgs.id = null;
  1324. nArgs.container = args[0];
  1325. nArgs.config = args[1];
  1326. } else {
  1327. nArgs.id = args[0];
  1328. nArgs.container = args[1];
  1329. nArgs.config = null;
  1330. }
  1331. break;
  1332. default: // 3+
  1333. nArgs.id = args[0];
  1334. nArgs.container = args[1];
  1335. nArgs.config = args[2];
  1336. break;
  1337. }
  1338. } else {
  1339. }
  1340. return nArgs;
  1341. },
  1342. /**
  1343. * Initializes the Calendar widget.
  1344. * @method init
  1345. *
  1346. * @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.
  1347. * @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.
  1348. * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
  1349. */
  1350. init : function(id, container, config) {
  1351. // Normalize 2.4.0, pre 2.4.0 args
  1352. var nArgs = this._parseArgs(arguments);
  1353. id = nArgs.id;
  1354. container = nArgs.container;
  1355. config = nArgs.config;
  1356. this.oDomContainer = Dom.get(container);
  1357. if (!this.oDomContainer.id) {
  1358. this.oDomContainer.id = Dom.generateId();
  1359. }
  1360. if (!id) {
  1361. id = this.oDomContainer.id + "_t";
  1362. }
  1363. this.id = id;
  1364. this.containerId = this.oDomContainer.id;
  1365. this.initEvents();
  1366. this.today = new Date();
  1367. DateMath.clearTime(this.today);
  1368. /**
  1369. * The Config object used to hold the configuration variables for the Calendar
  1370. * @property cfg
  1371. * @type YAHOO.util.Config
  1372. */
  1373. this.cfg = new YAHOO.util.Config(this);
  1374. /**
  1375. * The local object which contains the Calendar's options
  1376. * @property Options
  1377. * @type Object
  1378. */
  1379. this.Options = {};
  1380. /**
  1381. * The local object which contains the Calendar's locale settings
  1382. * @property Locale
  1383. * @type Object
  1384. */
  1385. this.Locale = {};
  1386. this.initStyles();
  1387. Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
  1388. Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
  1389. this.cellDates = [];
  1390. this.cells = [];
  1391. this.renderStack = [];
  1392. this._renderStack = [];
  1393. this.setupConfig();
  1394. if (config) {
  1395. this.cfg.applyConfig(config, true);
  1396. }
  1397. this.cfg.fireQueue();
  1398. },
  1399. /**
  1400. * Default Config listener for the iframe property. If the iframe config property is set to true,
  1401. * renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
  1402. *
  1403. * @method configIframe
  1404. */
  1405. configIframe : function(type, args, obj) {
  1406. var useIframe = args[0]