calendar-base.js revision 968de103b6c098098a5166a4de778706cbb825e0
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The CalendarBase submodule is a basic UI calendar view that displays
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * a range of dates in a two-dimensional month grid, with one or more
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * months visible at a single time. CalendarBase supports custom date
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * rendering, multiple calendar panes, and selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @module calendar
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @submodule calendar-base
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassvar getCN = Y.ClassNameManager.getClassName,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CALENDAR = 'calendar',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_GRID = getCN(CALENDAR, 'grid'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_LEFT_GRID = getCN(CALENDAR, 'left-grid'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_RIGHT_GRID = getCN(CALENDAR, 'right-grid'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_BODY = getCN(CALENDAR, 'body'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_HD = getCN(CALENDAR, 'header'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_HD_LABEL = getCN(CALENDAR, 'header-label'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_WDAYROW = getCN(CALENDAR, 'weekdayrow'),
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai CAL_WDAY = getCN(CALENDAR, 'weekday'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_COL_HIDDEN = getCN(CALENDAR, 'column-hidden'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_DAY_SELECTED = getCN(CALENDAR, 'day-selected'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass SELECTION_DISABLED = getCN(CALENDAR, 'selection-disabled'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_ROW = getCN(CALENDAR, 'row'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_DAY = getCN(CALENDAR, 'day'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_PREVMONTH_DAY = getCN(CALENDAR, 'prevmonth-day'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_NEXTMONTH_DAY = getCN(CALENDAR, 'nextmonth-day'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_ANCHOR = getCN(CALENDAR, 'anchor'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CAL_PANE = getCN(CALENDAR, 'pane'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass L = Y.Lang,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass node = Y.Node,
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai create = node.create,
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai substitute = Y.substitute,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each = Y.each,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass hasVal = Y.Array.hasValue,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass iOf = Y.Array.indexOf,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass hasKey = Y.Object.hasKey,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass setVal = Y.Object.setValue,
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai owns = Y.Object.owns,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass isEmpty = Y.Object.isEmpty,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ydate = Y.DataType.Date;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/** Create a calendar view to represent a single or multiple
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai * month range of dates, rendered as a grid with date and
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai * weekday labels.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai * @class CalendarBase
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai * @extends Widget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param config {Object} Configuration object (see Configuration
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * attributes)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @constructor
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassfunction CalendarBase(config) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CalendarBase.superclass.constructor.apply ( this, arguments );
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.CalendarBase = Y.extend( CalendarBase, Y.Widget, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A storage for various properties of individual month
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * panes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _paneProperties
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Object
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _paneProperties : {},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The number of month panes in the calendar, deduced
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * from the CONTENT_TEMPLATE's number of {calendar_grid}
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * tokens.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _paneNumber
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Number
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _paneNumber : 1,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The unique id used to prefix various elements of this
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * calendar instance.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _calendarId
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type String
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _calendarId : null,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The hash map of selected dates, populated with
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * selectDates() and deselectDates() methods
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _selectedDates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Object
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _selectedDates : {},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A private copy of the rules object, populated
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * by setting the customRenderer attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _rules
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Object
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _rules : {},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A private copy of the filterFunction, populated
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * by setting the customRenderer attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _filterFunction
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Function
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _filterFunction : null,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Storage for calendar cells modified by any custom
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * formatting. The storage is cleared, used to restore
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * cells to the original state, and repopulated accordingly
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * when the calendar is rerendered.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @property _storedDateCells
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @type Object
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _storedDateCells : {},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * Designated initializer
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * Initializes instance-level properties of
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * calendar.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method initializer
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai initializer : function () {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._paneProperties = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._calendarId = Y.guid('calendar');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates = {};
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._rules = {};
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.storedDateCells = {};
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * renderUI implementation
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Creates a visual representation of the calendar based on existing parameters.
f10a402d8cc7dba5b475e38d8beaf6b79342c927Tilo Mitra * @method renderUI
f10a402d8cc7dba5b475e38d8beaf6b79342c927Tilo Mitra */
f10a402d8cc7dba5b475e38d8beaf6b79342c927Tilo Mitra renderUI : function () {
f10a402d8cc7dba5b475e38d8beaf6b79342c927Tilo Mitra var contentBox = this.get('contentBox');
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai contentBox.appendChild(this._initCalendarHTML(this.get('date')));
f10a402d8cc7dba5b475e38d8beaf6b79342c927Tilo Mitra if (this.get('showPrevMonth')) {
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai this._afterShowPrevMonthChange();
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai }
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai if (this.get('showNextMonth')) {
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai this._afterShowNextMonthChange();
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderCustomRules();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderSelectedDates();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * bindUI implementation
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * Assigns listeners to relevant events that change the state
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * of the calendar.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method bindUI
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai bindUI : function () {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.after('dateChange', this._afterDateChange);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.after('showPrevMonthChange', this._afterShowPrevMonthChange);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.after('showNextMonthChange', this._afterShowNextMonthChange);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.after('headerRendererChange', this._afterHeaderRendererChange);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this.after('customRendererChange', this._afterCustomRendererChange);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._bindCalendarEvents();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * syncUI implementation
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * Update the scroll position, based on the current value of scrollY
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method syncUI
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai syncUI : function () {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (this.get('showPrevMonth')) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._afterShowPrevMonthChange();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
f7240e17b052fc7215fbe9e0f77da32b21d1da78Satyen Desai if (this.get('showNextMonth')) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._afterShowNextMonthChange();
f7240e17b052fc7215fbe9e0f77da32b21d1da78Satyen Desai }
f7240e17b052fc7215fbe9e0f77da32b21d1da78Satyen Desai },
f7240e17b052fc7215fbe9e0f77da32b21d1da78Satyen Desai
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * An internal utility method that generates a list of selected dates
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * from the hash storage.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _getSelectedDatesList
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return {Array} The array of `Date`s that are currently selected.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly _getSelectedDatesList : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var output = [];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each (this._selectedDates, function (year) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each (year, function (month) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each (month, function (day) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass output.push (day);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return output;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method that returns all dates selected in a specific month.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _getSelectedDatesInMonth
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate corresponding to the month for which selected dates
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * are requested.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @protected
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @return {Array} The array of `Date`s in a given month that are currently selected.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _getSelectedDatesInMonth : function (oDate) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai var year = oDate.getFullYear(),
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai month = oDate.getMonth();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (hasKey(this._selectedDates, year) && hasKey(this._selectedDates[year], month)) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai return Y.Object.values(this._selectedDates[year][month]);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return [];
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * An internal rendering method that modifies a date cell to have the
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * selected CSS class if the date cell is visible.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _renderSelectedDate
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate The date corresponding to a specific date cell.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _renderSelectedDate : function (oDate) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (this._isDateVisible(oDate)) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._dateToNode(oDate).addClass(CAL_DAY_SELECTED);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * An internal rendering method that modifies a date cell to remove the
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * selected CSS class if the date cell is visible.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _renderUnelectedDate
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate The date corresponding to a specific date cell.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _renderUnselectedDate : function (oDate) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (this._isDateVisible(oDate)) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._dateToNode(oDate).removeClass(CAL_DAY_SELECTED);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * An internal utility method that checks whether a particular date
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * is in the current view of the calendar.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _isDateVisible
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} oDate The date corresponding to a specific date cell.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return {boolean} Returns true if the given date is in the current
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai * view of the calendar.
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly */
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai _isDateVisible : function (oDate) {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai var minDate = this.get("date"),
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai maxDate = ydate.addMonths(minDate, this._paneNumber - 1),
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai oDateTime = this._normalizeDate(oDate).getTime();
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai if (minDate.getTime() <= oDateTime && oDateTime <= maxDate) {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai return true;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai }
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai else {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai return false;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai }
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai },
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly /**
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * An internal parsing method that receives a String list of numbers
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * and number ranges (of the form "1,2,3,4-6,7-9,10,11" etc.) and checks
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * whether a specific number is included in this list. Used for looking
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * up dates in the customRenderer rule set.
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly *
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * @method _isNumInList
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * @param {Number} num The number to look for in a list.
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * @param {String} strList The list of numbers of the form "1,2,3,4-6,7-8,9", etc.
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * @private
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly * @return {boolean} Returns true if the given number is in the given list.
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly */
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly _isNumInList : function (num, strList) {
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly if (strList == "all") {
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly return true;
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly }
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly else {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai var elements = strList.split(","),
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai val;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai for (val in elements) {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai var range = elements[val].split("-");
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai if (range.length == 2 && num >= parseInt(range[0], 10) && num <= parseInt(range[1], 10)) {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai return true;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai }
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai else if (range.length == 1 && (parseInt(elements[val], 10) == num)) {
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai return true;
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return false;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Given a specific date, returns an array of rules (from the customRenderer rule set)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * that the given date matches.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _getRulesForDate
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} oDate The date for which an array of rules is needed
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return {Array} Returns an array of `String`s, each containg the name of
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * a rule that the given date matches.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _getRulesForDate : function (oDate) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var year = oDate.getFullYear(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass month = oDate.getMonth(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass date = oDate.getDate(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass wday = oDate.getDay(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass rules = this._rules,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass outputRules = [],
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass years, months, dates, days;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (years in rules) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this._isNumInList(year, years)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (L.isString(rules[years])) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass outputRules.push(rules[years]);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (months in rules[years]) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this._isNumInList(month, months)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (L.isString(rules[years][months])) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass outputRules.push(rules[years][months]);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (dates in rules[years][months]) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (this._isNumInList(date, dates)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (L.isString(rules[years][months][dates])) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass outputRules.push(rules[years][months][dates]);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (days in rules[years][months][dates]) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (this._isNumInList(wday, days)) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (L.isString(rules[years][months][dates][days])) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai outputRules.push(rules[years][months][dates][days]);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai return outputRules;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method which, given a specific date and a name of the rule,
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * checks whether the date matches the given rule.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _matchesRule
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate The date to check
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {String} rule The name of the rule that the date should match.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @return {boolean} Returns true if the date matches the given rule.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai *
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _matchesRule : function (oDate, rule) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai return (iOf(this._getRulesForDate(oDate), rule) >= 0);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method which checks whether a given date matches the `enabledDatesRule`
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * or does not match the `disabledDatesRule` and therefore whether it can be selected.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _canBeSelected
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate The date to check
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @return {boolean} Returns true if the date can be selected; false otherwise.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _canBeSelected : function (oDate) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var enabledDatesRule = this.get("enabledDatesRule"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass disabledDatesRule = this.get("disabledDatesRule");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (enabledDatesRule) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._matchesRule(oDate, enabledDatesRule);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else if (disabledDatesRule) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return !this._matchesRule(oDate, disabledDatesRule);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return true;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Selects a given date or array of dates.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method selectDates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date|Array} dates A `Date` or `Array` of `Date`s.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass selectDates : function (dates) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (ydate.isValidDate(dates)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._addDateToSelection(dates);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else if (L.isArray(dates)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._addDatesToSelection(dates);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Deselects a given date or array of dates, or deselects
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * all dates if no argument is specified.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method deselectDates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date|Array} [dates] A `Date` or `Array` of `Date`s, or no
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * argument if all dates should be deselected.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass deselectDates : function (dates) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (dates == null) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._clearSelection();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else if (ydate.isValidDate(dates)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._removeDateFromSelection(dates);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else if (L.isArray(dates)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._removeDatesFromSelection(dates);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that adds a given date to selection..
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _addDateToSelection
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} oDate The date to add to selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Number} [index] An optional parameter that is used
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * to differentiate between individual date selections and multiple
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * date selections.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _addDateToSelection : function (oDate, index) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this._canBeSelected(oDate)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var year = oDate.getFullYear(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass month = oDate.getMonth(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass day = oDate.getDate();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (hasKey(this._selectedDates, year)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (hasKey(this._selectedDates[year], month)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year][month][day] = oDate;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year][month] = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year][month][day] = oDate;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year] = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year][month] = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates[year][month][day] = oDate;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates = setVal(this._selectedDates, [year, month, day], oDate);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderSelectedDate(oDate);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (index == null) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._fireSelectionChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that adds a given list of dates to selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _addDatesToSelection
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Array} datesArray The list of dates to add to selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _addDatesToSelection : function (datesArray) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each(datesArray, this._addDateToSelection, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._fireSelectionChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that adds a given range of dates to selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _addDateRangeToSelection
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} startDate The first date of the given range.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} endDate The last date of the given range.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _addDateRangeToSelection : function (startDate, endDate) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var timezoneDifference = (endDate.getTimezoneOffset() - startDate.getTimezoneOffset())*60000,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass startTime = startDate.getTime(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass endTime = endDate.getTime();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (startTime > endTime) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var tempTime = startTime;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass startTime = endTime;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass endTime = tempTime + timezoneDifference;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass endTime = endTime - timezoneDifference;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var time = startTime; time <= endTime; time += 86400000) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var addedDate = new Date(time);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass addedDate.setHours(12);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._addDateToSelection(addedDate, time);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._fireSelectionChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that removes a given date from selection..
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _removeDateFromSelection
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} oDate The date to remove from selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Number} [index] An optional parameter that is used
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * to differentiate between individual date selections and multiple
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * date selections.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _removeDateFromSelection : function (oDate, index) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var year = oDate.getFullYear(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass month = oDate.getMonth(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass day = oDate.getDate();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (hasKey(this._selectedDates, year) &&
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass hasKey(this._selectedDates[year], month) &&
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass hasKey(this._selectedDates[year][month], day)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass delete this._selectedDates[year][month][day];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderUnselectedDate(oDate);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (index == null) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._fireSelectionChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method that removes a given list of dates from selection.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _removeDatesFromSelection
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Array} datesArray The list of dates to remove from selection.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _removeDatesFromSelection : function (datesArray) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai each(datesArray, this._removeDateDromSelection);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._fireSelectionChange();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method that removes a given range of dates from selection.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _removeDateRangeFromSelection
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} startDate The first date of the given range.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} endDate The last date of the given range.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _removeDateRangeFromSelection : function (startDate, endDate) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai var startTime = startDate.getTime(),
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai endTime = endDate.getTime();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai for (var time = startTime; time <= endTime; time += 86400000) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._removeDateFromSelection(new Date(time), time);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai this._fireSelectionChange();
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method that removes all dates from selection.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _clearSelection
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {boolean} noevent A Boolean specifying whether a selectionChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * event should be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _clearSelection : function (noevent) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._selectedDates = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.get("contentBox").all("." + CAL_DAY_SELECTED).removeClass(CAL_DAY_SELECTED);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!noevent) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._fireSelectionChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that fires a selectionChange event.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _fireSelectionChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _fireSelectionChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Fired when the set of selected dates changes. Contains a payload with
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * a `newSelection` property with an array of selected dates.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @event selectionChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.fire("selectionChange", {newSelection: this._getSelectedDatesList()});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
479b9ac417be02467aadae8cd650d29050001f0bSatyen Desai * A utility method that restores cells modified by custom formatting.
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly * @method _restoreModifiedCells
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly * @private
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly */
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly _restoreModifiedCells : function () {
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var contentbox = this.get("contentBox"),
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly id;
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly for (id in this._storedDateCells) {
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly contentbox.one("#" + id).replace(this._storedDateCells[id]);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly delete this._storedDateCells[id];
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly }
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly },
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly /**
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai * A rendering assist method that renders all cells modified by the customRenderer
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly * rules, as well as the enabledDatesRule and disabledDatesRule.
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly * @method _renderCustomRules
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly * @private
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly */
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai _renderCustomRules : function () {
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai this.get("contentBox").all("." + CAL_DAY + ",." + CAL_NEXTMONTH_DAY).removeClass(SELECTION_DISABLED);
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai if (!isEmpty(this._rules)) {
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var enRule = this.get("enabledDatesRule"),
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly disRule = this.get("disabledDatesRule");
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly for (var paneNum = 0; paneNum < this._paneNumber; paneNum++) {
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var paneDate = ydate.addMonths(this.get("date"), paneNum);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var dateArray = ydate.listOfDatesInMonth(paneDate);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly each(dateArray, function (date) {
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai var matchingRules = this._getRulesForDate(date);
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai if (matchingRules.length > 0) {
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai var dateNode = this._dateToNode(date);
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly if ((enRule && !(iOf(matchingRules, enRule) >= 0)) ||
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly (disRule && (iOf(matchingRules, disRule) >= 0))) {
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai dateNode.addClass(SELECTION_DISABLED);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly }
609b3fdb3368975ebd66bf9ef6a074e3ca726524Jenny Donnelly
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly if (L.isFunction(this._filterFunction)) {
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai this._storedDateCells[dateNode.get("id")] = dateNode.cloneNode(true);
aa1e03f2af02ffea69e75323bf4fff95cbf736c5Satyen Desai this._filterFunction (date, dateNode, matchingRules);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly }
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly }
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A rendering assist method that renders all cells that are currently selected.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _renderSelectedDates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _renderSelectedDates : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.get("contentBox").all("." + CAL_DAY_SELECTED).removeClass(CAL_DAY_SELECTED);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
38dc51e07d95d1f02b709139ee7fe8caab01ad61Satyen Desai for (var paneNum = 0; paneNum < this._paneNumber; paneNum++) {
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var paneDate = ydate.addMonths(this.get("date"), paneNum);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly var dateArray = this._getSelectedDatesInMonth(paneDate);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly each(dateArray, function (date) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._dateToNode(date).addClass(CAL_DAY_SELECTED);
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly },
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
d5daadf7c87a641483741ee68c26b343acb5717cJenny Donnelly },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that converts a date to the node wrapping the calendar cell
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * the date corresponds to..
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _dateToNode
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai * @param {Date} oDate The date to convert to Node
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai * @protected
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai * @return {Node} The node wrapping the DOM element of the cell the date
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai * corresponds to.
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai */
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai _dateToNode : function (oDate) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var day = oDate.getDate(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 0,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass daymod = day%7,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass paneNum = (12 + oDate.getMonth() - this.get("date").getMonth()) % 12,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass paneId = this._calendarId + "_pane_" + paneNum,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass cutoffCol = this._paneProperties[paneId].cutoffCol;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass switch (daymod) {
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai case (0):
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai if (cutoffCol >= 6) {
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai col = 12;
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai }
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai else {
c32ac843533f2b40173501ca749de5d972f101c4Satyen Desai col = 5;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (1):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 6;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (2):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (cutoffCol > 0) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 7;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 0;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (3):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (cutoffCol > 1) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 8;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 1;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (4):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (cutoffCol > 2) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 9;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 2;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (5):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (cutoffCol > 3) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 10;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 3;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass case (6):
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (cutoffCol > 4) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 11;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass col = 4;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return(this.get("contentBox").one("#" + this._calendarId + "_pane_" + paneNum + "_" + col + "_" + day));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A utility method that converts a node corresponding to the DOM element of
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * the cell for a particular date to that date.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _nodeToDate
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} oNode The Node wrapping the DOM element of a particular date cell.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @return {Date} The date corresponding to the DOM element that the given node wraps.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _nodeToDate : function (oNode) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var idParts = oNode.get("id").split("_").reverse(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass paneNum = parseInt(idParts[2], 10),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass day = parseInt(idParts[0], 10);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var shiftedDate = ydate.addMonths(this.get("date"), paneNum),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass year = shiftedDate.getFullYear(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass month = shiftedDate.getMonth();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return new Date(year, month, day, 12, 0, 0, 0);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A placeholder method, called from bindUI, to bind the Calendar events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _bindCalendarEvents
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _bindCalendarEvents : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A utility method that normalizes a given date by converting it to the 1st
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * day of the month the date is in, with the time set to noon.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _normalizeDate
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} oDate The date to normalize
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @protected
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @return {Date} The normalized date, set to the first of the month, with time
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * set to noon.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _normalizeDate : function (date) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai return new Date(date.getFullYear(), date.getMonth(), 1, 12, 0, 0, 0);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A render assist utility method that computes the cutoff column for the calendar
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * rendering mask.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @method _getCutoffColumn
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Date} date The date of the month grid to compute the cutoff column for.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @param {Number} firstday The first day of the week (modified by internationalized calendars)
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @return {Number} The number of the cutoff column.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _getCutoffColumn : function (date, firstday) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var distance = this._normalizeDate(date).getDay() - firstday;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var cutOffColumn = 6 - (distance + 7)%7;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return cutOffColumn;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A render assist method that turns on the view of the previous month's dates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * in a given calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _turnPrevMonthOn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The calendar pane that needs its previous month's dates view
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * modified.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _turnPrevMonthOn : function (pane) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var pane_id = pane.get("id"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane_date = this._paneProperties[pane_id].paneDate,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass daysInPrevMonth = ydate.daysInMonth(ydate.addMonths(pane_date, -1));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!this._paneProperties[pane_id].hasOwnProperty("daysInPrevMonth")) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._paneProperties[pane_id].daysInPrevMonth = 0;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (daysInPrevMonth != this._paneProperties[pane_id].daysInPrevMonth) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._paneProperties[pane_id].daysInPrevMonth = daysInPrevMonth;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var cell = 5; cell >= 0; cell--)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_" + cell + "_" + (cell-5)).setContent(daysInPrevMonth--);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A render assist method that turns off the view of the previous month's dates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * in a given calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _turnPrevMonthOff
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The calendar pane that needs its previous month's dates view
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * modified.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _turnPrevMonthOff : function (pane) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var pane_id = pane.get("id");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._paneProperties[pane_id].daysInPrevMonth = 0;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var cell = 5; cell >= 0; cell--)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_" + cell + "_" + (cell-5)).setContent("&nbsp;");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A render assist method that cleans up the last few cells in the month grid
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * when the number of days in the month changes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _cleanUpNextMonthCells
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The calendar pane that needs the last date cells cleaned up.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _cleanUpNextMonthCells : function (pane) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var pane_id = pane.get("id");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_6_29").removeClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_7_30").removeClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_8_31").removeClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_0_30").removeClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_1_31").removeClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A render assist method that turns on the view of the next month's dates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * in a given calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _turnNextMonthOn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The calendar pane that needs its next month's dates view
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * modified.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _turnNextMonthOn : function (pane) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var dayCounter = 1,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane_id = pane.get("id"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass daysInMonth = this._paneProperties[pane_id].daysInMonth,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass cutoffCol = this._paneProperties[pane_id].cutoffCol;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var cell = daysInMonth - 22; cell < cutoffCol + 7; cell++)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_" + cell + "_" + (cell+23)).setContent(dayCounter++).addClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var startingCell = cutoffCol;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (daysInMonth == 31 && (cutoffCol <= 1)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass startingCell = 2;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else if (daysInMonth== 30 && cutoffCol == 0) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass startingCell = 1;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var cell = startingCell ; cell < cutoffCol + 7; cell++) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pane.one("#" + pane_id + "_" + cell + "_" + (cell+30)).setContent(dayCounter++).addClass(CAL_NEXTMONTH_DAY);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * A render assist method that turns off the view of the next month's dates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * in a given calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _turnNextMonthOff
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The calendar pane that needs its next month's dates view
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * modified.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai * @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _turnNextMonthOff : function (pane) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var pane_id = pane.get("id"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass daysInMonth = this._paneProperties[pane_id].daysInMonth,
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai cutoffCol = this._paneProperties[pane_id].cutoffCol;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai for (var cell = daysInMonth - 22; cell <= 12; cell++)
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai pane.one("#" + pane_id + "_" + cell + "_" + (cell+23)).setContent("&nbsp;").addClass(CAL_NEXTMONTH_DAY);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai var startingCell = 0;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai if (daysInMonth == 31 && (cutoffCol <= 1)) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai startingCell = 2;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai else if (daysInMonth == 30 && cutoffCol == 0) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai startingCell = 1;
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai for (var cell = startingCell ; cell <= 12; cell++) {
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai pane.one("#" + pane_id + "_" + cell + "_" + (cell+30)).setContent("&nbsp;").addClass(CAL_NEXTMONTH_DAY);
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai }
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The handler for the change in the showNextMonth attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _afterShowNextMonthChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterShowNextMonthChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var contentBox = this.get('contentBox'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass lastPane = contentBox.one("#" + this._calendarId + "_pane_" + (this._paneNumber - 1));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._cleanUpNextMonthCells(lastPane);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this.get('showNextMonth')) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._turnNextMonthOn(lastPane);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._turnNextMonthOff(lastPane);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The handler for the change in the showPrevMonth attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _afterShowPrevMonthChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterShowPrevMonthChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var contentBox = this.get('contentBox'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass firstPane = contentBox.one("#" + this._calendarId + "_pane_" + 0);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this.get('showPrevMonth')) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._turnPrevMonthOn(firstPane);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._turnPrevMonthOff(firstPane);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The handler for the change in the headerRenderer attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _afterHeaderRendererChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterHeaderRendererChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var headerCell = this.get('contentBox').one("." + CAL_HD).one("h4");
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith headerCell.setContent(this._updateCalendarHeader(this.get('date')));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The handler for the change in the customRenderer attribute.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _afterCustomRendererChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterCustomRendererChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderCustomRules();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * The handler for the change in the date attribute. Modifies the calendar
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * view by shifting the calendar grid mask and running custom rendering and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * selection rendering as necessary.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _afterDateChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterDateChange : function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var contentBox = this.get('contentBox'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass headerCell = contentBox.one("." + CAL_HD).one("h4"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendarPanes = contentBox.all("." + CAL_GRID),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass currentDate = this.get("date"),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass counter = 0;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contentBox.setStyle("visibility", "hidden");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass headerCell.setContent(this._updateCalendarHeader(currentDate));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._restoreModifiedCells();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendarPanes.each(function (curNode) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._rerenderCalendarPane(ydate.addMonths(currentDate, counter++),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass curNode);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._afterShowPrevMonthChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._afterShowNextMonthChange();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderCustomRules();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._renderSelectedDates();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contentBox.setStyle("visibility", "visible");
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A rendering assist method that initializes the HTML for a single
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @method _initCalendarPane
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} baseDate The date corresponding to the month of the given
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {String} pane_id The id of the pane, to be used as a prefix for
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * element ids in the given pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai */
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai _initCalendarPane : function (baseDate, pane_id) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Initialize final output HTML string
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var calString = '',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Get a list of short weekdays from the internationalization package, or else use default English ones.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass weekdays = this.get('strings.very_short_weekdays') || ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Get the first day of the week from the internationalization package, or else use Sunday as default.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass firstday = this.get('strings.first_weekday') || 0,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Compute the cutoff column of the masked calendar table, based on the start date and the first day of week.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass cutoffCol = this._getCutoffColumn(baseDate, firstday),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Compute the number of days in the month based on starting date
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass daysInMonth = ydate.daysInMonth(baseDate),
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai // Initialize the array of individual row HTML strings
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai row_array = ['','','','','',''],
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai // Initialize the partial templates object
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai partials = {};
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai // Initialize the partial template for the weekday row cells.
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai partials["weekday_row"] = '';
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai // Populate the partial template for the weekday row cells with weekday names
6bb97cfdea627b5bb0523ad4e6d2623c5fbf6954Satyen Desai for (var day = firstday; day <= firstday + 6; day++) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass partials["weekday_row"] +=
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass substitute(CalendarBase.WEEKDAY_TEMPLATE,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {weekdayname: weekdays[day%7]});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Populate the partial template for the weekday row container with the weekday row cells
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith partials["weekday_row_template"] = substitute(CalendarBase.WEEKDAY_ROW_TEMPLATE, partials);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Populate the array of individual row HTML strings
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var row = 0; row <= 5; row++) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (var column = 0; column <= 12; column++) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Compute the value of the date that needs to populate the cell
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var date = 7*row - 5 + column;
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Compose the value of the unique id of the current calendar cell
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var id_date = pane_id + "_" + column + "_" + date;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Set the calendar day class to one of three possible values
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var calendar_day_class = CAL_DAY;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (date < 1) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_day_class = CAL_PREVMONTH_DAY;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith else if (date > daysInMonth) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_day_class = CAL_NEXTMONTH_DAY;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Cut off dates that fall before the first and after the last date of the month
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (date < 1 || date > daysInMonth) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass date = "&nbsp;";
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Decide on whether a column in the masked table is visible or not based on the value of the cutoff column.
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith var column_visibility = (column >= cutoffCol && column < (cutoffCol + 7)) ? '' : CAL_COL_HIDDEN;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Substitute the values into the partial calendar day template and add it to the current row HTML string
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass row_array[row] += substitute (CalendarBase.CALDAY_TEMPLATE,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {day_content: date,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_col_class: "calendar_col" + column,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_col_visibility_class: column_visibility,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_day_class: calendar_day_class,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass calendar_day_id: id_date});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Instantiate the partial calendar pane body template
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass partials["body_template"] = '';
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Populate the body template with the rows templates
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass each (row_array, function (v) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass partials["body_template"] += substitute(CalendarBase.CALDAY_ROW_TEMPLATE,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {calday_row: v});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Populate the calendar grid id
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass partials["calendar_pane_id"] = pane_id;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Generate final output by substituting class names.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var output = substitute(substitute (CalendarBase.CALENDAR_GRID_TEMPLATE, partials),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CalendarBase.CALENDAR_STRINGS);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith // Store the initialized pane information
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai this._paneProperties[pane_id] = {cutoffCol: cutoffCol, daysInMonth: daysInMonth, paneDate: baseDate};
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return output;
10d8bafc5c24f3a4285cf6060a1935ba5cfc4b85Luke Smith },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * A rendering assist method that rerenders a specified calendar pane, based
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai * on a new Date.
d8d2286d8330892bb02eb2bf0735322f559ef5efSatyen Desai * @method _rerenderCalendarPane
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Date} newDate The date corresponding to the month of the given
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * calendar pane.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param {Node} pane The node corresponding to the calendar pane to be rerenders.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @private
9220b67634d9c9872485e6a84bd8de8dd3d7507bSatyen Desai */
_rerenderCalendarPane : function (newDate, pane) {
// Get the first day of the week from the internationalization package, or else use Sunday as default.
var firstday = this.get('strings.first_weekday') || 0,
// Compute the cutoff column of the masked calendar table, based on the start date and the first day of week.
cutoffCol = this._getCutoffColumn(newDate, firstday),
// Compute the number of days in the month based on starting date
daysInMonth = ydate.daysInMonth(newDate),
// Get pane id for easier reference
paneId = pane.get("id");
// Hide the pane before making DOM changes to speed them up
pane.setStyle("visibility", "hidden");
// Go through all columns, and flip their visibility setting based on whether they are within the unmasked range.
for (var column = 0; column <= 12; column++) {
var currentColumn = pane.all("." + "calendar_col" + column);
currentColumn.removeClass(CAL_COL_HIDDEN);
if (column < cutoffCol || column >= (cutoffCol + 7)) {
currentColumn.addClass(CAL_COL_HIDDEN);
}
else {
// Clean up dates in visible columns to account for the correct number of days in a month
switch(column)
{
case 0:
var curCell = pane.one("#" + paneId + "_0_30");
if (daysInMonth >= 30) {
curCell.setContent("30");
curCell.removeClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
else {
curCell.setContent("&nbsp;");
curCell.addClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
break;
case 1:
var curCell = pane.one("#" + paneId + "_1_31");
if (daysInMonth >= 31) {
curCell.setContent("31");
curCell.removeClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
else {
curCell.setContent("&nbsp;");
curCell.removeClass(CAL_DAY).addClass(CAL_NEXTMONTH_DAY);
}
break;
case 6:
var curCell = pane.one("#" + paneId + "_6_29");
if (daysInMonth >= 29) {
curCell.setContent("29");
curCell.removeClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
else {
curCell.setContent("&nbsp;");
curCell.removeClass(CAL_DAY).addClass(CAL_NEXTMONTH_DAY);
}
break;
case 7:
var curCell = pane.one("#" + paneId + "_7_30");
if (daysInMonth >= 30) {
curCell.setContent("30");
curCell.removeClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
else {
curCell.setContent("&nbsp;");
curCell.removeClass(CAL_DAY).addClass(CAL_NEXTMONTH_DAY);
}
break;
case 8:
var curCell = pane.one("#" + paneId + "_8_31");
if (daysInMonth >= 31) {
curCell.setContent("31");
curCell.removeClass(CAL_NEXTMONTH_DAY).addClass(CAL_DAY);
}
else {
curCell.setContent("&nbsp;");
curCell.removeClass(CAL_DAY).addClass(CAL_NEXTMONTH_DAY);
}
break;
}
}
}
// Update stored pane properties
this._paneProperties[paneId].cutoffCol = cutoffCol;
this._paneProperties[paneId].daysInMonth = daysInMonth;
this._paneProperties[paneId].paneDate = newDate;
// Bring the pane visibility back after all DOM changes are done
pane.setStyle("visibility", "visible");
},
/**
* A rendering assist method that updates the calendar header based
* on a given date and potentially the provided headerRenderer.
* @method _updateCalendarHeader
* @param {Date} baseDate The date with which to update the calendar header.
* @private
*/
_updateCalendarHeader : function (baseDate) {
var headerString = "",
headerRenderer = this.get("headerRenderer");
if (Y.Lang.isString(headerRenderer)) {
headerString = ydate.format(baseDate, {format:headerRenderer});
}
else if (headerRenderer instanceof Function) {
headerString = headerRenderer.call(this, baseDate);
}
return headerString;
},
/**
* A rendering assist method that initializes the calendar header HTML
* based on a given date and potentially the provided headerRenderer.
* @method _updateCalendarHeader
* @param {Date} baseDate The date with which to initialize the calendar header.
* @private
*/
_initCalendarHeader : function (baseDate) {
return substitute(substitute(CalendarBase.HEADER_TEMPLATE,
{calheader: this._updateCalendarHeader(baseDate)}),
CalendarBase.CALENDAR_STRINGS);
},
/**
* A rendering assist method that initializes the calendar HTML
* based on a given date.
* @method _initCalendarHTML
* @param {Date} baseDate The date with which to initialize the calendar.
* @private
*/
_initCalendarHTML : function (baseDate) {
// Instantiate the partials holder
var partials = {},
// Counter for iterative template replacement.
counter = 0;
// Generate the template for the header
partials["header_template"] = this._initCalendarHeader(baseDate);
partials["calendar_id"] = this._calendarId;
partials["body_template"] = substitute(substitute (CalendarBase.CONTENT_TEMPLATE, partials),
CalendarBase.CALENDAR_STRINGS);
// Instantiate the iterative template replacer function
function paneReplacer () {
var singlePane = this._initCalendarPane(ydate.addMonths(baseDate, counter), partials["calendar_id"]+"_pane_"+counter);
counter++;
return singlePane;
}
// Go through all occurrences of the calendar_grid_template token and replace it with an appropriate calendar grid.
var output = partials["body_template"].replace(/\{calendar_grid_template\}/g, Y.bind(paneReplacer, this));
// Update the paneNumber count
this._paneNumber = counter;
return output;
}
}, {
/**
* The CSS classnames for the calendar templates.
* @property CALENDAR_STRINGS
* @type Object
* @readOnly
* @protected
* @static
*/
CALENDAR_STRINGS: {
calendar_grid_class : CAL_GRID,
calendar_body_class : CAL_BODY,
calendar_hd_class : CAL_HD,
calendar_hd_label_class : CAL_HD_LABEL,
calendar_weekdayrow_class : CAL_WDAYROW,
calendar_weekday_class : CAL_WDAY,
calendar_row_class : CAL_ROW,
calendar_day_class : CAL_DAY,
calendar_dayanchor_class : CAL_ANCHOR,
calendar_pane_class : CAL_PANE,
calendar_right_grid_class : CAL_RIGHT_GRID,
calendar_left_grid_class : CAL_LEFT_GRID
},
/**
* The main content template for calendar.
* @property CONTENT_TEMPLATE
* @type String
* @protected
* @static
*/
CONTENT_TEMPLATE: '<div class="yui3-g {calendar_pane_class}" id="{calendar_id}">' +
'{header_template}' +
'<div class="yui3-u-1">' +
'{calendar_grid_template}' +
'</div>' +
'</div>',
/**
* A single pane template for calendar (same as default CONTENT_TEMPLATE)
* @property ONE_PANE_TEMPLATE
* @type String
* @protected
* @readOnly
* @static
*/
ONE_PANE_TEMPLATE: '<div class="yui3-g {calendar_pane_class}" id="{calendar_id}">' +
'{header_template}' +
'<div class="yui3-u-1 yui3-calendar-main-grid">' +
'{calendar_grid_template}' +
'</div>' +
'</div>',
/**
* A two pane template for calendar.
* @property TWO_PANE_TEMPLATE
* @type String
* @protected
* @readOnly
* @static
*/
TWO_PANE_TEMPLATE: '<div class="yui3-g {calendar_pane_class}" id="{calendar_id}">' +
'{header_template}' +
'<div class="yui3-u-1-2">'+
'<div class = "{calendar_left_grid_class}">' +
'{calendar_grid_template}' +
'</div>' +
'</div>' +
'<div class="yui3-u-1-2">' +
'<div class = "{calendar_right_grid_class}">' +
'{calendar_grid_template}' +
'</div>' +
'</div>' +
'</div>',
/**
* A three pane template for calendar.
* @property THREE_PANE_TEMPLATE
* @type String
* @protected
* @readOnly
* @static
*/
THREE_PANE_TEMPLATE: '<div class="yui3-g {calendar_pane_class}" id="{calendar_id}">' +
'{header_template}' +
'<div class="yui3-u-1-3">' +
'<div class = "{calendar_left_grid_class}">' +
'{calendar_grid_template}' +
'</div>' +
'</div>' +
'<div class="yui3-u-1-3">' +
'{calendar_grid_template}' +
'</div>' +
'<div class="yui3-u-1-3">' +
'<div class = "{calendar_right_grid_class}">' +
'{calendar_grid_template}' +
'</div>' +
'</div>' +
'</div>',
/**
* A template for the calendar grid.
* @property CALENDAR_GRID_TEMPLATE
* @type String
* @protected
* @static
*/
CALENDAR_GRID_TEMPLATE: '<table class="{calendar_grid_class}" id="{calendar_pane_id}">' +
'<thead>' +
'{weekday_row_template}' +
'</thead>' +
'<tbody>' +
'{body_template}' +
'</tbody>' +
'</table>',
/**
* A template for the calendar header.
* @property HEADER_TEMPLATE
* @type String
* @protected
* @static
*/
HEADER_TEMPLATE: '<div class="yui3-g {calendar_hd_class}">' +
'<div class="yui3-u {calendar_hd_label_class}">' +
'<h4>' +
'{calheader}' +
'</h4>' +
'</div>' +
'</div>',
/**
* A template for the row of weekday names.
* @property WEEKDAY_ROW_TEMPLATE
* @type String
* @protected
* @static
*/
WEEKDAY_ROW_TEMPLATE: '<tr class="{calendar_weekdayrow_class}">' +
'{weekday_row}' +
'</tr>',
/**
* A template for a single row of calendar days.
* @property CALDAY_ROW_TEMPLATE
* @type String
* @protected
* @static
*/
CALDAY_ROW_TEMPLATE: '<tr class="{calendar_row_class}">' +
'{calday_row}' +
'</tr>',
/**
* A template for a single cell with a weekday name.
* @property CALDAY_ROW_TEMPLATE
* @type String
* @protected
* @static
*/
WEEKDAY_TEMPLATE: '<th class="{calendar_weekday_class}">{weekdayname}</th>',
/**
* A template for a single cell with a calendar day.
* @property CALDAY_TEMPLATE
* @type String
* @protected
* @static
*/
CALDAY_TEMPLATE: '<td class="{calendar_col_class} {calendar_day_class} {calendar_col_visibility_class}" id="{calendar_day_id}">' +
'{day_content}' +
'</td>',
/**
* The identity of the widget.
*
* @property NAME
* @type String
* @default 'calendarBase'
* @readOnly
* @protected
* @static
*/
NAME: 'calendarBase',
/**
* Static property used to define the default attribute configuration of
* the Widget.
*
* @property ATTRS
* @type {Object}
* @protected
* @static
*/
ATTRS: {
/**
* The date corresponding to the current calendar view. Always
* normalized to the first of the month that contains the date
* at assignment time. Used as the first date visible in the
* calendar.
*
* @attribute date
* @type Date
* @default The first of the month containing today's date, as
* set on the end user's system.
*/
date: {
value: new Date(),
setter: function (val) {
var newDate = this._normalizeDate(val);
if (ydate.areEqual(newDate, this.get('date'))) {
return this.get('date');
}
}
},
/**
* A setting specifying whether to shows days from the previous
* month in the visible month's grid, if there are empty preceding
* cells available.
*
* @attribute showPrevMonth
* @type boolean
* @default false
*/
showPrevMonth: {
value: false
},
/**
* A setting specifying whether to shows days from the next
* month in the visible month's grid, if there are empty
* cells available at the end.
*
* @attribute showNextMonth
* @type boolean
* @default false
*/
showNextMonth: {
value: false
},
/**
* Strings and properties derived from the internationalization packages
* for the calendar.
*
* @attribute strings
* @type Object
* @protected
*/
strings : {
valueFn: function() { return Y.Intl.get("calendar-base"); }
},
/**
* Custom header renderer for the calendar.
*
* @attribute headerRenderer
* @type String | Function
*/
headerRenderer: {
value: "%B %Y"
},
/**
* The name of the rule which all enabled dates should match.
* Either disabledDatesRule or enabledDatesRule should be specified,
* or neither, but not both.
*
* @attribute enabledDatesRule
* @type String
* @default null
*/
enabledDatesRule: {
value: null
},
/**
* The name of the rule which all disabled dates should match.
* Either disabledDatesRule or enabledDatesRule should be specified,
* or neither, but not both.
*
* @attribute disabledDatesRule
* @type String
* @default null
*/
disabledDatesRule: {
value: null
},
/**
* A read-only attribute providing a list of currently selected dates.
*
* @attribute selectedDates
* @readOnly
* @type Array
*/
selectedDates : {
readOnly: true,
getter: function (val) {
return (this._getSelectedDatesList());
}
},
/**
* An object of the form {rules:Object, filterFunction:Function},
* providing set of rules and a custom rendering function for
* customizing specific calendar cells.
*
* @attribute customRenderer
* @readOnly
* @type Object
* @default {}
*/
customRenderer : {
value: {},
setter: function (val) {
this._rules = val.rules;
this._filterFunction = val.filterFunction;
}
}
}
});