diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/ui/datepicker.js')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/ui/datepicker.js | 1343 |
1 files changed, 0 insertions, 1343 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/ui/datepicker.js b/contexts/data/lib/closure-library/closure/goog/ui/datepicker.js deleted file mode 100644 index 62b296a..0000000 --- a/contexts/data/lib/closure-library/closure/goog/ui/datepicker.js +++ /dev/null @@ -1,1343 +0,0 @@ -// Copyright 2006 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Date picker implementation. - * - * @author eae@google.com (Emil A Eklund) - * @see ../demos/datepicker.html - */ - -goog.provide('goog.ui.DatePicker'); -goog.provide('goog.ui.DatePicker.Events'); -goog.provide('goog.ui.DatePickerEvent'); - -goog.require('goog.date'); -goog.require('goog.date.Date'); -goog.require('goog.date.Interval'); -goog.require('goog.dom'); -goog.require('goog.dom.a11y'); -goog.require('goog.dom.classes'); -goog.require('goog.events'); -goog.require('goog.events.Event'); -goog.require('goog.events.EventType'); -goog.require('goog.events.KeyHandler'); -goog.require('goog.events.KeyHandler.EventType'); -goog.require('goog.i18n.DateTimeFormat'); -goog.require('goog.i18n.DateTimeSymbols'); -goog.require('goog.style'); -goog.require('goog.ui.Component'); -goog.require('goog.ui.IdGenerator'); - - - -/** - * DatePicker widget. Allows a single date to be selected from a calendar like - * view. - * - * @param {goog.date.Date|Date=} opt_date Date to initialize the date picker - * with, defaults to the current date. - * @param {Object=} opt_dateTimeSymbols Date and time symbols to use. - * Defaults to goog.i18n.DateTimeSymbols if not set. - * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper. - * @constructor - * @extends {goog.ui.Component} - */ -goog.ui.DatePicker = function(opt_date, opt_dateTimeSymbols, opt_domHelper) { - goog.ui.Component.call(this, opt_domHelper); - - /** - * Date and time symbols to use. - * @type {Object} - * @private - */ - this.symbols_ = opt_dateTimeSymbols || goog.i18n.DateTimeSymbols; - - this.wdayNames_ = this.symbols_.SHORTWEEKDAYS; - - /** - * Selected date. - * @type {goog.date.Date} - * @private - */ - this.date_ = new goog.date.Date(opt_date); - this.date_.setFirstWeekCutOffDay(this.symbols_.FIRSTWEEKCUTOFFDAY); - this.date_.setFirstDayOfWeek(this.symbols_.FIRSTDAYOFWEEK); - - /** - * Active month. - * @type {goog.date.Date} - * @private - */ - this.activeMonth_ = this.date_.clone(); - this.activeMonth_.setDate(1); - - /** - * Class names to apply to the weekday columns. - * @type {Array.<string>} - * @private - */ - this.wdayStyles_ = ['', '', '', '', '', '', '']; - this.wdayStyles_[this.symbols_.WEEKENDRANGE[0]] = - goog.getCssName(this.getBaseCssClass(), 'wkend-start'); - this.wdayStyles_[this.symbols_.WEEKENDRANGE[1]] = - goog.getCssName(this.getBaseCssClass(), 'wkend-end'); - - /** - * Object that is being used to cache key handlers. - * @type {Object} - * @private - */ - this.keyHandlers_ = {}; -}; -goog.inherits(goog.ui.DatePicker, goog.ui.Component); - - -/** - * Flag indicating if the number of weeks shown should be fixed. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.showFixedNumWeeks_ = true; - - -/** - * Flag indicating if days from other months should be shown. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.showOtherMonths_ = true; - - -/** - * Flag indicating if extra week(s) always should be added at the end. If not - * set the extra week is added at the beginning if the number of days shown - * from the previous month is less then the number from the next month. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.extraWeekAtEnd_ = true; - - -/** - * Flag indicating if week numbers should be shown. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.showWeekNum_ = true; - - -/** - * Flag indicating if weekday names should be shown. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.showWeekdays_ = true; - - -/** - * Flag indicating if none is a valid selection. Also controls if the none - * button should be shown or not. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.allowNone_ = true; - - -/** - * Flag indicating if the today button should be shown. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.showToday_ = true; - - -/** - * Flag indicating if the picker should use a simple navigation menu that only - * contains controls for navigating to the next and previous month. The default - * navigation menu contains controls for navigating to the next/previous month, - * next/previous year, and menus for jumping to specific months and years. - * @type {boolean} - * @private - */ -goog.ui.DatePicker.prototype.simpleNavigation_ = false; - - -/** - * Custom decorator function. Takes a goog.date.Date object, returns a String - * representing a CSS class or null if no special styling applies - * @type {Function} - * @private - */ -goog.ui.DatePicker.prototype.decoratorFunction_ = null; - - -/** - * Element for navigation row on a datepicker. - * @type {Element} - * @private - */ -goog.ui.DatePicker.prototype.elNavRow_ = null; - - -/** - * Element for footer row on a datepicker. - * @type {Element} - * @private - */ -goog.ui.DatePicker.prototype.elFootRow_ = null; - - -/** - * Generator for unique table cell IDs. - * @type {goog.ui.IdGenerator} - * @private - */ -goog.ui.DatePicker.prototype.cellIdGenerator_ = - goog.ui.IdGenerator.getInstance(); - - -/** - * Name of base CSS clase of datepicker. - * @type {string} - * @private - */ -goog.ui.DatePicker.BASE_CSS_CLASS_ = goog.getCssName('goog-date-picker'); - - -/** - * Constants for event names - * - * @type {Object} - */ -goog.ui.DatePicker.Events = { - CHANGE: 'change', - SELECT: 'select' -}; - - -/** - * @deprecated Use isInDocument. - */ -goog.ui.DatePicker.prototype.isCreated = - goog.ui.DatePicker.prototype.isInDocument; - - -/** - * @return {number} The first day of week, 0 = Monday, 6 = Sunday. - */ -goog.ui.DatePicker.prototype.getFirstWeekday = function() { - return this.activeMonth_.getFirstDayOfWeek(); -}; - - -/** - * Returns the class name associated with specified weekday. - * @param {number} wday The week day number to get the class name for. - * @return {string} The class name associated with specified weekday. - */ -goog.ui.DatePicker.prototype.getWeekdayClass = function(wday) { - return this.wdayStyles_[wday]; -}; - - -/** - * @return {boolean} Whether a fixed number of weeks should be showed. If not - * only weeks for the current month will be shown. - */ -goog.ui.DatePicker.prototype.getShowFixedNumWeeks = function() { - return this.showFixedNumWeeks_; -}; - - -/** - * @return {boolean} Whether a days from the previous and/or next month should - * be shown. - */ -goog.ui.DatePicker.prototype.getShowOtherMonths = function() { - return this.showOtherMonths_; -}; - - -/** - * @return {boolean} Whether a the extra week(s) added always should be at the - * end. Only applicable if a fixed number of weeks are shown. - */ -goog.ui.DatePicker.prototype.getExtraWeekAtEnd = function() { - return this.extraWeekAtEnd_; -}; - - -/** - * @return {boolean} Whether week numbers should be shown. - */ -goog.ui.DatePicker.prototype.getShowWeekNum = function() { - return this.showWeekNum_; -}; - - -/** - * @return {boolean} Whether weekday names should be shown. - */ -goog.ui.DatePicker.prototype.getShowWeekdayNames = function() { - return this.showWeekdays_; -}; - - -/** - * @return {boolean} Whether none is a valid selection. - */ -goog.ui.DatePicker.prototype.getAllowNone = function() { - return this.allowNone_; -}; - - -/** - * @return {boolean} Whether the today button should be shown. - */ -goog.ui.DatePicker.prototype.getShowToday = function() { - return this.showToday_; -}; - - -/** - * Returns base CSS class. This getter is used to get base CSS class part. - * All CSS class names in component are created as: - * goog.getCssName(this.getBaseCssClass(), 'CLASS_NAME') - * @return {string} Base CSS class. - */ -goog.ui.DatePicker.prototype.getBaseCssClass = function() { - return goog.ui.DatePicker.BASE_CSS_CLASS_; -}; - - -/** - * Sets the first day of week - * - * @param {number} wday Week day, 0 = Monday, 6 = Sunday. - */ -goog.ui.DatePicker.prototype.setFirstWeekday = function(wday) { - this.activeMonth_.setFirstDayOfWeek(wday); - this.updateCalendarGrid_(); - this.redrawWeekdays_(); -}; - - -/** - * Sets class name associated with specified weekday. - * - * @param {number} wday Week day, 0 = Monday, 6 = Sunday. - * @param {string} className Class name. - */ -goog.ui.DatePicker.prototype.setWeekdayClass = function(wday, className) { - this.wdayStyles_[wday] = className; - this.redrawCalendarGrid_(); -}; - - -/** - * Sets whether a fixed number of weeks should be showed. If not only weeks - * for the current month will be showed. - * - * @param {boolean} b Whether a fixed number of weeks should be showed. - */ -goog.ui.DatePicker.prototype.setShowFixedNumWeeks = function(b) { - this.showFixedNumWeeks_ = b; - this.updateCalendarGrid_(); -}; - - -/** - * Sets whether a days from the previous and/or next month should be shown. - * - * @param {boolean} b Whether a days from the previous and/or next month should - * be shown. - */ -goog.ui.DatePicker.prototype.setShowOtherMonths = function(b) { - this.showOtherMonths_ = b; - this.redrawCalendarGrid_(); -}; - - -/** - * Sets whether the picker should use a simple navigation menu that only - * contains controls for navigating to the next and previous month. The default - * navigation menu contains controls for navigating to the next/previous month, - * next/previous year, and menus for jumping to specific months and years. - * - * @param {boolean} b Whether to use a simple navigation menu. - */ -goog.ui.DatePicker.prototype.setUseSimpleNavigationMenu = function(b) { - this.simpleNavigation_ = b; - this.updateNavigationRow_(); - this.updateCalendarGrid_(); -}; - - -/** - * Sets whether a the extra week(s) added always should be at the end. Only - * applicable if a fixed number of weeks are shown. - * - * @param {boolean} b Whether a the extra week(s) added always should be at the - * end. - */ -goog.ui.DatePicker.prototype.setExtraWeekAtEnd = function(b) { - this.extraWeekAtEnd_ = b; - this.updateCalendarGrid_(); -}; - - -/** - * Sets whether week numbers should be shown. - * - * @param {boolean} b Whether week numbers should be shown. - */ -goog.ui.DatePicker.prototype.setShowWeekNum = function(b) { - this.showWeekNum_ = b; - // The navigation row may rely on the number of visible columns, - // so we update it when adding/removing the weeknum column. - this.updateNavigationRow_(); - this.updateCalendarGrid_(); -}; - - -/** - * Sets whether weekday names should be shown. - * - * @param {boolean} b Whether weekday names should be shown. - */ -goog.ui.DatePicker.prototype.setShowWeekdayNames = function(b) { - this.showWeekdays_ = b; - this.redrawCalendarGrid_(); -}; - - -/** - * Sets whether the picker uses narrow weekday names ('M', 'T', 'W', ...). - * - * The default behavior is to use short names ('Mon', 'Tue', 'Wed', ...). - * - * @param {boolean} b Whether to use narrow weekday names. - */ -goog.ui.DatePicker.prototype.setUseNarrowWeekdayNames = function(b) { - this.wdayNames_ = b ? this.symbols_.NARROWWEEKDAYS : - this.symbols_.SHORTWEEKDAYS; - this.redrawWeekdays_(); -}; - - -/** - * Sets whether none is a valid selection. - * - * @param {boolean} b Whether none is a valid selection. - */ -goog.ui.DatePicker.prototype.setAllowNone = function(b) { - this.allowNone_ = b; - if (this.elNone_) { - this.updateTodayAndNone_(); - } -}; - - -/** - * Sets whether the today button should be shown. - * - * @param {boolean} b Whether the today button should be shown. - */ -goog.ui.DatePicker.prototype.setShowToday = function(b) { - this.showToday_ = b; - if (this.elToday_) { - this.updateTodayAndNone_(); - } -}; - - -/** - * Updates the display style of the None and Today buttons as well as hides the - * table foot if both are hidden. - * @private - */ -goog.ui.DatePicker.prototype.updateTodayAndNone_ = function() { - goog.style.showElement(this.elToday_, this.showToday_); - goog.style.showElement(this.elNone_, this.allowNone_); - goog.style.showElement(this.tableFoot_, this.showToday_ || this.allowNone_); -}; - - -/** - * Sets the decorator function. The function should have the interface of - * {string} f({goog.date.Date}); - * and return a String representing a CSS class to decorate the cell - * corresponding to the date specified. - * - * @param {Function} f The decorator function. - */ -goog.ui.DatePicker.prototype.setDecorator = function(f) { - this.decoratorFunction_ = f; -}; - - -/** - * Changes the active month to the previous one. - */ -goog.ui.DatePicker.prototype.previousMonth = function() { - this.activeMonth_.add(new goog.date.Interval(goog.date.Interval.MONTHS, -1)); - this.updateCalendarGrid_(); -}; - - -/** - * Changes the active month to the next one. - */ -goog.ui.DatePicker.prototype.nextMonth = function() { - this.activeMonth_.add(new goog.date.Interval(goog.date.Interval.MONTHS, 1)); - this.updateCalendarGrid_(); -}; - - -/** - * Changes the active year to the previous one. - */ -goog.ui.DatePicker.prototype.previousYear = function() { - this.activeMonth_.add(new goog.date.Interval(goog.date.Interval.YEARS, -1)); - this.updateCalendarGrid_(); -}; - - -/** - * Changes the active year to the next one. - */ -goog.ui.DatePicker.prototype.nextYear = function() { - this.activeMonth_.add(new goog.date.Interval(goog.date.Interval.YEARS, 1)); - this.updateCalendarGrid_(); -}; - - -/** - * Selects the current date. - */ -goog.ui.DatePicker.prototype.selectToday = function() { - this.setDate(new goog.date.Date()); -}; - - -/** - * Clears the selection. - */ -goog.ui.DatePicker.prototype.selectNone = function() { - if (this.allowNone_) { - this.setDate(null); - } -}; - - -/** - * @return {goog.date.Date} The active month displayed. - */ -goog.ui.DatePicker.prototype.getActiveMonth = function() { - return this.activeMonth_.clone(); -}; - - -/** - * @return {goog.date.Date} The selected date or null if nothing is selected. - */ -goog.ui.DatePicker.prototype.getDate = function() { - return this.date_ && this.date_.clone(); -}; - - -/** - * Sets the selected date. - * - * @param {goog.date.Date|Date} date Date to select or null to select nothing. - */ -goog.ui.DatePicker.prototype.setDate = function(date) { - // Check if date has been changed - var changed = date != this.date_ && - !(date && this.date_ && - date.getFullYear() == this.date_.getFullYear() && - date.getMonth() == this.date_.getMonth() && - date.getDate() == this.date_.getDate()); - - // Set current date to clone of supplied goog.date.Date or Date. - this.date_ = date && new goog.date.Date(date); - - // Set current month - if (date) { - this.activeMonth_.set(this.date_); - this.activeMonth_.setDate(1); - } - - // Update calendar grid even if the date has not changed as even if today is - // selected another month can be displayed. - this.updateCalendarGrid_(); - - // TODO(eae): Standardize selection and change events with other components. - // Fire select event. - var selectEvent = new goog.ui.DatePickerEvent( - goog.ui.DatePicker.Events.SELECT, this, this.date_); - this.dispatchEvent(selectEvent); - - // Fire change event. - if (changed) { - var changeEvent = new goog.ui.DatePickerEvent( - goog.ui.DatePicker.Events.CHANGE, this, this.date_); - this.dispatchEvent(changeEvent); - } -}; - - -/** - * Updates the navigation row (navigating months and maybe years) in the navRow_ - * element of a created picker. - * @private - */ -goog.ui.DatePicker.prototype.updateNavigationRow_ = function() { - if (!this.elNavRow_) { - return; - } - var row = this.elNavRow_; - - // Clear the navigation row. - while (row.firstChild) { - row.removeChild(row.firstChild); - } - // Populate the navigation row according to the configured navigation mode. - var cell, monthCell, yearCell; - - if (this.simpleNavigation_) { - cell = this.dom_.createElement('td'); - cell.colSpan = this.showWeekNum_ ? 1 : 2; - this.createButton_(cell, '\u00AB', this.previousMonth); // << - row.appendChild(cell); - - cell = this.dom_.createElement('td'); - cell.colSpan = this.showWeekNum_ ? 6 : 5; - cell.className = goog.getCssName(this.getBaseCssClass(), 'monthyear'); - row.appendChild(cell); - this.elMonthYear_ = cell; - - cell = this.dom_.createElement('td'); - this.createButton_(cell, '\u00BB', this.nextMonth); // >> - row.appendChild(cell); - - } else { - var fullDateFormat = this.symbols_.DATEFORMATS[ - goog.i18n.DateTimeFormat.Format.FULL_DATE].toLowerCase(); - - monthCell = this.dom_.createElement('td'); - monthCell.colSpan = 5; - this.createButton_(monthCell, '\u00AB', this.previousMonth); // << - this.elMonth_ = this.createButton_( - monthCell, '', this.showMonthMenu_, - goog.getCssName(this.getBaseCssClass(), 'month')); - this.createButton_(monthCell, '\u00BB', this.nextMonth); // >> - - yearCell = this.dom_.createElement('td'); - yearCell.colSpan = 3; - this.createButton_(yearCell, '\u00AB', this.previousYear); // << - this.elYear_ = this.createButton_(yearCell, '', this.showYearMenu_, - goog.getCssName(this.getBaseCssClass(), - 'year')); - this.createButton_(yearCell, '\u00BB', this.nextYear); // >> - - // If the date format has year ('y') appearing first before month ('m'), - // show the year on the left hand side of the datepicker popup. Otherwise, - // show the month on the left side. This check assumes the data to be - // valid, and that all date formats contain month and year. - if (fullDateFormat.indexOf('y') < fullDateFormat.indexOf('m')) { - row.appendChild(yearCell); - row.appendChild(monthCell); - } else { - row.appendChild(monthCell); - row.appendChild(yearCell); - } - } -}; - - -/** - * Updates the footer row (with select buttons) in the footRow_ element of a - * created picker. - * @private - */ -goog.ui.DatePicker.prototype.updateFooterRow_ = function() { - var row = this.elFootRow_; - - // Clear the footer row. - goog.dom.removeChildren(row); - - // Populate the footer row with buttons for Today and None. - var cell = this.dom_.createElement('td'); - cell.colSpan = 2; - cell.className = goog.getCssName(this.getBaseCssClass(), 'today-cont'); - - /** @desc Label for button that selects the current date. */ - var MSG_DATEPICKER_TODAY_BUTTON_LABEL = goog.getMsg('Today'); - this.elToday_ = this.createButton_(cell, MSG_DATEPICKER_TODAY_BUTTON_LABEL, - this.selectToday); - row.appendChild(cell); - - cell = this.dom_.createElement('td'); - cell.colSpan = 4; - row.appendChild(cell); - - cell = this.dom_.createElement('td'); - cell.colSpan = 2; - cell.className = goog.getCssName(this.getBaseCssClass(), 'none-cont'); - - /** @desc Label for button that clears the selection. */ - var MSG_DATEPICKER_NONE = goog.getMsg('None'); - this.elNone_ = this.createButton_(cell, MSG_DATEPICKER_NONE, this.selectNone); - row.appendChild(cell); - this.updateTodayAndNone_(); -}; - - -/** @override */ -goog.ui.DatePicker.prototype.decorateInternal = function(el) { - goog.ui.DatePicker.superClass_.decorateInternal.call(this, el); - - el.className = this.getBaseCssClass(); - - var table = this.dom_.createElement('table'); - var thead = this.dom_.createElement('thead'); - var tbody = this.dom_.createElement('tbody'); - var tfoot = this.dom_.createElement('tfoot'); - - goog.dom.a11y.setRole(tbody, 'grid'); - tbody.tabIndex = '0'; - - // As per comment in colorpicker: table.tBodies and table.tFoot should not be - // used because of a bug in Safari, hence using an instance variable - this.tableBody_ = tbody; - this.tableFoot_ = tfoot; - - var row = this.dom_.createElement('tr'); - row.className = goog.getCssName(this.getBaseCssClass(), 'head'); - this.elNavRow_ = row; - this.updateNavigationRow_(); - - thead.appendChild(row); - - var cell; - this.elTable_ = []; - for (var i = 0; i < 7; i++) { - row = this.dom_.createElement('tr'); - this.elTable_[i] = []; - for (var j = 0; j < 8; j++) { - cell = this.dom_.createElement(j == 0 || i == 0 ? 'th' : 'td'); - if ((j == 0 || i == 0) && j != i) { - cell.className = (j == 0) ? - goog.getCssName(this.getBaseCssClass(), 'week') : - goog.getCssName(this.getBaseCssClass(), 'wday'); - goog.dom.a11y.setRole(cell, j == 0 ? 'rowheader' : 'columnheader'); - } - row.appendChild(cell); - this.elTable_[i][j] = cell; - } - tbody.appendChild(row); - } - - row = this.dom_.createElement('tr'); - row.className = goog.getCssName(this.getBaseCssClass(), 'foot'); - this.elFootRow_ = row; - this.updateFooterRow_(); - tfoot.appendChild(row); - - - table.cellSpacing = '0'; - table.cellPadding = '0'; - table.appendChild(thead); - table.appendChild(tbody); - table.appendChild(tfoot); - el.appendChild(table); - - this.redrawWeekdays_(); - this.updateCalendarGrid_(); - - el.tabIndex = 0; -}; - - -/** @override */ -goog.ui.DatePicker.prototype.createDom = function() { - goog.ui.DatePicker.superClass_.createDom.call(this); - this.decorateInternal(this.getElement()); -}; - - -/** @override */ -goog.ui.DatePicker.prototype.enterDocument = function() { - goog.ui.DatePicker.superClass_.enterDocument.call(this); - - var eh = this.getHandler(); - eh.listen(this.tableBody_, goog.events.EventType.CLICK, - this.handleGridClick_); - eh.listen(this.getKeyHandlerForElement_(this.getElement()), - goog.events.KeyHandler.EventType.KEY, this.handleGridKeyPress_); -}; - - -/** @override */ -goog.ui.DatePicker.prototype.exitDocument = function() { - goog.ui.DatePicker.superClass_.exitDocument.call(this); - this.destroyMenu_(); - for (var uid in this.keyHandlers_) { - this.keyHandlers_[uid].dispose(); - } - this.keyHandlers_ = {}; -}; - - -/** - * @deprecated Use decorate instead. - */ -goog.ui.DatePicker.prototype.create = - goog.ui.DatePicker.prototype.decorate; - - -/** @override */ -goog.ui.DatePicker.prototype.disposeInternal = function() { - goog.ui.DatePicker.superClass_.disposeInternal.call(this); - - this.elTable_ = null; - this.tableBody_ = null; - this.tableFoot_ = null; - this.elNavRow_ = null; - this.elFootRow_ = null; - this.elMonth_ = null; - this.elMonthYear_ = null; - this.elYear_ = null; - this.elToday_ = null; - this.elNone_ = null; -}; - - -/** - * Click handler for date grid. - * - * @param {goog.events.BrowserEvent} event Click event. - * @private - */ -goog.ui.DatePicker.prototype.handleGridClick_ = function(event) { - if (event.target.tagName == 'TD') { - // colIndex/rowIndex is broken in Safari, find position by looping - var el, x = -2, y = -2; // first col/row is for weekday/weeknum - for (el = event.target; el; el = el.previousSibling, x++) {} - for (el = event.target.parentNode; el; el = el.previousSibling, y++) {} - var obj = this.grid_[y][x]; - this.setDate(obj.clone()); - } -}; - - -/** - * Keypress handler for date grid. - * - * @param {goog.events.BrowserEvent} event Keypress event. - * @private - */ -goog.ui.DatePicker.prototype.handleGridKeyPress_ = function(event) { - var months, days; - switch (event.keyCode) { - case 33: // Page up - event.preventDefault(); - months = -1; - break; - case 34: // Page down - event.preventDefault(); - months = 1; - break; - case 37: // Left - event.preventDefault(); - days = -1; - break; - case 39: // Right - event.preventDefault(); - days = 1; - break; - case 38: // Down - event.preventDefault(); - days = -7; - break; - case 40: // Up - event.preventDefault(); - days = 7; - break; - case 36: // Home - event.preventDefault(); - this.selectToday(); - case 46: // Delete - event.preventDefault(); - this.selectNone(); - default: - return; - } - var date; - if (this.date_) { - date = this.date_.clone(); - date.add(new goog.date.Interval(0, months, days)); - } else { - date = this.activeMonth_.clone(); - date.setDate(1); - } - this.setDate(date); -}; - - -/** - * Click handler for month button. Opens month selection menu. - * - * @param {goog.events.BrowserEvent} event Click event. - * @private - */ -goog.ui.DatePicker.prototype.showMonthMenu_ = function(event) { - event.stopPropagation(); - - var list = []; - for (var i = 0; i < 12; i++) { - list.push(this.symbols_.STANDALONEMONTHS[i]); - } - this.createMenu_(this.elMonth_, list, this.handleMonthMenuClick_, - this.symbols_.STANDALONEMONTHS[this.activeMonth_.getMonth()]); -}; - - -/** - * Click handler for year button. Opens year selection menu. - * - * @param {goog.events.BrowserEvent} event Click event. - * @private - */ -goog.ui.DatePicker.prototype.showYearMenu_ = function(event) { - event.stopPropagation(); - - var list = []; - var year = this.activeMonth_.getFullYear() - 5; - for (var i = 0; i < 11; i++) { - list.push(String(year + i)); - } - this.createMenu_(this.elYear_, list, this.handleYearMenuClick_, - String(this.activeMonth_.getFullYear())); -}; - - -/** - * Call back function for month menu. - * - * @param {Element} target Selected item. - * @private - */ -goog.ui.DatePicker.prototype.handleMonthMenuClick_ = function(target) { - var el = target; - for (var i = -1; el; el = goog.dom.getPreviousElementSibling(el), i++) {} - - this.activeMonth_.setMonth(i); - this.updateCalendarGrid_(); - - if (this.elMonth_.focus) { - this.elMonth_.focus(); - } -}; - - -/** - * Call back function for year menu. - * - * @param {Element} target Selected item. - * @private - */ -goog.ui.DatePicker.prototype.handleYearMenuClick_ = function(target) { - if (target.firstChild.nodeType == goog.dom.NodeType.TEXT) { - this.activeMonth_.setFullYear(Number(target.firstChild.nodeValue)); - this.updateCalendarGrid_(); - } - - this.elYear_.focus(); -}; - - -/** - * Support function for menu creation. - * - * @param {Element} srcEl Button to create menu for. - * @param {Array.<string>} items List of items to populate menu with. - * @param {Function} method Call back method. - * @param {string} selected Item to mark as selected in menu. - * @private - */ -goog.ui.DatePicker.prototype.createMenu_ = function(srcEl, items, method, - selected) { - this.destroyMenu_(); - - var el = this.dom_.createElement('div'); - el.className = goog.getCssName(this.getBaseCssClass(), 'menu'); - - this.menuSelected_ = null; - - var ul = this.dom_.createElement('ul'); - for (var i = 0; i < items.length; i++) { - var li = this.dom_.createDom('li', null, items[i]); - if (items[i] == selected) { - this.menuSelected_ = li; - } - ul.appendChild(li); - } - el.appendChild(ul); - el.style.left = srcEl.offsetLeft + srcEl.parentNode.offsetLeft + 'px'; - el.style.top = srcEl.offsetTop + 'px'; - el.style.width = srcEl.clientWidth + 'px'; - this.elMonth_.parentNode.appendChild(el); - - this.menu_ = el; - if (!this.menuSelected_) { - this.menuSelected_ = ul.firstChild; - } - this.menuSelected_.className = - goog.getCssName(this.getBaseCssClass(), 'menu-selected'); - this.menuCallback_ = method; - - var eh = this.getHandler(); - eh.listen(this.menu_, goog.events.EventType.CLICK, this.handleMenuClick_); - eh.listen(this.getKeyHandlerForElement_(this.menu_), - goog.events.KeyHandler.EventType.KEY, this.handleMenuKeyPress_); - eh.listen(this.dom_.getDocument(), goog.events.EventType.CLICK, - this.destroyMenu_); - el.tabIndex = 0; - el.focus(); -}; - - -/** - * Click handler for menu. - * - * @param {goog.events.BrowserEvent} event Click event. - * @private - */ -goog.ui.DatePicker.prototype.handleMenuClick_ = function(event) { - event.stopPropagation(); - - this.destroyMenu_(); - if (this.menuCallback_) { - this.menuCallback_(event.target); - } -}; - - -/** - * Keypress handler for menu. - * - * @param {goog.events.BrowserEvent} event Keypress event. - * @private - */ -goog.ui.DatePicker.prototype.handleMenuKeyPress_ = function(event) { - // Prevent the grid keypress handler from catching the keypress event. - event.stopPropagation(); - - var el; - var menuSelected = this.menuSelected_; - switch (event.keyCode) { - case 35: // End - event.preventDefault(); - el = menuSelected.parentNode.lastChild; - break; - case 36: // Home - event.preventDefault(); - el = menuSelected.parentNode.firstChild; - break; - case 38: // Up - event.preventDefault(); - el = menuSelected.previousSibling; - break; - case 40: // Down - event.preventDefault(); - el = menuSelected.nextSibling; - break; - case 13: // Enter - case 9: // Tab - case 0: // Space - event.preventDefault(); - this.destroyMenu_(); - this.menuCallback_(menuSelected); - break; - } - if (el && el != menuSelected) { - menuSelected.className = ''; - el.className = goog.getCssName(this.getBaseCssClass(), 'menu-selected'); - this.menuSelected_ = el; - } -}; - - -/** - * Support function for menu destruction. - * @private - */ -goog.ui.DatePicker.prototype.destroyMenu_ = function() { - if (this.menu_) { - var eh = this.getHandler(); - eh.unlisten(this.menu_, goog.events.EventType.CLICK, this.handleMenuClick_); - eh.unlisten(this.getKeyHandlerForElement_(this.menu_), - goog.events.KeyHandler.EventType.KEY, this.handleMenuKeyPress_); - eh.unlisten(this.dom_.getDocument(), goog.events.EventType.CLICK, - this.destroyMenu_); - goog.dom.removeNode(this.menu_); - delete this.menu_; - } -}; - - -/** - * Support function for button creation. - * - * @param {Element} parentNode Container the button should be added to. - * @param {string} label Button label. - * @param {Function} method Event handler. - * @param {string=} opt_className Class name for button, which will be used - * in addition to "goog-date-picker-btn". - * @private - * @return {Element} The created button element. - */ -goog.ui.DatePicker.prototype.createButton_ = function(parentNode, label, - method, opt_className) { - var classes = [goog.getCssName(this.getBaseCssClass(), 'btn')]; - if (opt_className) { - classes.push(opt_className); - } - var el = this.dom_.createElement('button'); - el.className = classes.join(' '); - el.appendChild(this.dom_.createTextNode(label)); - parentNode.appendChild(el); - this.getHandler().listen(el, goog.events.EventType.CLICK, function(e) { - // Since this is a button, the default action is to submit a form if the - // node is added inside a form. Prevent this. - e.preventDefault(); - method.call(this, e); - }); - - return el; -}; - - -/** - * Determines the dates/weekdays for the current month and builds an in memory - * representation of the calendar. - * - * @private - */ -goog.ui.DatePicker.prototype.updateCalendarGrid_ = function() { - if (!this.getElement()) { - return; - } - - var date = this.activeMonth_.clone(); - date.setDate(1); - - // Show year name of select month - if (this.elMonthYear_) { - goog.dom.setTextContent(this.elMonthYear_, - goog.date.formatMonthAndYear( - this.symbols_.STANDALONEMONTHS[date.getMonth()], - date.getFullYear())); - } - if (this.elMonth_) { - goog.dom.setTextContent(this.elMonth_, - this.symbols_.STANDALONEMONTHS[date.getMonth()]); - } - if (this.elYear_) { - goog.dom.setTextContent(this.elYear_, String(date.getFullYear())); - } - - var wday = date.getWeekday(); - var days = date.getNumberOfDaysInMonth(); - - // Determine how many days to show for previous month - date.add(new goog.date.Interval(goog.date.Interval.MONTHS, -1)); - date.setDate(date.getNumberOfDaysInMonth() - (wday - 1)); - - if (this.showFixedNumWeeks_ && !this.extraWeekAtEnd_ && days + wday < 33) { - date.add(new goog.date.Interval(goog.date.Interval.DAYS, -7)); - } - - // Create weekday/day grid - var dayInterval = new goog.date.Interval(goog.date.Interval.DAYS, 1); - this.grid_ = []; - for (var y = 0; y < 6; y++) { // Weeks - this.grid_[y] = []; - for (var x = 0; x < 7; x++) { // Weekdays - this.grid_[y][x] = date.clone(); - date.add(dayInterval); - } - } - - this.redrawCalendarGrid_(); -}; - - -/** - * Draws calendar view from in memory representation and applies class names - * depending on the selection, weekday and whatever the day belongs to the - * active month or not. - * @private - */ -goog.ui.DatePicker.prototype.redrawCalendarGrid_ = function() { - if (!this.getElement()) { - return; - } - - var month = this.activeMonth_.getMonth(); - var today = new goog.date.Date(); - var todayYear = today.getFullYear(); - var todayMonth = today.getMonth(); - var todayDate = today.getDate(); - - // Draw calendar week by week, a worst case month has six weeks. - for (var y = 0; y < 6; y++) { - - // Draw week number, if enabled - if (this.showWeekNum_) { - goog.dom.setTextContent(this.elTable_[y + 1][0], - this.grid_[y][0].getWeekNumber()); - goog.dom.classes.set(this.elTable_[y + 1][0], - goog.getCssName(this.getBaseCssClass(), 'week')); - } else { - goog.dom.setTextContent(this.elTable_[y + 1][0], ''); - goog.dom.classes.set(this.elTable_[y + 1][0], ''); - } - - for (var x = 0; x < 7; x++) { - var o = this.grid_[y][x]; - var el = this.elTable_[y + 1][x + 1]; - - // Assign a unique element id (required for setting the active descendant - // ARIA role) unless already set. - if (!el.id) { - el.id = this.cellIdGenerator_.getNextUniqueId(); - } - goog.dom.a11y.setRole(el, 'gridcell'); - var classes = [goog.getCssName(this.getBaseCssClass(), 'date')]; - if (this.showOtherMonths_ || o.getMonth() == month) { - // Date belongs to previous or next month - if (o.getMonth() != month) { - classes.push(goog.getCssName(this.getBaseCssClass(), 'other-month')); - } - - // Apply styles set by setWeekdayClass - var wday = (x + this.activeMonth_.getFirstDayOfWeek() + 7) % 7; - if (this.wdayStyles_[wday]) { - classes.push(this.wdayStyles_[wday]); - } - - // Current date - if (o.getDate() == todayDate && o.getMonth() == todayMonth && - o.getFullYear() == todayYear) { - classes.push(goog.getCssName(this.getBaseCssClass(), 'today')); - } - - // Selected date - if (this.date_ && o.getDate() == this.date_.getDate() && - o.getMonth() == this.date_.getMonth() && - o.getFullYear() == this.date_.getFullYear()) { - classes.push(goog.getCssName(this.getBaseCssClass(), 'selected')); - goog.dom.a11y.setState(this.tableBody_, 'activedescendant', el.id); - } - - // Custom decorator - if (this.decoratorFunction_) { - var customClass = this.decoratorFunction_(o); - if (customClass) { - classes.push(customClass); - } - } - - // Set cell text to the date and apply classes. - goog.dom.setTextContent(el, o.getDate()); - // Date belongs to previous or next month and showOtherMonths is false, - // clear text and classes. - } else { - goog.dom.setTextContent(el, ''); - } - goog.dom.classes.set(el, classes.join(' ')); - } - - // Hide the either the last one or last two weeks if they contain no days - // from the active month and the showFixedNumWeeks is false. The first four - // weeks are always shown as no month has less than 28 days). - if (y >= 4) { - goog.style.showElement(this.elTable_[y + 1][0].parentNode, - this.grid_[y][0].getMonth() == month || - this.showFixedNumWeeks_); - } - } -}; - - -/** - * Draw weekday names, if enabled. Start with whatever day has been set as the - * first day of week. - * @private - */ -goog.ui.DatePicker.prototype.redrawWeekdays_ = function() { - if (!this.getElement()) { - return; - } - if (this.showWeekdays_) { - for (var x = 0; x < 7; x++) { - var el = this.elTable_[0][x + 1]; - var wday = (x + this.activeMonth_.getFirstDayOfWeek() + 7) % 7; - goog.dom.setTextContent(el, this.wdayNames_[(wday + 1) % 7]); - } - } - goog.style.showElement(this.elTable_[0][0].parentNode, this.showWeekdays_); -}; - - -/** - * Returns the key handler for an element and caches it so that it can be - * retrieved at a later point. - * @param {Element} el The element to get the key handler for. - * @return {goog.events.KeyHandler} The key handler for the element. - * @private - */ -goog.ui.DatePicker.prototype.getKeyHandlerForElement_ = function(el) { - var uid = goog.getUid(el); - if (!(uid in this.keyHandlers_)) { - this.keyHandlers_[uid] = new goog.events.KeyHandler(el); - } - return this.keyHandlers_[uid]; -}; - - - -/** - * Object representing a date picker event. - * - * @param {string} type Event type. - * @param {goog.ui.DatePicker} target Date picker initiating event. - * @param {goog.date.Date} date Selected date. - * @constructor - * @extends {goog.events.Event} - */ -goog.ui.DatePickerEvent = function(type, target, date) { - goog.events.Event.call(this, type, target); - - /** - * The selected date - * @type {goog.date.Date} - */ - this.date = date; -}; -goog.inherits(goog.ui.DatePickerEvent, goog.events.Event); |