Version 3.18.1
Show:

File: calendar/js/calendarnavigator.js

            /**
             * Provides a plugin which adds navigation controls to Calendar.
             *
             * @module calendarnavigator
             */
            var CONTENT_BOX = "contentBox",
                HOST        = "host",
                getCN       = Y.ClassNameManager.getClassName,
                substitute  = Y.Lang.sub,
                node        = Y.Node,
                create      = node.create,
                CALENDAR    = 'calendar',
                CALENDARNAV = 'calendarnav',
                CAL_HD      = getCN(CALENDAR, 'header'),
                CAL_PREV_M  = getCN(CALENDARNAV, 'prevmonth'),
                CAL_NEXT_M  = getCN(CALENDARNAV, 'nextmonth'),
                CAL_DIS_M   = getCN(CALENDARNAV, 'month-disabled'),
                ydate       = Y.DataType.Date;
            /**
             * A plugin class which adds navigation controls to Calendar.
             *
             * @class CalendarNavigator
             * @extends Plugin.Base
             * @namespace Plugin
             */
            function CalendarNavigator() {
                CalendarNavigator.superclass.constructor.apply(this, arguments);
            }
            
            /**
             * The namespace for the plugin. This will be the property on the widget, which will
             * reference the plugin instance, when it's plugged in.
             *
             * @property NS
             * @static
             * @type String
             * @default "navigator"
             */
            CalendarNavigator.NS = "navigator";
            
            /**
             * The NAME of the CalendarNavigator class. Used to prefix events generated
             * by the plugin class.
             *
             * @property NAME
             * @static
             * @type String
             * @default "pluginCalendarNavigator"
             */
            CalendarNavigator.NAME = "pluginCalendarNavigator";
            
            
            /**
             * Static property used to define the default attribute
             * configuration for the plugin.
             *
             * @property ATTRS
             * @type Object
             * @static
             */
            CalendarNavigator.ATTRS = {
            
                /**
                 * The number of months to shift by when the control arrows are clicked.
                 *
                 * @attribute shiftByMonths
                 * @type Number
                 * @default 1 (months)
                 */
                shiftByMonths : {
                    value: 1
                }
            };
            
               /**
                * The CSS classnames for the calendar navigator controls.
                * @property CALENDARNAV_STRINGS
                * @type Object
                * @readOnly
                * @protected
                * @static
                */
            CalendarNavigator.CALENDARNAV_STRINGS = {
               prev_month_class: CAL_PREV_M,
               next_month_class: CAL_NEXT_M
            };
            
               /**
                * The template for the calendar navigator previous month control.
                * @property PREV_MONTH_CONTROL_TEMPLATE
                * @type String
                * @protected
                * @static
                */
            CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {prev_month_class}" role="button" aria-label="{prev_month_arialabel}" ' +
                                                                'tabindex="{control_tabindex}" />';
               /**
                * The template for the calendar navigator next month control.
                * @property NEXT_MONTH_CONTROL_TEMPLATE
                * @type String
                * @readOnly
                * @protected
                * @static
                */
            CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {next_month_class}" role="button" aria-label="{next_month_arialabel}" ' +
                                                                'tabindex="{control_tabindex}" />';
            
            
            Y.extend(CalendarNavigator, Y.Plugin.Base, {
            
                _eventAttachments : {},
                _controls: {},
            
                /**
                 * The initializer lifecycle implementation. Modifies the host widget's
                 * render to add navigation controls.
                 *
                 * @method initializer
                 */
                initializer : function() {
            
                    // After the host has rendered its UI, place the navigation cotnrols
                    this._controls = {};
                    this._eventAttachments = {};
            
                    this.afterHostMethod("renderUI", this._initNavigationControls);
                },
            
                /**
                 * The initializer destructor implementation. Responsible for destroying the initialized
                 * control mechanisms.
                 *
                 * @method destructor
                 */
                destructor : function() {
            
                },
            
                /**
                 * Private utility method that focuses on a navigation button when it is clicked
                 * or pressed with a keyboard.
                 *
                 * @method _focusNavigation
                 * @param {Event} ev Click or keydown event from the controls
                 * @protected
                 */
                _focusNavigation : function (ev) {
                    ev.currentTarget.focus();
                },
            
                /**
                 * Private utility method that subtracts months from the host calendar date
                 * based on the control click and the shiftByMonths property.
                 *
                 * @method _subtractMonths
                 * @param {Event} ev Click event from the controls
                 * @protected
                 */
                _subtractMonths : function (ev) {
                    if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
                        var host = this.get(HOST),
                            oldDate = host.get("date");
                        host.set("date", ydate.addMonths(oldDate, -1*this.get("shiftByMonths")));
                        ev.preventDefault();
                    }
                },
            
                /**
                 * Private utility method that adds months to the host calendar date
                 * based on the control click and the shiftByMonths property.
                 *
                 * @method _addMonths
                 * @param {Event} ev Click event from the controls
                 * @protected
                 */
                _addMonths : function (ev) {
                    if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
                        var host = this.get(HOST),
                            oldDate = host.get("date");
                        host.set("date", ydate.addMonths(oldDate, this.get("shiftByMonths")));
                        ev.preventDefault();
                    }
                },
            
            
                _updateControlState : function () {
            
                    var host      = this.get(HOST),
                        startDate = host.get('date'),
                        endDate   = ydate.addMonths(startDate, host._paneNumber - 1),
                        minDate   = host._normalizeDate(host.get("minimumDate")),
                        maxDate   = host._normalizeDate(host.get("maximumDate"));
            
                    if (ydate.areEqual(minDate, startDate)) {
                        if (this._eventAttachments.prevMonth) {
                            this._eventAttachments.prevMonth.detach();
                            this._eventAttachments.prevMonth = false;
                        }
            
                        if (!this._controls.prevMonth.hasClass(CAL_DIS_M)) {
                            this._controls.prevMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
                        }
                    }
                    else {
                        if (!this._eventAttachments.prevMonth) {
                        this._eventAttachments.prevMonth = this._controls.prevMonth.on(["click", "keydown"], this._subtractMonths, this);
                        }
                        if (this._controls.prevMonth.hasClass(CAL_DIS_M)) {
                          this._controls.prevMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
                        }
                    }
            
                    if (ydate.areEqual(maxDate, endDate)) {
                        if (this._eventAttachments.nextMonth) {
                            this._eventAttachments.nextMonth.detach();
                            this._eventAttachments.nextMonth = false;
                        }
            
                        if (!this._controls.nextMonth.hasClass(CAL_DIS_M)) {
                            this._controls.nextMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
                        }
                    }
                    else {
                        if (!this._eventAttachments.nextMonth) {
                        this._eventAttachments.nextMonth = this._controls.nextMonth.on(["click", "keydown"], this._addMonths, this);
                        }
                        if (this._controls.nextMonth.hasClass(CAL_DIS_M)) {
                          this._controls.nextMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
                        }
                    }
            
                    this._controls.prevMonth.on(["click", "keydown"], this._focusNavigation, this);
                    this._controls.nextMonth.on(["click", "keydown"], this._focusNavigation, this);
                },
            
            
            
            
                /**
                 * Private render assist method that renders the previous month control
                 *
                 * @method _renderPrevControls
                 * @private
                 */
                _renderPrevControls : function () {
                  var prevControlNode = create(substitute (CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE,
                                           CalendarNavigator.CALENDARNAV_STRINGS));
                  prevControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);
            
                  return prevControlNode;
                },
            
                /**
                 * Private render assist method that renders the next month control
                 *
                 * @method _renderNextControls
                 * @private
                 */
                _renderNextControls : function () {
                  var nextControlNode = create(substitute (CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE,
                                           CalendarNavigator.CALENDARNAV_STRINGS));
                  nextControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);
            
                  return nextControlNode;
                },
            
                /**
                 * Protected render assist method that initialized and renders the navigation controls.
                 * @method _initNavigationControls
                 * @protected
                 */
                _initNavigationControls : function() {
                    var host = this.get(HOST),
                        headerCell = host.get(CONTENT_BOX).one("." + CAL_HD);
            
                    CalendarNavigator.CALENDARNAV_STRINGS.control_tabindex = host.get("tabIndex");
                    CalendarNavigator.CALENDARNAV_STRINGS.prev_month_arialabel = "Go to previous month";
                    CalendarNavigator.CALENDARNAV_STRINGS.next_month_arialabel = "Go to next month";
            
                    this._controls.prevMonth = this._renderPrevControls();
                    this._controls.nextMonth = this._renderNextControls();
            
                    this._updateControlState();
            
                    host.after(["dateChange", "minimumDateChange", "maximumDateChange"], this._updateControlState, this);
            
                    headerCell.prepend(this._controls.prevMonth);
                    headerCell.append(this._controls.nextMonth);
                }
            });
            
            Y.namespace("Plugin").CalendarNavigator = CalendarNavigator;