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