dijit/Calendar.js

  • Provides:

    • dijit.Calendar
  • dijit.Calendar

    • type
      Function
    • chains:
      • dijit._Widget: (prototype)
      • dijit._Widget: (call)
      • dijit._Templated: (call)
      • dijit._CssStateMixin: (call)
    • mixins:
      • dijit._Templated.prototype: (prototype)
      • dijit._CssStateMixin.prototype: (prototype)
    • summary
      A simple GUI for choosing a date in the context of a monthly calendar.
    • description
      A simple GUI for choosing a date in the context of a monthly calendar.
      This widget can't be used in a form because it doesn't serialize the date to an
      `<input>` field.  For a form element, use dijit.form.DateTextBox instead.
      
      Note that the parser takes all dates attributes passed in the
      [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
      so that they are serializable and locale-independent.
    • example
      
      	var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
    • example
      
      	<div dojoType="dijit.Calendar"></div>
    • parameters:
      • args: (typeof Object)
    • source: [view]
         var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
         this.dateClassObj = dojo.getObject(dateClass, false);
         this.datePackage = args.datePackage || this.datePackage;
         this.dateFuncObj = dojo.getObject(this.datePackage, false);
         this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
  • dijit.Calendar.templateString

    • summary
  • dijit.Calendar.widgetsInTemplate

    • summary
  • dijit.Calendar.value

    • type
      Date
    • summary
      The currently selected Date, initially set to invalid date to indicate no selection.
      
      TODO: for 2.0 make this a string (ISO format) rather than a Date
  • dijit.Calendar.datePackage

    • type
      String
    • summary
      JavaScript namespace to find Calendar routines.  Uses Gregorian Calendar routines
      at dojo.date by default.
  • dijit.Calendar.dayWidth

    • type
      String
    • summary
      How to represent the days of the week in the calendar header. See dojo.date.locale
  • dijit.Calendar.tabIndex

    • type
      Integer
    • summary
      Order fields are traversed when user hits the tab key
  • dijit.Calendar.currentFocus

    • type
      Date
    • summary
      Date object containing the currently focused date, or the date which would be focused
      if the calendar itself was focused.   Also indicates which year and month to display,
      i.e. the current &quot;page&quot; the calendar is on.
  • dijit.Calendar.baseClass

    • summary
  • dijit.Calendar.cssStateNodes

    • type
      Object
    • summary
  • dijit.Calendar._isValidDate

    • type
      Function
    • parameters:
      • value: (typeof Date)
    • source: [view]
         return value && !isNaN(value) && typeof value == "object" &&
          value.toString() != this.constructor.prototype.value.toString();
    • summary
      Runs various tests on the value, checking that it's a valid date, rather
      than blank or NaN.
    • tags:
  • dijit.Calendar.setValue

    • type
      Function
    • parameters:
      • value: (typeof Date)
    • source: [view]
         dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
         this.set('value', value);
    • summary
      Deprecated.   Use set('value', ...) instead.
    • tags:
  • dijit.Calendar._getValueAttr

    • type
      Function
    • source: [view]
      define("dijit/Calendar", ["dojo", "dijit", "text!dijit/templates/Calendar.html", "dojo/cldr/supplemental", "dojo/date", "dojo/date/locale", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton"], function(dojo, dijit) {


      dojo.declare(
       "dijit.Calendar",
       [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
       {
        // summary:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //
        // description:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //  This widget can't be used in a form because it doesn't serialize the date to an
        //  `` field. For a form element, use dijit.form.DateTextBox instead.
        //
        //  Note that the parser takes all dates attributes passed in the
        //  [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
        //  so that they are serializable and locale-independent.
        //
        // example:
        // | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
        //
        // example:
        // | 



        templateString: dojo.cache("dijit", "templates/Calendar.html"),
        widgetsInTemplate: true,


        // value: Date
        //  The currently selected Date, initially set to invalid date to indicate no selection.
        value: new Date(""),
        // TODO: for 2.0 make this a string (ISO format) rather than a Date


        // datePackage: String
        //  JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
        //  at dojo.date by default.
        datePackage: "dojo.date",


        // dayWidth: String
        //  How to represent the days of the week in the calendar header. See dojo.date.locale
        dayWidth: "narrow",


        // tabIndex: Integer
        //  Order fields are traversed when user hits the tab key
        tabIndex: "0",

        
        // currentFocus: Date
        //  Date object containing the currently focused date, or the date which would be focused
        //  if the calendar itself was focused. Also indicates which year and month to display,
        //  i.e. the current "page" the calendar is on.
        currentFocus: new Date(),


        baseClass:"dijitCalendar",


        // Set node classes for various mouse events, see dijit._CssStateMixin for more details
        cssStateNodes: {
         "decrementMonth": "dijitCalendarArrow",
         "incrementMonth": "dijitCalendarArrow",
         "previousYearLabelNode": "dijitCalendarPreviousYear",
         "nextYearLabelNode": "dijitCalendarNextYear"
        },


        _isValidDate: function(/*Date*/ value){
         // summary:
         //  Runs various tests on the value, checking that it's a valid date, rather
         //  than blank or NaN.
         // tags:
         //  private
         return value && !isNaN(value) && typeof value == "object" &&
          value.toString() != this.constructor.prototype.value.toString();
        },


        setValue: function(/*Date*/ value){
         // summary:
         // Deprecated. Use set('value', ...) instead.
         // tags:
         // deprecated
         dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
         this.set('value', value);
        },


        _getValueAttr: function(){
         // summary:
         //  Support get('value')


         // this.value is set to 1AM, but return midnight, local time for back-compat
         var value = new this.dateClassObj(this.value);
         value.setHours(0, 0, 0, 0);


         // If daylight savings pushes midnight to the previous date, fix the Date
         // object to point at 1am so it will represent the correct day. See #9366
         if(value.getDate() < this.value.getDate()){
          value = this.dateFuncObj.add(value, "hour", 1);
         }
         return value;
    • summary
  • dijit.Calendar._setValueAttr

    • type
      Function
    • parameters:
      • value: (typeof Date|Number)
        Either a Date or the number of seconds since 1970.
      • priorityChange: (typeof Boolean)
    • source: [view]
         if(value){
          // convert from Number to Date, or make copy of Date object so that setHours() call below
          // doesn't affect original value
          value = new this.dateClassObj(value);
         }
         if(this._isValidDate(value)){
          if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
           value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)

       
           if(!this.isDisabledDate(value, this.lang)){
            this._set("value", value);

        
            // Set focus cell to the new value. Arguably this should only happen when there isn't a current
            // focus point. This will also repopulate the grid, showing the new selected value (and possibly
            // new month/year).
            this.set("currentFocus", value);

       
            if(priorityChange || typeof priorityChange == "undefined"){
             this.onChange(this.get('value'));
             this.onValueSelected(this.get('value')); // remove in 2.0
            }
           }
          }
         }else{
          // clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
          this._set("value", null);
          this.set("currentFocus", this.currentFocus);
         }
    • summary
      Support set(&quot;value&quot;, ...)
    • description
      Set the current date and update the UI.  If the date is disabled, the value will
      not change, but the display will change to the corresponding month.
    • tags:
  • dijit.Calendar._setText

    • type
      Function
    • parameters:
      • node: (typeof )
      • text: (typeof )
    • source: [view]
         while(node.firstChild){
          node.removeChild(node.firstChild);
         }
         node.appendChild(dojo.doc.createTextNode(text));
    • summary
      This just sets the content of node to the specified text.
      Can't do &quot;node.innerHTML=text&quot; because of an IE bug w/tables, see #3434.
    • tags:
  • dijit.Calendar._populateGrid

    • type
      Function
    • source: [view]
         var month = new this.dateClassObj(this.currentFocus);
         month.setDate(1);


         var firstDay = month.getDay(),
          daysInMonth = this.dateFuncObj.getDaysInMonth(month),
          daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
          today = new this.dateClassObj(),
          dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         if(dayOffset > firstDay){ dayOffset -= 7; }


         // Iterate through dates in the calendar and fill in date numbers and style info
         dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
          i += dayOffset;
          var date = new this.dateClassObj(month),
           number, clazz = "dijitCalendar", adj = 0;


          if(i < firstDay){
           number = daysInPreviousMonth - firstDay + i + 1;
           adj = -1;
           clazz += "Previous";
          }else if(i >= (firstDay + daysInMonth)){
           number = i - firstDay - daysInMonth + 1;
           adj = 1;
           clazz += "Next";
          }else{
           number = i - firstDay + 1;
           clazz += "Current";
          }


          if(adj){
           date = this.dateFuncObj.add(date, "month", adj);
          }
          date.setDate(number);


          if(!this.dateFuncObj.compare(date, today, "date")){
           clazz = "dijitCalendarCurrentDate " + clazz;
          }


          if(this._isSelectedDate(date, this.lang)){
           clazz = "dijitCalendarSelectedDate " + clazz;
          }


          if(this.isDisabledDate(date, this.lang)){
           clazz = "dijitCalendarDisabledDate " + clazz;
          }


          var clazz2 = this.getClassForDate(date, this.lang);
          if(clazz2){
           clazz = clazz2 + " " + clazz;
          }


          template.className = clazz + "Month dijitCalendarDateTemplate";
          template.dijitDateValue = date.valueOf();    // original code
          dojo.attr(template, "dijitDateValue", date.valueOf()); // so I can dojo.query() it
          var label = dojo.query(".dijitCalendarDateLabel", template)[0],
           text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
          this._setText(label, text);
         }, this);


         // Repopulate month drop down list based on current year.
         // Need to do this to hide leap months in Hebrew calendar.
         var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
         this.monthDropDownButton.dropDown.set("months", monthNames);


         // Set name of current month and also fill in spacer element with all the month names
         // (invisible) so that the maximum width will affect layout. But not on IE6 because then
         // the center overlaps the right (due to a browser bug).
         this.monthDropDownButton.containerNode.innerHTML =
          (dojo.isIE == 6 ? "" : "
      " + this.monthDropDownButton.dropDown.domNode.innerHTML + "
      ") +
          "
      " + monthNames[month.getMonth()] + "
      ";


         // Fill in localized prev/current/next years
         var y = month.getFullYear() - 1;
         var d = new this.dateClassObj();
         dojo.forEach(["previous", "current", "next"], function(name){
          d.setFullYear(y++);
          this._setText(this[name+"YearLabelNode"],
           this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
         }, this);
    • summary
      Fills in the calendar grid with each day (1-31)
    • tags:
  • dijit.Calendar.goToToday

    • type
      Function
    • source: [view]
         this.set('value', new this.dateClassObj());
    • summary
      Sets calendar's value to today's date
  • dijit.Calendar.postMixInProperties

    • type
      Function
    • source: [view]
      define("dijit/Calendar", ["dojo", "dijit", "text!dijit/templates/Calendar.html", "dojo/cldr/supplemental", "dojo/date", "dojo/date/locale", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton"], function(dojo, dijit) {


      dojo.declare(
       "dijit.Calendar",
       [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
       {
        // summary:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //
        // description:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //  This widget can't be used in a form because it doesn't serialize the date to an
        //  `` field. For a form element, use dijit.form.DateTextBox instead.
        //
        //  Note that the parser takes all dates attributes passed in the
        //  [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
        //  so that they are serializable and locale-independent.
        //
        // example:
        // | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
        //
        // example:
        // | 



        templateString: dojo.cache("dijit", "templates/Calendar.html"),
        widgetsInTemplate: true,


        // value: Date
        //  The currently selected Date, initially set to invalid date to indicate no selection.
        value: new Date(""),
        // TODO: for 2.0 make this a string (ISO format) rather than a Date


        // datePackage: String
        //  JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
        //  at dojo.date by default.
        datePackage: "dojo.date",


        // dayWidth: String
        //  How to represent the days of the week in the calendar header. See dojo.date.locale
        dayWidth: "narrow",


        // tabIndex: Integer
        //  Order fields are traversed when user hits the tab key
        tabIndex: "0",

        
        // currentFocus: Date
        //  Date object containing the currently focused date, or the date which would be focused
        //  if the calendar itself was focused. Also indicates which year and month to display,
        //  i.e. the current "page" the calendar is on.
        currentFocus: new Date(),


        baseClass:"dijitCalendar",


        // Set node classes for various mouse events, see dijit._CssStateMixin for more details
        cssStateNodes: {
         "decrementMonth": "dijitCalendarArrow",
         "incrementMonth": "dijitCalendarArrow",
         "previousYearLabelNode": "dijitCalendarPreviousYear",
         "nextYearLabelNode": "dijitCalendarNextYear"
        },


        _isValidDate: function(/*Date*/ value){
         // summary:
         //  Runs various tests on the value, checking that it's a valid date, rather
         //  than blank or NaN.
         // tags:
         //  private
         return value && !isNaN(value) && typeof value == "object" &&
          value.toString() != this.constructor.prototype.value.toString();
        },


        setValue: function(/*Date*/ value){
         // summary:
         // Deprecated. Use set('value', ...) instead.
         // tags:
         // deprecated
         dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
         this.set('value', value);
        },


        _getValueAttr: function(){
         // summary:
         //  Support get('value')


         // this.value is set to 1AM, but return midnight, local time for back-compat
         var value = new this.dateClassObj(this.value);
         value.setHours(0, 0, 0, 0);


         // If daylight savings pushes midnight to the previous date, fix the Date
         // object to point at 1am so it will represent the correct day. See #9366
         if(value.getDate() < this.value.getDate()){
          value = this.dateFuncObj.add(value, "hour", 1);
         }
         return value;
        },


        _setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
         // summary:
         //  Support set("value", ...)
         // description:
         //   Set the current date and update the UI. If the date is disabled, the value will
         //  not change, but the display will change to the corresponding month.
         // value:
         //  Either a Date or the number of seconds since 1970.
         // tags:
         // protected
         if(value){
          // convert from Number to Date, or make copy of Date object so that setHours() call below
          // doesn't affect original value
          value = new this.dateClassObj(value);
         }
         if(this._isValidDate(value)){
          if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
           value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)

       
           if(!this.isDisabledDate(value, this.lang)){
            this._set("value", value);

        
            // Set focus cell to the new value. Arguably this should only happen when there isn't a current
            // focus point. This will also repopulate the grid, showing the new selected value (and possibly
            // new month/year).
            this.set("currentFocus", value);

       
            if(priorityChange || typeof priorityChange == "undefined"){
             this.onChange(this.get('value'));
             this.onValueSelected(this.get('value')); // remove in 2.0
            }
           }
          }
         }else{
          // clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
          this._set("value", null);
          this.set("currentFocus", this.currentFocus);
         }
        },


        _setText: function(node, text){
         // summary:
         //  This just sets the content of node to the specified text.
         //  Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
         // tags:
         // private
         while(node.firstChild){
          node.removeChild(node.firstChild);
         }
         node.appendChild(dojo.doc.createTextNode(text));
        },


        _populateGrid: function(){
         // summary:
         // Fills in the calendar grid with each day (1-31)
         // tags:
         // private


         var month = new this.dateClassObj(this.currentFocus);
         month.setDate(1);


         var firstDay = month.getDay(),
          daysInMonth = this.dateFuncObj.getDaysInMonth(month),
          daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
          today = new this.dateClassObj(),
          dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         if(dayOffset > firstDay){ dayOffset -= 7; }


         // Iterate through dates in the calendar and fill in date numbers and style info
         dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
          i += dayOffset;
          var date = new this.dateClassObj(month),
           number, clazz = "dijitCalendar", adj = 0;


          if(i < firstDay){
           number = daysInPreviousMonth - firstDay + i + 1;
           adj = -1;
           clazz += "Previous";
          }else if(i >= (firstDay + daysInMonth)){
           number = i - firstDay - daysInMonth + 1;
           adj = 1;
           clazz += "Next";
          }else{
           number = i - firstDay + 1;
           clazz += "Current";
          }


          if(adj){
           date = this.dateFuncObj.add(date, "month", adj);
          }
          date.setDate(number);


          if(!this.dateFuncObj.compare(date, today, "date")){
           clazz = "dijitCalendarCurrentDate " + clazz;
          }


          if(this._isSelectedDate(date, this.lang)){
           clazz = "dijitCalendarSelectedDate " + clazz;
          }


          if(this.isDisabledDate(date, this.lang)){
           clazz = "dijitCalendarDisabledDate " + clazz;
          }


          var clazz2 = this.getClassForDate(date, this.lang);
          if(clazz2){
           clazz = clazz2 + " " + clazz;
          }


          template.className = clazz + "Month dijitCalendarDateTemplate";
          template.dijitDateValue = date.valueOf();    // original code
          dojo.attr(template, "dijitDateValue", date.valueOf()); // so I can dojo.query() it
          var label = dojo.query(".dijitCalendarDateLabel", template)[0],
           text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
          this._setText(label, text);
         }, this);


         // Repopulate month drop down list based on current year.
         // Need to do this to hide leap months in Hebrew calendar.
         var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
         this.monthDropDownButton.dropDown.set("months", monthNames);


         // Set name of current month and also fill in spacer element with all the month names
         // (invisible) so that the maximum width will affect layout. But not on IE6 because then
         // the center overlaps the right (due to a browser bug).
         this.monthDropDownButton.containerNode.innerHTML =
          (dojo.isIE == 6 ? "" : "
      " + this.monthDropDownButton.dropDown.domNode.innerHTML + "
      ") +
          "
      " + monthNames[month.getMonth()] + "
      ";


         // Fill in localized prev/current/next years
         var y = month.getFullYear() - 1;
         var d = new this.dateClassObj();
         dojo.forEach(["previous", "current", "next"], function(name){
          d.setFullYear(y++);
          this._setText(this[name+"YearLabelNode"],
           this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
         }, this);
        },


        goToToday: function(){
         // summary:
         // Sets calendar's value to today's date
         this.set('value', new this.dateClassObj());
        },


        constructor: function(/*Object*/args){
         var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
         this.dateClassObj = dojo.getObject(dateClass, false);
         this.datePackage = args.datePackage || this.datePackage;
         this.dateFuncObj = dojo.getObject(this.datePackage, false);
         this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
        },


        postMixInProperties: function(){
         // Parser.instantiate sometimes passes in NaN for IE. Use default value in prototype instead.
         // TODO: remove this for 2.0 (thanks to #11511)
         if(isNaN(this.value)){ delete this.value; }


         this.inherited(arguments);
    • summary
  • dijit.Calendar.buildRendering

    • type
      Function
    • source: [view]
         this.inherited(arguments);
         dojo.setSelectable(this.domNode, false);


         var cloneClass = dojo.hitch(this, function(clazz, n){
          var template = dojo.query(clazz, this.domNode)[0];
           for(var i=0; i     template.parentNode.appendChild(template.cloneNode(true));
          }
         });


         // clone the day label and calendar day templates 6 times to make 7 columns
         cloneClass(".dijitCalendarDayLabelTemplate", 6);
         cloneClass(".dijitCalendarDateTemplate", 6);


         // now make 6 week rows
         cloneClass(".dijitCalendarWeekTemplate", 5);


         // insert localized day names in the header
         var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
         var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
          this._setText(label, dayNames[(i + dayOffset) % 7]);
         }, this);


         var dateObj = new this.dateClassObj(this.currentFocus);


         this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
          id: this.id + "_mdd",
          onChange: dojo.hitch(this, "_onMonthSelect")
         });


         this.set('currentFocus', dateObj, false); // draw the grid to the month specified by currentFocus


         // Set up repeating mouse behavior for increment/decrement of months/years
         var _this = this;
         var typematic = function(nodeProp, dateProp, adj){
          _this._connects.push(
           dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
            if(count >= 0){ _this._adjustDisplay(dateProp, adj); }
           }, 0.8, 500)
          );
         };
         typematic("incrementMonth", "month", 1);
         typematic("decrementMonth", "month", -1);
         typematic("nextYearLabelNode", "year", 1);
         typematic("previousYearLabelNode", "year", -1);
    • summary
  • dijit.Calendar._adjustDisplay

    • type
      Function
    • parameters:
      • part: (typeof String)
        &quot;month&quot; or &quot;year&quot;
      • amount: (typeof int)
        Number of months or years
    • source: [view]
         this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
    • summary
      Moves calendar forwards or backwards by months or years
    • tags:
  • dijit.Calendar._setCurrentFocusAttr

    • type
      Function
    • parameters:
      • date: (typeof Date)
      • forceFocus: (typeof Boolean)
        If true, will focus() the cell even if calendar itself doesn't have focus
    • source: [view]
         var oldFocus = this.currentFocus,
          oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : null;


         // round specified value to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
         date = new this.dateClassObj(date);
         date.setHours(1, 0, 0, 0);


         this._set("currentFocus", date);


         // TODO: only re-populate grid when month/year has changed
         this._populateGrid();


         // set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
         var newCell = dojo.query("[dijitDateValue=" + date.valueOf() + "]", this.domNode)[0];
         newCell.setAttribute("tabIndex", this.tabIndex);
         if(this._focused || forceFocus){
          newCell.focus();
         }


         // set tabIndex=-1 on old focusable cell
         if(oldCell && oldCell != newCell){
          if(dojo.isWebKit){ // see #11064 about webkit bug
           oldCell.setAttribute("tabIndex", "-1");
          }else{
            oldCell.removeAttribute("tabIndex");
          }
         }
    • summary
      If the calendar currently has focus, then focuses specified date,
      changing the currently displayed month/year if necessary.
      If the calendar doesn't have focus, updates currently
      displayed month/year, and sets the cell that will get focus.
  • dijit.Calendar.focus

    • type
      Function
    • source: [view]
         this._setCurrentFocusAttr(this.currentFocus, true);
    • summary
      Focus the calendar by focusing one of the calendar cells
  • dijit.Calendar._onMonthSelect

    • type
      Function
    • parameters:
      • newMonth: (typeof Number)
    • source: [view]
      define("dijit/Calendar", ["dojo", "dijit", "text!dijit/templates/Calendar.html", "dojo/cldr/supplemental", "dojo/date", "dojo/date/locale", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton"], function(dojo, dijit) {


      dojo.declare(
       "dijit.Calendar",
       [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
       {
        // summary:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //
        // description:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //  This widget can't be used in a form because it doesn't serialize the date to an
        //  `` field. For a form element, use dijit.form.DateTextBox instead.
        //
        //  Note that the parser takes all dates attributes passed in the
        //  [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
        //  so that they are serializable and locale-independent.
        //
        // example:
        // | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
        //
        // example:
        // | 



        templateString: dojo.cache("dijit", "templates/Calendar.html"),
        widgetsInTemplate: true,


        // value: Date
        //  The currently selected Date, initially set to invalid date to indicate no selection.
        value: new Date(""),
        // TODO: for 2.0 make this a string (ISO format) rather than a Date


        // datePackage: String
        //  JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
        //  at dojo.date by default.
        datePackage: "dojo.date",


        // dayWidth: String
        //  How to represent the days of the week in the calendar header. See dojo.date.locale
        dayWidth: "narrow",


        // tabIndex: Integer
        //  Order fields are traversed when user hits the tab key
        tabIndex: "0",

        
        // currentFocus: Date
        //  Date object containing the currently focused date, or the date which would be focused
        //  if the calendar itself was focused. Also indicates which year and month to display,
        //  i.e. the current "page" the calendar is on.
        currentFocus: new Date(),


        baseClass:"dijitCalendar",


        // Set node classes for various mouse events, see dijit._CssStateMixin for more details
        cssStateNodes: {
         "decrementMonth": "dijitCalendarArrow",
         "incrementMonth": "dijitCalendarArrow",
         "previousYearLabelNode": "dijitCalendarPreviousYear",
         "nextYearLabelNode": "dijitCalendarNextYear"
        },


        _isValidDate: function(/*Date*/ value){
         // summary:
         //  Runs various tests on the value, checking that it's a valid date, rather
         //  than blank or NaN.
         // tags:
         //  private
         return value && !isNaN(value) && typeof value == "object" &&
          value.toString() != this.constructor.prototype.value.toString();
        },


        setValue: function(/*Date*/ value){
         // summary:
         // Deprecated. Use set('value', ...) instead.
         // tags:
         // deprecated
         dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
         this.set('value', value);
        },


        _getValueAttr: function(){
         // summary:
         //  Support get('value')


         // this.value is set to 1AM, but return midnight, local time for back-compat
         var value = new this.dateClassObj(this.value);
         value.setHours(0, 0, 0, 0);


         // If daylight savings pushes midnight to the previous date, fix the Date
         // object to point at 1am so it will represent the correct day. See #9366
         if(value.getDate() < this.value.getDate()){
          value = this.dateFuncObj.add(value, "hour", 1);
         }
         return value;
        },


        _setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
         // summary:
         //  Support set("value", ...)
         // description:
         //   Set the current date and update the UI. If the date is disabled, the value will
         //  not change, but the display will change to the corresponding month.
         // value:
         //  Either a Date or the number of seconds since 1970.
         // tags:
         // protected
         if(value){
          // convert from Number to Date, or make copy of Date object so that setHours() call below
          // doesn't affect original value
          value = new this.dateClassObj(value);
         }
         if(this._isValidDate(value)){
          if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
           value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)

       
           if(!this.isDisabledDate(value, this.lang)){
            this._set("value", value);

        
            // Set focus cell to the new value. Arguably this should only happen when there isn't a current
            // focus point. This will also repopulate the grid, showing the new selected value (and possibly
            // new month/year).
            this.set("currentFocus", value);

       
            if(priorityChange || typeof priorityChange == "undefined"){
             this.onChange(this.get('value'));
             this.onValueSelected(this.get('value')); // remove in 2.0
            }
           }
          }
         }else{
          // clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
          this._set("value", null);
          this.set("currentFocus", this.currentFocus);
         }
        },


        _setText: function(node, text){
         // summary:
         //  This just sets the content of node to the specified text.
         //  Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
         // tags:
         // private
         while(node.firstChild){
          node.removeChild(node.firstChild);
         }
         node.appendChild(dojo.doc.createTextNode(text));
        },


        _populateGrid: function(){
         // summary:
         // Fills in the calendar grid with each day (1-31)
         // tags:
         // private


         var month = new this.dateClassObj(this.currentFocus);
         month.setDate(1);


         var firstDay = month.getDay(),
          daysInMonth = this.dateFuncObj.getDaysInMonth(month),
          daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
          today = new this.dateClassObj(),
          dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         if(dayOffset > firstDay){ dayOffset -= 7; }


         // Iterate through dates in the calendar and fill in date numbers and style info
         dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
          i += dayOffset;
          var date = new this.dateClassObj(month),
           number, clazz = "dijitCalendar", adj = 0;


          if(i < firstDay){
           number = daysInPreviousMonth - firstDay + i + 1;
           adj = -1;
           clazz += "Previous";
          }else if(i >= (firstDay + daysInMonth)){
           number = i - firstDay - daysInMonth + 1;
           adj = 1;
           clazz += "Next";
          }else{
           number = i - firstDay + 1;
           clazz += "Current";
          }


          if(adj){
           date = this.dateFuncObj.add(date, "month", adj);
          }
          date.setDate(number);


          if(!this.dateFuncObj.compare(date, today, "date")){
           clazz = "dijitCalendarCurrentDate " + clazz;
          }


          if(this._isSelectedDate(date, this.lang)){
           clazz = "dijitCalendarSelectedDate " + clazz;
          }


          if(this.isDisabledDate(date, this.lang)){
           clazz = "dijitCalendarDisabledDate " + clazz;
          }


          var clazz2 = this.getClassForDate(date, this.lang);
          if(clazz2){
           clazz = clazz2 + " " + clazz;
          }


          template.className = clazz + "Month dijitCalendarDateTemplate";
          template.dijitDateValue = date.valueOf();    // original code
          dojo.attr(template, "dijitDateValue", date.valueOf()); // so I can dojo.query() it
          var label = dojo.query(".dijitCalendarDateLabel", template)[0],
           text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
          this._setText(label, text);
         }, this);


         // Repopulate month drop down list based on current year.
         // Need to do this to hide leap months in Hebrew calendar.
         var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
         this.monthDropDownButton.dropDown.set("months", monthNames);


         // Set name of current month and also fill in spacer element with all the month names
         // (invisible) so that the maximum width will affect layout. But not on IE6 because then
         // the center overlaps the right (due to a browser bug).
         this.monthDropDownButton.containerNode.innerHTML =
          (dojo.isIE == 6 ? "" : "
      " + this.monthDropDownButton.dropDown.domNode.innerHTML + "
      ") +
          "
      " + monthNames[month.getMonth()] + "
      ";


         // Fill in localized prev/current/next years
         var y = month.getFullYear() - 1;
         var d = new this.dateClassObj();
         dojo.forEach(["previous", "current", "next"], function(name){
          d.setFullYear(y++);
          this._setText(this[name+"YearLabelNode"],
           this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
         }, this);
        },


        goToToday: function(){
         // summary:
         // Sets calendar's value to today's date
         this.set('value', new this.dateClassObj());
        },


        constructor: function(/*Object*/args){
         var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
         this.dateClassObj = dojo.getObject(dateClass, false);
         this.datePackage = args.datePackage || this.datePackage;
         this.dateFuncObj = dojo.getObject(this.datePackage, false);
         this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
        },


        postMixInProperties: function(){
         // Parser.instantiate sometimes passes in NaN for IE. Use default value in prototype instead.
         // TODO: remove this for 2.0 (thanks to #11511)
         if(isNaN(this.value)){ delete this.value; }


         this.inherited(arguments);
        },


        buildRendering: function(){
         this.inherited(arguments);
         dojo.setSelectable(this.domNode, false);


         var cloneClass = dojo.hitch(this, function(clazz, n){
          var template = dojo.query(clazz, this.domNode)[0];
           for(var i=0; i     template.parentNode.appendChild(template.cloneNode(true));
          }
         });


         // clone the day label and calendar day templates 6 times to make 7 columns
         cloneClass(".dijitCalendarDayLabelTemplate", 6);
         cloneClass(".dijitCalendarDateTemplate", 6);


         // now make 6 week rows
         cloneClass(".dijitCalendarWeekTemplate", 5);


         // insert localized day names in the header
         var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
         var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
          this._setText(label, dayNames[(i + dayOffset) % 7]);
         }, this);


         var dateObj = new this.dateClassObj(this.currentFocus);


         this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
          id: this.id + "_mdd",
          onChange: dojo.hitch(this, "_onMonthSelect")
         });


         this.set('currentFocus', dateObj, false); // draw the grid to the month specified by currentFocus


         // Set up repeating mouse behavior for increment/decrement of months/years
         var _this = this;
         var typematic = function(nodeProp, dateProp, adj){
          _this._connects.push(
           dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
            if(count >= 0){ _this._adjustDisplay(dateProp, adj); }
           }, 0.8, 500)
          );
         };
         typematic("incrementMonth", "month", 1);
         typematic("decrementMonth", "month", -1);
         typematic("nextYearLabelNode", "year", 1);
         typematic("previousYearLabelNode", "year", -1);
        },


        _adjustDisplay: function(/*String*/ part, /*int*/ amount){
         // summary:
         // Moves calendar forwards or backwards by months or years
         // part:
         // "month" or "year"
         // amount:
         // Number of months or years
         // tags:
         // private
         this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
        },


        _setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
         // summary:
         //  If the calendar currently has focus, then focuses specified date,
         //  changing the currently displayed month/year if necessary.
         //  If the calendar doesn't have focus, updates currently
         //  displayed month/year, and sets the cell that will get focus.
         // forceFocus:
         //  If true, will focus() the cell even if calendar itself doesn't have focus


         var oldFocus = this.currentFocus,
          oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : null;


         // round specified value to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
         date = new this.dateClassObj(date);
         date.setHours(1, 0, 0, 0);


         this._set("currentFocus", date);


         // TODO: only re-populate grid when month/year has changed
         this._populateGrid();


         // set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
         var newCell = dojo.query("[dijitDateValue=" + date.valueOf() + "]", this.domNode)[0];
         newCell.setAttribute("tabIndex", this.tabIndex);
         if(this._focused || forceFocus){
          newCell.focus();
         }


         // set tabIndex=-1 on old focusable cell
         if(oldCell && oldCell != newCell){
          if(dojo.isWebKit){ // see #11064 about webkit bug
           oldCell.setAttribute("tabIndex", "-1");
          }else{
            oldCell.removeAttribute("tabIndex");
          }
         }
        },


        focus: function(){
         // summary:
         //  Focus the calendar by focusing one of the calendar cells
         this._setCurrentFocusAttr(this.currentFocus, true);
        },


        _onMonthSelect: function(/*Number*/ newMonth){
         // summary:
         // Handler for when user selects a month from the drop down list
         // tags:
         // protected


         // move to selected month, bounding by the number of days in the month
         // (ex: dec 31 --> jan 28, not jan 31)
         this.currentFocus = this.dateFuncObj.add(this.currentFocus, "month",
          newMonth - this.currentFocus.getMonth());
         this._populateGrid();
    • summary
      Handler for when user selects a month from the drop down list
  • dijit.Calendar._onDayClick

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         dojo.stopEvent(evt);
         for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
         if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
          this.set('value', node.dijitDateValue);
         }
    • summary
      Handler for day clicks, selects the date if appropriate
    • tags:
  • dijit.Calendar._onDayMouseOver

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
      define("dijit/Calendar", ["dojo", "dijit", "text!dijit/templates/Calendar.html", "dojo/cldr/supplemental", "dojo/date", "dojo/date/locale", "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton"], function(dojo, dijit) {


      dojo.declare(
       "dijit.Calendar",
       [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
       {
        // summary:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //
        // description:
        //  A simple GUI for choosing a date in the context of a monthly calendar.
        //  This widget can't be used in a form because it doesn't serialize the date to an
        //  `` field. For a form element, use dijit.form.DateTextBox instead.
        //
        //  Note that the parser takes all dates attributes passed in the
        //  [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
        //  so that they are serializable and locale-independent.
        //
        // example:
        // | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
        //
        // example:
        // | 



        templateString: dojo.cache("dijit", "templates/Calendar.html"),
        widgetsInTemplate: true,


        // value: Date
        //  The currently selected Date, initially set to invalid date to indicate no selection.
        value: new Date(""),
        // TODO: for 2.0 make this a string (ISO format) rather than a Date


        // datePackage: String
        //  JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
        //  at dojo.date by default.
        datePackage: "dojo.date",


        // dayWidth: String
        //  How to represent the days of the week in the calendar header. See dojo.date.locale
        dayWidth: "narrow",


        // tabIndex: Integer
        //  Order fields are traversed when user hits the tab key
        tabIndex: "0",

        
        // currentFocus: Date
        //  Date object containing the currently focused date, or the date which would be focused
        //  if the calendar itself was focused. Also indicates which year and month to display,
        //  i.e. the current "page" the calendar is on.
        currentFocus: new Date(),


        baseClass:"dijitCalendar",


        // Set node classes for various mouse events, see dijit._CssStateMixin for more details
        cssStateNodes: {
         "decrementMonth": "dijitCalendarArrow",
         "incrementMonth": "dijitCalendarArrow",
         "previousYearLabelNode": "dijitCalendarPreviousYear",
         "nextYearLabelNode": "dijitCalendarNextYear"
        },


        _isValidDate: function(/*Date*/ value){
         // summary:
         //  Runs various tests on the value, checking that it's a valid date, rather
         //  than blank or NaN.
         // tags:
         //  private
         return value && !isNaN(value) && typeof value == "object" &&
          value.toString() != this.constructor.prototype.value.toString();
        },


        setValue: function(/*Date*/ value){
         // summary:
         // Deprecated. Use set('value', ...) instead.
         // tags:
         // deprecated
         dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
         this.set('value', value);
        },


        _getValueAttr: function(){
         // summary:
         //  Support get('value')


         // this.value is set to 1AM, but return midnight, local time for back-compat
         var value = new this.dateClassObj(this.value);
         value.setHours(0, 0, 0, 0);


         // If daylight savings pushes midnight to the previous date, fix the Date
         // object to point at 1am so it will represent the correct day. See #9366
         if(value.getDate() < this.value.getDate()){
          value = this.dateFuncObj.add(value, "hour", 1);
         }
         return value;
        },


        _setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
         // summary:
         //  Support set("value", ...)
         // description:
         //   Set the current date and update the UI. If the date is disabled, the value will
         //  not change, but the display will change to the corresponding month.
         // value:
         //  Either a Date or the number of seconds since 1970.
         // tags:
         // protected
         if(value){
          // convert from Number to Date, or make copy of Date object so that setHours() call below
          // doesn't affect original value
          value = new this.dateClassObj(value);
         }
         if(this._isValidDate(value)){
          if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
           value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)

       
           if(!this.isDisabledDate(value, this.lang)){
            this._set("value", value);

        
            // Set focus cell to the new value. Arguably this should only happen when there isn't a current
            // focus point. This will also repopulate the grid, showing the new selected value (and possibly
            // new month/year).
            this.set("currentFocus", value);

       
            if(priorityChange || typeof priorityChange == "undefined"){
             this.onChange(this.get('value'));
             this.onValueSelected(this.get('value')); // remove in 2.0
            }
           }
          }
         }else{
          // clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
          this._set("value", null);
          this.set("currentFocus", this.currentFocus);
         }
        },


        _setText: function(node, text){
         // summary:
         //  This just sets the content of node to the specified text.
         //  Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
         // tags:
         // private
         while(node.firstChild){
          node.removeChild(node.firstChild);
         }
         node.appendChild(dojo.doc.createTextNode(text));
        },


        _populateGrid: function(){
         // summary:
         // Fills in the calendar grid with each day (1-31)
         // tags:
         // private


         var month = new this.dateClassObj(this.currentFocus);
         month.setDate(1);


         var firstDay = month.getDay(),
          daysInMonth = this.dateFuncObj.getDaysInMonth(month),
          daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
          today = new this.dateClassObj(),
          dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         if(dayOffset > firstDay){ dayOffset -= 7; }


         // Iterate through dates in the calendar and fill in date numbers and style info
         dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
          i += dayOffset;
          var date = new this.dateClassObj(month),
           number, clazz = "dijitCalendar", adj = 0;


          if(i < firstDay){
           number = daysInPreviousMonth - firstDay + i + 1;
           adj = -1;
           clazz += "Previous";
          }else if(i >= (firstDay + daysInMonth)){
           number = i - firstDay - daysInMonth + 1;
           adj = 1;
           clazz += "Next";
          }else{
           number = i - firstDay + 1;
           clazz += "Current";
          }


          if(adj){
           date = this.dateFuncObj.add(date, "month", adj);
          }
          date.setDate(number);


          if(!this.dateFuncObj.compare(date, today, "date")){
           clazz = "dijitCalendarCurrentDate " + clazz;
          }


          if(this._isSelectedDate(date, this.lang)){
           clazz = "dijitCalendarSelectedDate " + clazz;
          }


          if(this.isDisabledDate(date, this.lang)){
           clazz = "dijitCalendarDisabledDate " + clazz;
          }


          var clazz2 = this.getClassForDate(date, this.lang);
          if(clazz2){
           clazz = clazz2 + " " + clazz;
          }


          template.className = clazz + "Month dijitCalendarDateTemplate";
          template.dijitDateValue = date.valueOf();    // original code
          dojo.attr(template, "dijitDateValue", date.valueOf()); // so I can dojo.query() it
          var label = dojo.query(".dijitCalendarDateLabel", template)[0],
           text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
          this._setText(label, text);
         }, this);


         // Repopulate month drop down list based on current year.
         // Need to do this to hide leap months in Hebrew calendar.
         var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
         this.monthDropDownButton.dropDown.set("months", monthNames);


         // Set name of current month and also fill in spacer element with all the month names
         // (invisible) so that the maximum width will affect layout. But not on IE6 because then
         // the center overlaps the right (due to a browser bug).
         this.monthDropDownButton.containerNode.innerHTML =
          (dojo.isIE == 6 ? "" : "
      " + this.monthDropDownButton.dropDown.domNode.innerHTML + "
      ") +
          "
      " + monthNames[month.getMonth()] + "
      ";


         // Fill in localized prev/current/next years
         var y = month.getFullYear() - 1;
         var d = new this.dateClassObj();
         dojo.forEach(["previous", "current", "next"], function(name){
          d.setFullYear(y++);
          this._setText(this[name+"YearLabelNode"],
           this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
         }, this);
        },


        goToToday: function(){
         // summary:
         // Sets calendar's value to today's date
         this.set('value', new this.dateClassObj());
        },


        constructor: function(/*Object*/args){
         var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
         this.dateClassObj = dojo.getObject(dateClass, false);
         this.datePackage = args.datePackage || this.datePackage;
         this.dateFuncObj = dojo.getObject(this.datePackage, false);
         this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
        },


        postMixInProperties: function(){
         // Parser.instantiate sometimes passes in NaN for IE. Use default value in prototype instead.
         // TODO: remove this for 2.0 (thanks to #11511)
         if(isNaN(this.value)){ delete this.value; }


         this.inherited(arguments);
        },


        buildRendering: function(){
         this.inherited(arguments);
         dojo.setSelectable(this.domNode, false);


         var cloneClass = dojo.hitch(this, function(clazz, n){
          var template = dojo.query(clazz, this.domNode)[0];
           for(var i=0; i     template.parentNode.appendChild(template.cloneNode(true));
          }
         });


         // clone the day label and calendar day templates 6 times to make 7 columns
         cloneClass(".dijitCalendarDayLabelTemplate", 6);
         cloneClass(".dijitCalendarDateTemplate", 6);


         // now make 6 week rows
         cloneClass(".dijitCalendarWeekTemplate", 5);


         // insert localized day names in the header
         var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
         var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
         dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
          this._setText(label, dayNames[(i + dayOffset) % 7]);
         }, this);


         var dateObj = new this.dateClassObj(this.currentFocus);


         this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
          id: this.id + "_mdd",
          onChange: dojo.hitch(this, "_onMonthSelect")
         });


         this.set('currentFocus', dateObj, false); // draw the grid to the month specified by currentFocus


         // Set up repeating mouse behavior for increment/decrement of months/years
         var _this = this;
         var typematic = function(nodeProp, dateProp, adj){
          _this._connects.push(
           dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
            if(count >= 0){ _this._adjustDisplay(dateProp, adj); }
           }, 0.8, 500)
          );
         };
         typematic("incrementMonth", "month", 1);
         typematic("decrementMonth", "month", -1);
         typematic("nextYearLabelNode", "year", 1);
         typematic("previousYearLabelNode", "year", -1);
        },


        _adjustDisplay: function(/*String*/ part, /*int*/ amount){
         // summary:
         // Moves calendar forwards or backwards by months or years
         // part:
         // "month" or "year"
         // amount:
         // Number of months or years
         // tags:
         // private
         this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
        },


        _setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
         // summary:
         //  If the calendar currently has focus, then focuses specified date,
         //  changing the currently displayed month/year if necessary.
         //  If the calendar doesn't have focus, updates currently
         //  displayed month/year, and sets the cell that will get focus.
         // forceFocus:
         //  If true, will focus() the cell even if calendar itself doesn't have focus


         var oldFocus = this.currentFocus,
          oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : null;


         // round specified value to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
         date = new this.dateClassObj(date);
         date.setHours(1, 0, 0, 0);


         this._set("currentFocus", date);


         // TODO: only re-populate grid when month/year has changed
         this._populateGrid();


         // set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
         var newCell = dojo.query("[dijitDateValue=" + date.valueOf() + "]", this.domNode)[0];
         newCell.setAttribute("tabIndex", this.tabIndex);
         if(this._focused || forceFocus){
          newCell.focus();
         }


         // set tabIndex=-1 on old focusable cell
         if(oldCell && oldCell != newCell){
          if(dojo.isWebKit){ // see #11064 about webkit bug
           oldCell.setAttribute("tabIndex", "-1");
          }else{
            oldCell.removeAttribute("tabIndex");
          }
         }
        },


        focus: function(){
         // summary:
         //  Focus the calendar by focusing one of the calendar cells
         this._setCurrentFocusAttr(this.currentFocus, true);
        },


        _onMonthSelect: function(/*Number*/ newMonth){
         // summary:
         // Handler for when user selects a month from the drop down list
         // tags:
         // protected


         // move to selected month, bounding by the number of days in the month
         // (ex: dec 31 --> jan 28, not jan 31)
         this.currentFocus = this.dateFuncObj.add(this.currentFocus, "month",
          newMonth - this.currentFocus.getMonth());
         this._populateGrid();
        },


        _onDayClick: function(/*Event*/ evt){
         // summary:
         // Handler for day clicks, selects the date if appropriate
         // tags:
         // protected
         dojo.stopEvent(evt);
         for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
         if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
          this.set('value', node.dijitDateValue);
         }
        },


        _onDayMouseOver: function(/*Event*/ evt){
         // summary:
         // Handler for mouse over events on days, sets hovered style
         // tags:
         // protected


         // event can occur on or the inside the td,
         // set node to the .
         var node =
          dojo.hasClass(evt.target, "dijitCalendarDateLabel") ?
          evt.target.parentNode :
          evt.target;


         if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){
          dojo.addClass(node, "dijitCalendarHoveredDate");
          this._currentNode = node;
         }
    • summary
      Handler for mouse over events on days, sets hovered style
  • dijit.Calendar._onDayMouseOut

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         if(!this._currentNode){ return; }

         
         // if mouse out occurs moving from to inside , ignore it
         if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
         var cls = "dijitCalendarHoveredDate";
         if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) {
          cls += " dijitCalendarActiveDate";
         }
         dojo.removeClass(this._currentNode, cls);
         this._currentNode = null;
    • summary
      Handler for mouse out events on days, clears hovered style
    • tags:
  • dijit.Calendar._onDayMouseDown

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         var node = evt.target.parentNode;
         if(node && node.dijitDateValue){
          dojo.addClass(node, "dijitCalendarActiveDate");
          this._currentNode = node;
         }
    • summary
  • dijit.Calendar._onDayMouseUp

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         var node = evt.target.parentNode;
         if(node && node.dijitDateValue){
          dojo.removeClass(node, "dijitCalendarActiveDate");
         }
    • summary
  • dijit.Calendar.handleKey

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         var dk = dojo.keys,
          increment = -1,
          interval,
          newValue = this.currentFocus;
         switch(evt.keyCode){
          case dk.RIGHT_ARROW:
           increment = 1;
           //fallthrough...
          case dk.LEFT_ARROW:
           interval = "day";
           if(!this.isLeftToRight()){ increment *= -1; }
           break;
          case dk.DOWN_ARROW:
           increment = 1;
           //fallthrough...
          case dk.UP_ARROW:
           interval = "week";
           break;
          case dk.PAGE_DOWN:
           increment = 1;
           //fallthrough...
          case dk.PAGE_UP:
           interval = evt.ctrlKey || evt.altKey ? "year" : "month";
           break;
          case dk.END:
           // go to the next month
           newValue = this.dateFuncObj.add(newValue, "month", 1);
           // subtract a day from the result when we're done
           interval = "day";
           //fallthrough...
          case dk.HOME:
           newValue = new this.dateClassObj(newValue);
           newValue.setDate(1);
           break;
          case dk.ENTER:
          case dk.SPACE:
           this.set("value", this.currentFocus);
           break;
          default:
           return true;
         }


         if(interval){
          newValue = this.dateFuncObj.add(newValue, interval, increment);
         }


         this._setCurrentFocusAttr(newValue);


         return false;
    • summary
      Provides keyboard navigation of calendar.
    • description
      Called from _onKeyPress() to handle keypress on a stand alone Calendar,
      and also from `dijit.form._DateTimeTextBox` to pass a keypress event
      from the `dijit.form.DateTextBox` to be handled in this widget
    • return_summary
      False if the key was recognized as a navigation key,
      to indicate that the event was handled by Calendar and shouldn't be propogated
    • tags:
  • dijit.Calendar._onKeyPress

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
         if(!this.handleKey(evt)){
          dojo.stopEvent(evt);
         }
    • summary
      For handling keypress events on a stand alone calendar
  • dijit.Calendar.onValueSelected

    • type
      Function
    • parameters:
      • date: (typeof Date)
    • source: [view]
         // summary:
         //  Notification that a date cell was selected. It may be the same as the previous value.
         // description:
         // Formerly used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
         // to get notification when the user has clicked a date. Now onExecute() (above) is used.
         // tags:
         // protected
    • summary
      Notification that a date cell was selected.  It may be the same as the previous value.
    • description
      Formerly used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
      to get notification when the user has clicked a date.  Now onExecute() (above) is used.
    • tags:
  • dijit.Calendar.onChange

    • type
      Function
    • parameters:
      • date: (typeof Date)
    • source: [view]
         // summary:
         //  Called only when the selected date has changed
    • summary
      Called only when the selected date has changed
  • dijit.Calendar._isSelectedDate

    • type
      Function
    • parameters:
      • dateObject: (typeof Date)
      • locale: (typeof String)
    • source: [view]
         return this._isValidDate(this.value) && !this.dateFuncObj.compare(dateObject, this.value, "date")
    • summary
      Extension point so developers can subclass Calendar to
      support multiple (concurrently) selected dates
    • tags:
  • dijit.Calendar.isDisabledDate

    • type
      Function
    • parameters:
      • dateObject: (typeof Date)
      • locale: (typeof String)
    • source: [view]
         return false; // Boolean
    • summary
      May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
    • tags:
    • returns
      Boolean
  • dijit.Calendar.getClassForDate

    • type
      Function
    • parameters:
      • dateObject: (typeof Date)
      • locale: (typeof String)
    • source: [view]
         return ""; // String
    • summary
      May be overridden to return CSS classes to associate with the date entry for the given dateObject,
      for example to indicate a holiday in specified locale.
    • tags:
    • returns
      String
  • dijit.Calendar.cssStateNodes.decrementMonth

    • summary
  • dijit.Calendar.cssStateNodes.incrementMonth

    • summary
  • dijit.Calendar.cssStateNodes.previousYearLabelNode

    • summary
  • dijit.Calendar.cssStateNodes.nextYearLabelNode

    • summary
  • dijit.Calendar.monthDropDownButton.containerNode.innerHTML

    • summary
  • dijit.Calendar.monthDropDownButton.dropDown

    • summary
  • dijit.Calendar._currentNode

    • summary
  • dijit.Calendar.dateClassObj

    • summary
  • dijit.Calendar.dateFuncObj

    • summary
  • dijit.Calendar.dateLocaleModule

    • summary
  • dijit.Calendar._MonthDropDown

    • type
      Function
    • chains:
      • dijit._Widget: (prototype)
      • dijit._Widget: (call)
      • dijit._Templated: (call)
    • mixins:
      • dijit._Templated.prototype: (prototype)
    • summary
      The month drop down
  • dijit.Calendar._MonthDropDown.months

    • type
      String[
    • summary
      List of names of months, possibly w/some undefined entries for Hebrew leap months
      (ex: [&quot;January&quot;, &quot;February&quot;, undefined, &quot;April&quot;, ...])
  • dijit.Calendar._MonthDropDown.templateString

    • summary
  • dijit.Calendar._MonthDropDown._setMonthsAttr

    • type
      Function
    • parameters:
      • months: (typeof String[])
    • source: [view]
        this.domNode.innerHTML = dojo.map(months, function(month, idx){
          return month ? "
      " + month + "
      " : "";
         }).join("");
    • summary
  • dijit.Calendar._MonthDropDown._onClick

    • type
      Function
    • parameters:
      • evt: (typeof Event)
    • source: [view]
        this.onChange(dojo.attr(evt.target, "month"));
    • summary
  • dijit.Calendar._MonthDropDown.onChange

    • type
      Function
    • parameters:
      • month: (typeof Number)
    • source: [view]
        // summary:
        //  Callback when month is selected from drop down
    • summary
      Callback when month is selected from drop down
  • dijit.Calendar._MonthDropDown._onMenuHover

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
        dojo.toggleClass(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
    • summary
  • dijit.Calendar._MonthDropDown.domNode.innerHTML

    • summary
  • dijit

    • type
      Object
    • summary