/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version 0.12.2
*/
/**
* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month ("one-up") or two-month ("two-up") interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
* @module calendar
* @title Calendar
* @namespace YAHOO.widget
* @requires yahoo,dom,event
*/
/**
* Calendar is the base class for the Calendar widget. In its most basic
* implementation, it has the ability to render a calendar widget on the page
* that can be manipulated to select a single date, move back and forth between
* months and years.
* <p>To construct the placeholder for the calendar widget, the code is as
* follows:
* <xmp>
* <div id="cal1Container"></div>
* </xmp>
* Note that the table can be replaced with any kind of element.
* </p>
* @namespace YAHOO.widget
* @class Calendar
* @constructor
* @param {String} id The id of the table element that will represent the calendar widget
* @param {String} containerId The id of the container div element that will wrap the calendar table
* @param {Object} config The configuration object containing the Calendar's arguments
*/
YAHOO.widget.Calendar = function(id, containerId, config) {
this.init(id, containerId, config);
};
/**
* The path to be used for images loaded for the Calendar
* @property YAHOO.widget.Calendar.IMG_ROOT
* @static
* @type String
*/
YAHOO.widget.Calendar.IMG_ROOT = (window.location.href.toLowerCase().indexOf("https") === 0 ? "https://a248.e.akamai.net/sec.yimg.com/i/" : "http://us.i1.yimg.com/us.yimg.com/i/");
/**
* Type constant used for renderers to represent an individual date (M/D/Y)
* @property YAHOO.widget.Calendar.DATE
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.DATE = "D";
/**
* Type constant used for renderers to represent an individual date across any year (M/D)
* @property YAHOO.widget.Calendar.MONTH_DAY
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.MONTH_DAY = "MD";
/**
* Type constant used for renderers to represent a weekday
* @property YAHOO.widget.Calendar.WEEKDAY
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.WEEKDAY = "WD";
/**
* Type constant used for renderers to represent a range of individual dates (M/D/Y-M/D/Y)
* @property YAHOO.widget.Calendar.RANGE
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.RANGE = "R";
/**
* Type constant used for renderers to represent a month across any year
* @property YAHOO.widget.Calendar.MONTH
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.MONTH = "M";
/**
* Constant that represents the total number of date cells that are displayed in a given month
* @property YAHOO.widget.Calendar.DISPLAY_DAYS
* @static
* @final
* @type Number
*/
YAHOO.widget.Calendar.DISPLAY_DAYS = 42;
/**
* Constant used for halting the execution of the remainder of the render stack
* @property YAHOO.widget.Calendar.STOP_RENDER
* @static
* @final
* @type String
*/
YAHOO.widget.Calendar.STOP_RENDER = "S";
YAHOO.widget.Calendar.prototype = {
/**
* The configuration object used to set up the calendars various locale and style options.
* @property Config
* @private
* @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
* @type Object
*/
Config : null,
/**
* The parent CalendarGroup, only to be set explicitly by the parent group
* @property parent
* @type CalendarGroup
*/
parent : null,
/**
* The index of this item in the parent group
* @property index
* @type Number
*/
index : -1,
/**
* The collection of calendar table cells
* @property cells
* @type HTMLTableCellElement[]
*/
cells : null,
/**
* The collection of calendar cell dates that is parallel to the cells collection. The array contains dates field arrays in the format of [YYYY, M, D].
* @property cellDates
* @type Array[](Number[])
*/
cellDates : null,
/**
* The id that uniquely identifies this calendar. This id should match the id of the placeholder element on the page.
* @property id
* @type String
*/
id : null,
/**
* The DOM element reference that points to this calendar's container element. The calendar will be inserted into this element when the shell is rendered.
* @property oDomContainer
* @type HTMLElement
*/
oDomContainer : null,
/**
* A Date object representing today's date.
* @property today
* @type Date
*/
today : null,
/**
* The list of render functions, along with required parameters, used to render cells.
* @property renderStack
* @type Array[]
*/
renderStack : null,
/**
* A copy of the initial render functions created before rendering.
* @property _renderStack
* @private
* @type Array
*/
_renderStack : null,
/**
* A Date object representing the month/year that the calendar is initially set to
* @property _pageDate
* @private
* @type Date
*/
_pageDate : null,
/**
* The private list of initially selected dates.
* @property _selectedDates
* @private
* @type Array
*/
_selectedDates : null,
/**
* A map of DOM event handlers to attach to cells associated with specific CSS class names
* @property domEventMap
* @type Object
*/
domEventMap : null
};
/**
* Initializes the Calendar widget.
* @method init
* @param {String} id The id of the table element that will represent the calendar widget
* @param {String} containerId The id of the container div element that will wrap the calendar table
* @param {Object} config The configuration object containing the Calendar's arguments
*/
YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
this.initEvents();
this.today = new Date();
YAHOO.widget.DateMath.clearTime(this.today);
this.id = id;
this.oDomContainer = document.getElementById(containerId);
/**
* The Config object used to hold the configuration variables for the Calendar
* @property cfg
* @type YAHOO.util.Config
*/
this.cfg = new YAHOO.util.Config(this);
/**
* The local object which contains the Calendar's options
* @property Options
* @type Object
*/
this.Options = {};
/**
* The local object which contains the Calendar's locale settings
* @property Locale
* @type Object
*/
this.Locale = {};
this.initStyles();
YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
this.cellDates = [];
this.cells = [];
this.renderStack = [];
this._renderStack = [];
this.setupConfig();
if (config) {
this.cfg.applyConfig(config, true);
}
this.cfg.fireQueue();
};
/**
* Renders the built-in IFRAME shim for the IE6 and below
* @method configIframe
*/
YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
var useIframe = args[0];
if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
if (useIframe) {
var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");
if (this.browser == "ie" && (pos == "absolute" || pos == "relative")) {
if (! YAHOO.util.Dom.inDocument(this.iframe)) {
this.iframe = document.createElement("iframe");
this.iframe.src = "javascript:false;";
YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
}
}
} else {
if (this.iframe) {
if (this.iframe.parentNode) {
this.iframe.parentNode.removeChild(this.iframe);
}
this.iframe = null;
}
}
}
};
/**
* Default handler for the "title" property
* @method configTitle
*/
YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
var title = args[0];
var close = this.cfg.getProperty("close");
var titleDiv;
if (title && title !== "") {
titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
titleDiv.innerHTML = title;
this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
} else {
titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
if (titleDiv) {
YAHOO.util.Event.purgeElement(titleDiv);
this.oDomContainer.removeChild(titleDiv);
}
if (! close) {
YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
}
}
};
/**
* Default handler for the "close" property
* @method configClose
*/
YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
var close = args[0];
var title = this.cfg.getProperty("title");
var linkClose;
if (close === true) {
linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
linkClose.href = "javascript:void(null);";
linkClose.className = "link-close";
YAHOO.util.Event.addListener(linkClose, "click", this.hide, this, true);
var imgClose = document.createElement("img");
imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + "us/my/bn/x_d.gif";
imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
linkClose.appendChild(imgClose);
this.oDomContainer.appendChild(linkClose);
YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
} else {
linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
if (linkClose) {
YAHOO.util.Event.purgeElement(linkClose);
this.oDomContainer.removeChild(linkClose);
}
if (! title || title === "") {
YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
}
}
};
/**
* Initializes Calendar's built-in CustomEvents
* @method initEvents
*/
YAHOO.widget.Calendar.prototype.initEvents = function() {
/**
* Fired before a selection is made
* @event beforeSelectEvent
*/
this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
/**
* Fired when a selection is made
* @event selectEvent
* @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
*/
this.selectEvent = new YAHOO.util.CustomEvent("select");
/**
* Fired before a selection is made
* @event beforeDeselectEvent
*/
this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
/**
* Fired when a selection is made
* @event deselectEvent
* @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
*/
this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
/**
* Fired when the Calendar page is changed
* @event changePageEvent
*/
this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
/**
* Fired before the Calendar is rendered
* @event beforeRenderEvent
*/
this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
/**
* Fired when the Calendar is rendered
* @event renderEvent
*/
this.renderEvent = new YAHOO.util.CustomEvent("render");
/**
* Fired when the Calendar is reset
* @event resetEvent
*/
this.resetEvent = new YAHOO.util.CustomEvent("reset");
/**
* Fired when the Calendar is cleared
* @event clearEvent
*/
this.clearEvent = new YAHOO.util.CustomEvent("clear");
this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
this.selectEvent.subscribe(this.onSelect, this, true);
this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
this.deselectEvent.subscribe(this.onDeselect, this, true);
this.changePageEvent.subscribe(this.onChangePage, this, true);
this.renderEvent.subscribe(this.onRender, this, true);
this.resetEvent.subscribe(this.onReset, this, true);
this.clearEvent.subscribe(this.onClear, this, true);
};
/**
* The default event function that is attached to a date link within a calendar cell
* when the calendar is rendered.
* @method doSelectCell
* @param {DOMEvent} e The event
* @param {Calendar} cal A reference to the calendar passed by the Event utility
*/
YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
var target = YAHOO.util.Event.getTarget(e);
var cell,index,d,date;
while (target.tagName.toLowerCase() != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
target = target.parentNode;
if (target.tagName.toLowerCase() == "html") {
return;
}
}
cell = target;
if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
index = cell.id.split("cell")[1];
d = cal.cellDates[index];
date = new Date(d[0],d[1]-1,d[2]);
var link;
if (cal.Options.MULTI_SELECT) {
link = cell.getElementsByTagName("a")[0];
if (link) {
link.blur();
}
var cellDate = cal.cellDates[index];
var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
if (cellDateIndex > -1) {
cal.deselectCell(index);
} else {
cal.selectCell(index);
}
} else {
link = cell.getElementsByTagName("a")[0];
if (link) {
link.blur();
}
cal.selectCell(index);
}
}
};
/**
* The event that is executed when the user hovers over a cell
* @method doCellMouseOver
* @param {DOMEvent} e The event
* @param {Calendar} cal A reference to the calendar passed by the Event utility
*/
YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
var target;
if (e) {
target = YAHOO.util.Event.getTarget(e);
} else {
target = this;
}
while (target.tagName.toLowerCase() != "td") {
target = target.parentNode;
if (target.tagName.toLowerCase() == "html") {
return;
}
}
if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
}
};
/**
* The event that is executed when the user moves the mouse out of a cell
* @method doCellMouseOut
* @param {DOMEvent} e The event
* @param {Calendar} cal A reference to the calendar passed by the Event utility
*/
YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
var target;
if (e) {
target = YAHOO.util.Event.getTarget(e);
} else {
target = this;
}
while (target.tagName.toLowerCase() != "td") {
target = target.parentNode;
if (target.tagName.toLowerCase() == "html") {
return;
}
}
if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
}
};
YAHOO.widget.Calendar.prototype.setupConfig = function() {
/**
* The month/year representing the current visible Calendar date (mm/yyyy)
* @config pagedate
* @type String
* @default today's date
*/
this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );
/**
* The date or range of dates representing the current Calendar selection
* @config selected
* @type String
* @default []
*/
this.cfg.addProperty("selected", { value:[], handler:this.configSelected } );
/**
* The title to display above the Calendar's month header
* @config title
* @type String
* @default ""
*/
this.cfg.addProperty("title", { value:"", handler:this.configTitle } );
/**
* Whether or not a close button should be displayed for this Calendar
* @config close
* @type Boolean
* @default false
*/
this.cfg.addProperty("close", { value:false, handler:this.configClose } );
/**
* Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
* @config iframe
* @type Boolean
* @default true
*/
this.cfg.addProperty("iframe", { value:true, handler:this.configIframe, validator:this.cfg.checkBoolean } );
/**
* The minimum selectable date in the current Calendar (mm/dd/yyyy)
* @config mindate
* @type String
* @default null
*/
this.cfg.addProperty("mindate", { value:null, handler:this.configMinDate } );
/**
* The maximum selectable date in the current Calendar (mm/dd/yyyy)
* @config maxdate
* @type String
* @default null
*/
this.cfg.addProperty("maxdate", { value:null, handler:this.configMaxDate } );
// Options properties
/**
* True if the Calendar should allow multiple selections. False by default.
* @config MULTI_SELECT
* @type Boolean
* @default false
*/
this.cfg.addProperty("MULTI_SELECT", { value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
/**
* The weekday the week begins on. Default is 0 (Sunday).
* @config START_WEEKDAY
* @type number
* @default 0
*/
this.cfg.addProperty("START_WEEKDAY", { value:0, handler:this.configOptions, validator:this.cfg.checkNumber } );
/**
* True if the Calendar should show weekday labels. True by default.
* @config SHOW_WEEKDAYS
* @type Boolean
* @default true
*/
this.cfg.addProperty("SHOW_WEEKDAYS", { value:true, handler:this.configOptions, validator:this.cfg.checkBoolean } );
/**
* True if the Calendar should show week row headers. False by default.
* @config SHOW_WEEK_HEADER
* @type Boolean
* @default false
*/
this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
/**
* True if the Calendar should show week row footers. False by default.
* @config SHOW_WEEK_FOOTER
* @type Boolean
* @default false
*/
this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
/**
* True if the Calendar should suppress weeks that are not a part of the current month. False by default.
* @config HIDE_BLANK_WEEKS
* @type Boolean
* @default false
*/
this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );
/**
* The image that should be used for the left navigation arrow.
* @config NAV_ARROW_LEFT
* @type String
* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif"
*/
this.cfg.addProperty("NAV_ARROW_LEFT", { value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.configOptions } );
/**
* The image that should be used for the left navigation arrow.
* @config NAV_ARROW_RIGHT
* @type String
* @default YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif"
*/
this.cfg.addProperty("NAV_ARROW_RIGHT", { value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.configOptions } );
// Locale properties
/**
* The short month labels for the current locale.
* @config MONTHS_SHORT
* @type String[]
* @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
*/
this.cfg.addProperty("MONTHS_SHORT", { value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.configLocale } );
/**
* The long month labels for the current locale.
* @config MONTHS_LONG
* @type String[]
* @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
*/
this.cfg.addProperty("MONTHS_LONG", { value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.configLocale } );
/**
* The 1-character weekday labels for the current locale.
* @config WEEKDAYS_1CHAR
* @type String[]
* @default ["S", "M", "T", "W", "T", "F", "S"]
*/
this.cfg.addProperty("WEEKDAYS_1CHAR", { value:["S", "M", "T", "W", "T", "F", "S"], handler:this.configLocale } );
/**
* The short weekday labels for the current locale.
* @config WEEKDAYS_SHORT
* @type String[]
* @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
*/
this.cfg.addProperty("WEEKDAYS_SHORT", { value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.configLocale } );
/**
* The medium weekday labels for the current locale.
* @config WEEKDAYS_MEDIUM
* @type String[]
* @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
*/
this.cfg.addProperty("WEEKDAYS_MEDIUM", { value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.configLocale } );
/**
* The long weekday labels for the current locale.
* @config WEEKDAYS_LONG
* @type String[]
* @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
*/
this.cfg.addProperty("WEEKDAYS_LONG", { value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.configLocale } );
/**
* Refreshes the locale values used to build the Calendar.
* @method refreshLocale
* @private
*/
var refreshLocale = function() {
this.cfg.refireEvent("LOCALE_MONTHS");
this.cfg.refireEvent("LOCALE_WEEKDAYS");
};
this.cfg.subscribeToConfigEvent("START_WEEKDAY", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("MONTHS_SHORT", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("MONTHS_LONG", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("WEEKDAYS_1CHAR", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("WEEKDAYS_SHORT", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("WEEKDAYS_MEDIUM", refreshLocale, this, true);
this.cfg.subscribeToConfigEvent("WEEKDAYS_LONG", refreshLocale, this, true);
/**
* The setting that determines which length of month labels should be used. Possible values are "short" and "long".
* @config LOCALE_MONTHS
* @type String
* @default "long"
*/
this.cfg.addProperty("LOCALE_MONTHS", { value:"long", handler:this.configLocaleValues } );
/**
* The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
* @config LOCALE_WEEKDAYS
* @type String
* @default "short"
*/
this.cfg.addProperty("LOCALE_WEEKDAYS", { value:"short", handler:this.configLocaleValues } );
/**
* The value used to delimit individual dates in a date string passed to various Calendar functions.
* @config DATE_DELIMITER
* @type String
* @default ","
*/
this.cfg.addProperty("DATE_DELIMITER", { value:",", handler:this.configLocale } );
/**
* The value used to delimit date fields in a date string passed to various Calendar functions.
* @config DATE_FIELD_DELIMITER
* @type String
* @default "/"
*/
this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.configLocale } );
/**
* The value used to delimit date ranges in a date string passed to various Calendar functions.
* @config DATE_RANGE_DELIMITER
* @type String
* @default "-"
*/
this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.configLocale } );
/**
* The position of the month in a month/year date string
* @config MY_MONTH_POSITION
* @type Number
* @default 1
*/
this.cfg.addProperty("MY_MONTH_POSITION", { value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the year in a month/year date string
* @config MY_YEAR_POSITION
* @type Number
* @default 2
*/
this.cfg.addProperty("MY_YEAR_POSITION", { value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the month in a month/day date string
* @config MD_MONTH_POSITION
* @type Number
* @default 1
*/
this.cfg.addProperty("MD_MONTH_POSITION", { value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the day in a month/year date string
* @config MD_DAY_POSITION
* @type Number
* @default 2
*/
this.cfg.addProperty("MD_DAY_POSITION", { value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the month in a month/day/year date string
* @config MDY_MONTH_POSITION
* @type Number
* @default 1
*/
this.cfg.addProperty("MDY_MONTH_POSITION", { value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the day in a month/day/year date string
* @config MDY_DAY_POSITION
* @type Number
* @default 2
*/
this.cfg.addProperty("MDY_DAY_POSITION", { value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );
/**
* The position of the year in a month/day/year date string
* @config MDY_YEAR_POSITION
* @type Number
* @default 3
*/
this.cfg.addProperty("MDY_YEAR_POSITION", { value:3, handler:this.configLocale, validator:this.cfg.checkNumber } );
};
/**
* The default handler for the "pagedate" property
* @method configPageDate
*/
YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
var val = args[0];
var month, year, aMonthYear;
if (val) {
if (val instanceof Date) {
val = YAHOO.widget.DateMath.findMonthStart(val);
this.cfg.setProperty("pagedate", val, true);
if (! this._pageDate) {
this._pageDate = this.cfg.getProperty("pagedate");
}
return;
} else {
aMonthYear = val.split(this.cfg.getProperty("DATE_FIELD_DELIMITER"));
month = parseInt(aMonthYear[this.cfg.getProperty("MY_MONTH_POSITION")-1], 10)-1;
year = parseInt(aMonthYear[this.cfg.getProperty("MY_YEAR_POSITION")-1], 10);
}
} else {
month = this.today.getMonth();
year = this.today.getFullYear();
}
this.cfg.setProperty("pagedate", new Date(year, month, 1), true);
if (! this._pageDate) {
this._pageDate = this.cfg.getProperty("pagedate");
}
};
/**
* The default handler for the "mindate" property
* @method configMinDate
*/
YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
var val = args[0];
if (typeof val == 'string') {
val = this._parseDate(val);
this.cfg.setProperty("mindate", new Date(val[0],(val[1]-1),val[2]));
}
};
/**
* The default handler for the "maxdate" property
* @method configMaxDate
*/
YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
var val = args[0];
if (typeof val == 'string') {
val = this._parseDate(val);
this.cfg.setProperty("maxdate", new Date(val[0],(val[1]-1),val[2]));
}
};
/**
* The default handler for the "selected" property
* @method configSelected
*/
YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
var selected = args[0];
if (selected) {
if (typeof selected == 'string') {
this.cfg.setProperty("selected", this._parseDates(selected), true);
}
}
if (! this._selectedDates) {
this._selectedDates = this.cfg.getProperty("selected");
}
};
/**
* The default handler for all configuration options properties
* @method configOptions
*/
YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
type = type.toUpperCase();
var val = args[0];
this.Options[type] = val;
};
/**
* The default handler for all configuration locale properties
* @method configLocale
*/
YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
type = type.toUpperCase();
var val = args[0];
this.Locale[type] = val;
this.cfg.refireEvent("LOCALE_MONTHS");
this.cfg.refireEvent("LOCALE_WEEKDAYS");
};
/**
* The default handler for all configuration locale field length properties
* @method configLocaleValues
*/
YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
type = type.toUpperCase();
var val = args[0];
switch (type) {
case "LOCALE_MONTHS":
switch (val) {
case "short":
this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_SHORT").concat();
break;
case "long":
this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_LONG").concat();
break;
}
break;
case "LOCALE_WEEKDAYS":
switch (val) {
case "1char":
this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_1CHAR").concat();
break;
case "short":
this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_SHORT").concat();
break;
case "medium":
this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_MEDIUM").concat();
break;
case "long":
this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_LONG").concat();
break;
}
var START_WEEKDAY = this.cfg.getProperty("START_WEEKDAY");
if (START_WEEKDAY > 0) {
for (var w=0;w<START_WEEKDAY;++w) {
this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
}
}
break;
}
};
/**
* Defines the style constants for the Calendar
* @method initStyles
*/
YAHOO.widget.Calendar.prototype.initStyles = function() {
/**
* Collection of Style constants for the Calendar
* @property Style
*/
this.Style = {
/**
* @property Style.CSS_ROW_HEADER
*/
CSS_ROW_HEADER: "calrowhead",
/**
* @property Style.CSS_ROW_FOOTER
*/
CSS_ROW_FOOTER: "calrowfoot",
/**
* @property Style.CSS_CELL
*/
CSS_CELL : "calcell",
/**
* @property Style.CSS_CELL_SELECTED
*/
CSS_CELL_SELECTED : "selected",
/**
* @property Style.CSS_CELL_SELECTABLE
*/
CSS_CELL_SELECTABLE : "selectable",
/**
* @property Style.CSS_CELL_RESTRICTED
*/
CSS_CELL_RESTRICTED : "restricted",
/**
* @property Style.CSS_CELL_TODAY
*/
CSS_CELL_TODAY : "today",
/**
* @property Style.CSS_CELL_OOM
*/
CSS_CELL_OOM : "oom",
/**
* @property Style.CSS_CELL_OOB
*/
CSS_CELL_OOB : "previous",
/**
* @property Style.CSS_HEADER
*/
CSS_HEADER : "calheader",
/**
* @property Style.CSS_HEADER_TEXT
*/
CSS_HEADER_TEXT : "calhead",
/**
* @property Style.CSS_WEEKDAY_CELL
*/
CSS_WEEKDAY_CELL : "calweekdaycell",
/**
* @property Style.CSS_WEEKDAY_ROW
*/
CSS_WEEKDAY_ROW : "calweekdayrow",
/**
* @property Style.CSS_FOOTER
*/
CSS_FOOTER : "calfoot",
/**
* @property Style.CSS_CALENDAR
*/
CSS_CALENDAR : "yui-calendar",
/**
* @property Style.CSS_SINGLE
*/
CSS_SINGLE : "single",
/**
* @property Style.CSS_CONTAINER
*/
CSS_CONTAINER : "yui-calcontainer",
/**
* @property Style.CSS_NAV_LEFT
*/
CSS_NAV_LEFT : "calnavleft",
/**
* @property Style.CSS_NAV_RIGHT
*/
CSS_NAV_RIGHT : "calnavright",
/**
* @property Style.CSS_CELL_TOP
*/
CSS_CELL_TOP : "calcelltop",
/**
* @property Style.CSS_CELL_LEFT
*/
CSS_CELL_LEFT : "calcellleft",
/**
* @property Style.CSS_CELL_RIGHT
*/
CSS_CELL_RIGHT :