Calendar.js.uncompressed.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. define("dijit/Calendar", [
  2. "dojo/_base/array", // array.map
  3. "dojo/date",
  4. "dojo/date/locale",
  5. "dojo/_base/declare", // declare
  6. "dojo/dom-attr", // domAttr.get
  7. "dojo/dom-class", // domClass.add domClass.contains domClass.remove domClass.toggle
  8. "dojo/_base/event", // event.stop
  9. "dojo/_base/kernel", // kernel.deprecated
  10. "dojo/keys", // keys
  11. "dojo/_base/lang", // lang.hitch
  12. "dojo/sniff", // has("ie")
  13. "./CalendarLite",
  14. "./_Widget",
  15. "./_CssStateMixin",
  16. "./_TemplatedMixin",
  17. "./form/DropDownButton"
  18. ], function(array, date, local, declare, domAttr, domClass, event, kernel, keys, lang, has,
  19. CalendarLite, _Widget, _CssStateMixin, _TemplatedMixin, DropDownButton){
  20. // module:
  21. // dijit/Calendar
  22. var Calendar = declare("dijit.Calendar",
  23. [CalendarLite, _Widget, _CssStateMixin], // _Widget for deprecated methods like setAttribute()
  24. {
  25. // summary:
  26. // A simple GUI for choosing a date in the context of a monthly calendar.
  27. //
  28. // description:
  29. // See CalendarLite for general description. Calendar extends CalendarLite, adding:
  30. //
  31. // - month drop down list
  32. // - keyboard navigation
  33. // - CSS classes for hover/mousepress on date, month, and year nodes
  34. // - support of deprecated methods (will be removed in 2.0)
  35. // Set node classes for various mouse events, see dijit._CssStateMixin for more details
  36. cssStateNodes: {
  37. "decrementMonth": "dijitCalendarArrow",
  38. "incrementMonth": "dijitCalendarArrow",
  39. "previousYearLabelNode": "dijitCalendarPreviousYear",
  40. "nextYearLabelNode": "dijitCalendarNextYear"
  41. },
  42. setValue: function(/*Date*/ value){
  43. // summary:
  44. // Deprecated. Use set('value', ...) instead.
  45. // tags:
  46. // deprecated
  47. kernel.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
  48. this.set('value', value);
  49. },
  50. _createMonthWidget: function(){
  51. // summary:
  52. // Creates the drop down button that displays the current month and lets user pick a new one
  53. return new Calendar._MonthDropDownButton({
  54. id: this.id + "_mddb",
  55. tabIndex: -1,
  56. onMonthSelect: lang.hitch(this, "_onMonthSelect"),
  57. lang: this.lang,
  58. dateLocaleModule: this.dateLocaleModule
  59. }, this.monthNode);
  60. },
  61. postCreate: function(){
  62. this.inherited(arguments);
  63. // Events specific to Calendar, not used in CalendarLite
  64. this.connect(this.domNode, "onkeydown", "_onKeyDown");
  65. this.connect(this.dateRowsNode, "onmouseover", "_onDayMouseOver");
  66. this.connect(this.dateRowsNode, "onmouseout", "_onDayMouseOut");
  67. this.connect(this.dateRowsNode, "onmousedown", "_onDayMouseDown");
  68. this.connect(this.dateRowsNode, "onmouseup", "_onDayMouseUp");
  69. },
  70. _onMonthSelect: function(/*Number*/ newMonth){
  71. // summary:
  72. // Handler for when user selects a month from the drop down list
  73. // tags:
  74. // protected
  75. // move to selected month, bounding by the number of days in the month
  76. // (ex: jan 31 --> feb 28, not feb 31)
  77. var date = new this.dateClassObj(this.currentFocus);
  78. date.setDate(1);
  79. date.setMonth(newMonth);
  80. var daysInMonth = this.dateModule.getDaysInMonth(date);
  81. var currentDate = this.currentFocus.getDate();
  82. date.setDate(Math.min(currentDate, daysInMonth));
  83. this._setCurrentFocusAttr(date);
  84. },
  85. _onDayMouseOver: function(/*Event*/ evt){
  86. // summary:
  87. // Handler for mouse over events on days, sets hovered style
  88. // tags:
  89. // protected
  90. // event can occur on <td> or the <span> inside the td,
  91. // set node to the <td>.
  92. var node =
  93. domClass.contains(evt.target, "dijitCalendarDateLabel") ?
  94. evt.target.parentNode :
  95. evt.target;
  96. if(node && (
  97. (node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate"))
  98. || node == this.previousYearLabelNode || node == this.nextYearLabelNode
  99. )){
  100. domClass.add(node, "dijitCalendarHoveredDate");
  101. this._currentNode = node;
  102. }
  103. },
  104. _onDayMouseOut: function(/*Event*/ evt){
  105. // summary:
  106. // Handler for mouse out events on days, clears hovered style
  107. // tags:
  108. // protected
  109. if(!this._currentNode){ return; }
  110. // if mouse out occurs moving from <td> to <span> inside <td>, ignore it
  111. if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
  112. var cls = "dijitCalendarHoveredDate";
  113. if(domClass.contains(this._currentNode, "dijitCalendarActiveDate")){
  114. cls += " dijitCalendarActiveDate";
  115. }
  116. domClass.remove(this._currentNode, cls);
  117. this._currentNode = null;
  118. },
  119. _onDayMouseDown: function(/*Event*/ evt){
  120. var node = evt.target.parentNode;
  121. if(node && node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate")){
  122. domClass.add(node, "dijitCalendarActiveDate");
  123. this._currentNode = node;
  124. }
  125. },
  126. _onDayMouseUp: function(/*Event*/ evt){
  127. var node = evt.target.parentNode;
  128. if(node && node.dijitDateValue){
  129. domClass.remove(node, "dijitCalendarActiveDate");
  130. }
  131. },
  132. handleKey: function(/*Event*/ evt){
  133. // summary:
  134. // Provides keyboard navigation of calendar.
  135. // description:
  136. // Called from _onKeyDown() to handle keypress on a stand alone Calendar,
  137. // and also from `dijit/form/_DateTimeTextBox` to pass a keydown event
  138. // from the `dijit/form/DateTextBox` to be handled in this widget
  139. // returns:
  140. // False if the key was recognized as a navigation key,
  141. // to indicate that the event was handled by Calendar and shouldn't be propagated
  142. // tags:
  143. // protected
  144. var increment = -1,
  145. interval,
  146. newValue = this.currentFocus;
  147. switch(evt.keyCode){
  148. case keys.RIGHT_ARROW:
  149. increment = 1;
  150. //fallthrough...
  151. case keys.LEFT_ARROW:
  152. interval = "day";
  153. if(!this.isLeftToRight()){ increment *= -1; }
  154. break;
  155. case keys.DOWN_ARROW:
  156. increment = 1;
  157. //fallthrough...
  158. case keys.UP_ARROW:
  159. interval = "week";
  160. break;
  161. case keys.PAGE_DOWN:
  162. increment = 1;
  163. //fallthrough...
  164. case keys.PAGE_UP:
  165. interval = evt.ctrlKey || evt.altKey ? "year" : "month";
  166. break;
  167. case keys.END:
  168. // go to the next month
  169. newValue = this.dateModule.add(newValue, "month", 1);
  170. // subtract a day from the result when we're done
  171. interval = "day";
  172. //fallthrough...
  173. case keys.HOME:
  174. newValue = new this.dateClassObj(newValue);
  175. newValue.setDate(1);
  176. break;
  177. case keys.ENTER:
  178. case keys.SPACE:
  179. this.set("value", this.currentFocus);
  180. break;
  181. default:
  182. return true;
  183. }
  184. if(interval){
  185. newValue = this.dateModule.add(newValue, interval, increment);
  186. }
  187. this._setCurrentFocusAttr(newValue);
  188. return false;
  189. },
  190. _onKeyDown: function(/*Event*/ evt){
  191. // summary:
  192. // For handling keypress events on a stand alone calendar
  193. if(!this.handleKey(evt)){
  194. event.stop(evt);
  195. }
  196. },
  197. onValueSelected: function(/*Date*/ /*===== date =====*/){
  198. // summary:
  199. // Deprecated. Notification that a date cell was selected. It may be the same as the previous value.
  200. // description:
  201. // Formerly used by `dijit/form/_DateTimeTextBox` (and thus `dijit/form/DateTextBox`)
  202. // to get notification when the user has clicked a date. Now onExecute() (above) is used.
  203. // tags:
  204. // protected
  205. },
  206. onChange: function(value){
  207. this.onValueSelected(value); // remove in 2.0
  208. },
  209. getClassForDate: function(/*===== dateObject, locale =====*/){
  210. // summary:
  211. // May be overridden to return CSS classes to associate with the date entry for the given dateObject,
  212. // for example to indicate a holiday in specified locale.
  213. // dateObject: Date
  214. // locale: String?
  215. // tags:
  216. // extension
  217. /*=====
  218. return ""; // String
  219. =====*/
  220. }
  221. });
  222. Calendar._MonthDropDownButton = declare("dijit.Calendar._MonthDropDownButton", DropDownButton, {
  223. // summary:
  224. // DropDownButton for the current month. Displays name of current month
  225. // and a list of month names in the drop down
  226. onMonthSelect: function(){ },
  227. postCreate: function(){
  228. this.inherited(arguments);
  229. this.dropDown = new Calendar._MonthDropDown({
  230. id: this.id + "_mdd", //do not change this id because it is referenced in the template
  231. onChange: this.onMonthSelect
  232. });
  233. },
  234. _setMonthAttr: function(month){
  235. // summary:
  236. // Set the current month to display as a label
  237. var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
  238. this.dropDown.set("months", monthNames);
  239. // Set name of current month and also fill in spacer element with all the month names
  240. // (invisible) so that the maximum width will affect layout. But not on IE6 because then
  241. // the center <TH> overlaps the right <TH> (due to a browser bug).
  242. this.containerNode.innerHTML =
  243. (has("ie") == 6 ? "" : "<div class='dijitSpacer'>" + this.dropDown.domNode.innerHTML + "</div>") +
  244. "<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" + monthNames[month.getMonth()] + "</div>";
  245. }
  246. });
  247. Calendar._MonthDropDown = declare("dijit.Calendar._MonthDropDown", [_Widget, _TemplatedMixin], {
  248. // summary:
  249. // The list-of-months drop down from the MonthDropDownButton
  250. // months: String[]
  251. // List of names of months, possibly w/some undefined entries for Hebrew leap months
  252. // (ex: ["January", "February", undefined, "April", ...])
  253. months: [],
  254. templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
  255. "data-dojo-attach-event='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
  256. _setMonthsAttr: function(/*String[]*/ months){
  257. this.domNode.innerHTML = array.map(months, function(month, idx){
  258. return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
  259. }).join("");
  260. },
  261. _onClick: function(/*Event*/ evt){
  262. this.onChange(domAttr.get(evt.target, "month"));
  263. },
  264. onChange: function(/*Number*/ /*===== month =====*/){
  265. // summary:
  266. // Callback when month is selected from drop down
  267. },
  268. _onMenuHover: function(evt){
  269. domClass.toggle(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
  270. }
  271. });
  272. return Calendar;
  273. });