API Docs for: 3.8.0
Show:

File: calendar/js/calendarnavigator.js

  1. /**
  2.  * Provides a plugin which adds navigation controls to Calendar.
  3.  *
  4.  * @module calendarnavigator
  5.  */
  6. var CONTENT_BOX = "contentBox",
  7.     HOST        = "host",
  8.     getCN       = Y.ClassNameManager.getClassName,
  9.     substitute  = Y.Lang.sub,
  10.     node        = Y.Node,
  11.     create      = node.create,
  12.     CALENDAR    = 'calendar',
  13.     CALENDARNAV = 'calendarnav',
  14.     CAL_HD      = getCN(CALENDAR, 'header'),
  15.     CAL_PREV_M  = getCN(CALENDARNAV, 'prevmonth'),
  16.     CAL_NEXT_M  = getCN(CALENDARNAV, 'nextmonth'),
  17.     CAL_DIS_M   = getCN(CALENDARNAV, 'month-disabled'),
  18.     ydate       = Y.DataType.Date;
  19. /**
  20.  * A plugin class which adds navigation controls to Calendar.
  21.  *
  22.  * @class CalendarNavigator
  23.  * @extends Plugin.Base
  24.  * @namespace Plugin
  25.  */
  26. function CalendarNavigator() {
  27.     CalendarNavigator.superclass.constructor.apply(this, arguments);
  28. }

  29. /**
  30.  * The namespace for the plugin. This will be the property on the widget, which will
  31.  * reference the plugin instance, when it's plugged in.
  32.  *
  33.  * @property NS
  34.  * @static
  35.  * @type String
  36.  * @default "navigator"
  37.  */
  38. CalendarNavigator.NS = "navigator";

  39. /**
  40.  * The NAME of the CalendarNavigator class. Used to prefix events generated
  41.  * by the plugin class.
  42.  *
  43.  * @property NAME
  44.  * @static
  45.  * @type String
  46.  * @default "pluginCalendarNavigator"
  47.  */
  48. CalendarNavigator.NAME = "pluginCalendarNavigator";


  49. /**
  50.  * Static property used to define the default attribute
  51.  * configuration for the plugin.
  52.  *
  53.  * @property ATTRS
  54.  * @type Object
  55.  * @static
  56.  */
  57. CalendarNavigator.ATTRS = {

  58.     /**
  59.      * The number of months to shift by when the control arrows are clicked.
  60.      *
  61.      * @attribute shiftByMonths
  62.      * @type Number
  63.      * @default 1 (months)
  64.      */
  65.     shiftByMonths : {
  66.         value: 1
  67.     }
  68. };

  69.    /**
  70.     * The CSS classnames for the calendar navigator controls.
  71.     * @property CALENDARNAV_STRINGS
  72.     * @type Object
  73.     * @readOnly
  74.     * @protected
  75.     * @static
  76.     */
  77. CalendarNavigator.CALENDARNAV_STRINGS = {
  78.    prev_month_class: CAL_PREV_M,
  79.    next_month_class: CAL_NEXT_M
  80. };

  81.    /**
  82.     * The template for the calendar navigator previous month control.
  83.     * @property PREV_MONTH_CONTROL_TEMPLATE
  84.     * @type String
  85.     * @protected
  86.     * @static
  87.     */
  88. CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {prev_month_class}" role="button" aria-label="{prev_month_arialabel}" ' +
  89.                                                     'tabindex="{control_tabindex}">' +
  90.                                                     "<span>&lt;</span>" +
  91.                                                 '</a>';
  92.    /**
  93.     * The template for the calendar navigator next month control.
  94.     * @property NEXT_MONTH_CONTROL_TEMPLATE
  95.     * @type String
  96.     * @readOnly
  97.     * @protected
  98.     * @static
  99.     */
  100. CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE = '<a class="yui3-u {next_month_class}" role="button" aria-label="{next_month_arialabel}" ' +
  101.                                                     'tabindex="{control_tabindex}">' +
  102.                                                     "<span>&gt;</span>" +
  103.                                                 '</a>';


  104. Y.extend(CalendarNavigator, Y.Plugin.Base, {

  105.     _eventAttachments : {},
  106.     _controls: {},

  107.     /**
  108.      * The initializer lifecycle implementation. Modifies the host widget's
  109.      * render to add navigation controls.
  110.      *
  111.      * @method initializer
  112.      */
  113.     initializer : function() {

  114.         // After the host has rendered its UI, place the navigation cotnrols
  115.         this._controls = {};
  116.         this._eventAttachments = {};

  117.         this.afterHostMethod("renderUI", this._initNavigationControls);
  118.     },

  119.     /**
  120.      * The initializer destructor implementation. Responsible for destroying the initialized
  121.      * control mechanisms.
  122.      *
  123.      * @method destructor
  124.      */
  125.     destructor : function() {

  126.     },

  127.     /**
  128.      * Private utility method that focuses on a navigation button when it is clicked
  129.      * or pressed with a keyboard.
  130.      *
  131.      * @method _focusNavigation
  132.      * @param {Event} ev Click or keydown event from the controls
  133.      * @protected
  134.      */
  135.     _focusNavigation : function (ev) {
  136.         ev.currentTarget.focus();
  137.     },

  138.     /**
  139.      * Private utility method that subtracts months from the host calendar date
  140.      * based on the control click and the shiftByMonths property.
  141.      *
  142.      * @method _subtractMonths
  143.      * @param {Event} ev Click event from the controls
  144.      * @protected
  145.      */
  146.     _subtractMonths : function (ev) {
  147.         if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
  148.             var host = this.get(HOST),
  149.                 oldDate = host.get("date");
  150.             host.set("date", ydate.addMonths(oldDate, -1*this.get("shiftByMonths")));
  151.             ev.preventDefault();
  152.         }
  153.     },

  154.     /**
  155.      * Private utility method that adds months to the host calendar date
  156.      * based on the control click and the shiftByMonths property.
  157.      *
  158.      * @method _addMonths
  159.      * @param {Event} ev Click event from the controls
  160.      * @protected
  161.      */
  162.     _addMonths : function (ev) {
  163.         if ( (ev.type === "click") || (ev.type === "keydown" && (ev.keyCode === 13 || ev.keyCode === 32)) ) {
  164.             var host = this.get(HOST),
  165.                 oldDate = host.get("date");
  166.             host.set("date", ydate.addMonths(oldDate, this.get("shiftByMonths")));
  167.             ev.preventDefault();
  168.         }
  169.     },


  170.     _updateControlState : function () {

  171.         var host = this.get(HOST);
  172.         if (ydate.areEqual(host.get("minimumDate"), host.get("date"))) {
  173.             if (this._eventAttachments.prevMonth) {
  174.                 this._eventAttachments.prevMonth.detach();
  175.                 this._eventAttachments.prevMonth = false;
  176.             }

  177.             if (!this._controls.prevMonth.hasClass(CAL_DIS_M)) {
  178.                 this._controls.prevMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
  179.             }
  180.         }
  181.         else {
  182.             if (!this._eventAttachments.prevMonth) {
  183.             this._eventAttachments.prevMonth = this._controls.prevMonth.on(["click", "keydown"], this._subtractMonths, this);
  184.             }
  185.             if (this._controls.prevMonth.hasClass(CAL_DIS_M)) {
  186.               this._controls.prevMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
  187.             }
  188.         }

  189.         if (ydate.areEqual(host.get("maximumDate"), ydate.addMonths(host.get("date"), host._paneNumber - 1))) {
  190.             if (this._eventAttachments.nextMonth) {
  191.                 this._eventAttachments.nextMonth.detach();
  192.                 this._eventAttachments.nextMonth = false;
  193.             }

  194.             if (!this._controls.nextMonth.hasClass(CAL_DIS_M)) {
  195.                 this._controls.nextMonth.addClass(CAL_DIS_M).setAttribute("aria-disabled", "true");
  196.             }
  197.         }
  198.         else {
  199.             if (!this._eventAttachments.nextMonth) {
  200.             this._eventAttachments.nextMonth = this._controls.nextMonth.on(["click", "keydown"], this._addMonths, this);
  201.             }
  202.             if (this._controls.nextMonth.hasClass(CAL_DIS_M)) {
  203.               this._controls.nextMonth.removeClass(CAL_DIS_M).setAttribute("aria-disabled", "false");
  204.             }
  205.         }

  206.         this._controls.prevMonth.on(["click", "keydown"], this._focusNavigation, this);
  207.         this._controls.nextMonth.on(["click", "keydown"], this._focusNavigation, this);
  208.     },




  209.     /**
  210.      * Private render assist method that renders the previous month control
  211.      *
  212.      * @method _renderPrevControls
  213.      * @private
  214.      */
  215.     _renderPrevControls : function () {
  216.       var prevControlNode = create(substitute (CalendarNavigator.PREV_MONTH_CONTROL_TEMPLATE,
  217.                                CalendarNavigator.CALENDARNAV_STRINGS));
  218.       prevControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);

  219.       return prevControlNode;
  220.     },

  221.     /**
  222.      * Private render assist method that renders the next month control
  223.      *
  224.      * @method _renderNextControls
  225.      * @private
  226.      */
  227.     _renderNextControls : function () {
  228.       var nextControlNode = create(substitute (CalendarNavigator.NEXT_MONTH_CONTROL_TEMPLATE,
  229.                                CalendarNavigator.CALENDARNAV_STRINGS));
  230.       nextControlNode.on("selectstart", this.get(HOST)._preventSelectionStart);

  231.       return nextControlNode;
  232.     },

  233.     /**
  234.      * Protected render assist method that initialized and renders the navigation controls.
  235.      * @method _initNavigationControls
  236.      * @protected
  237.      */
  238.     _initNavigationControls : function() {
  239.         var host = this.get(HOST),
  240.             headerCell = host.get(CONTENT_BOX).one("." + CAL_HD);

  241.         CalendarNavigator.CALENDARNAV_STRINGS.control_tabindex = host.get("tabIndex");
  242.         CalendarNavigator.CALENDARNAV_STRINGS.prev_month_arialabel = "Go to previous month";
  243.         CalendarNavigator.CALENDARNAV_STRINGS.next_month_arialabel = "Go to next month";

  244.         this._controls.prevMonth = this._renderPrevControls();
  245.         this._controls.nextMonth = this._renderNextControls();

  246.         this._updateControlState();

  247.         host.after("dateChange", this._updateControlState, this);

  248.         headerCell.prepend(this._controls.prevMonth);
  249.         headerCell.append(this._controls.nextMonth);
  250.     }
  251. });

  252. Y.namespace("Plugin").CalendarNavigator = CalendarNavigator;

  253.