]>
Commit | Line | Data |
---|---|---|
1354d172 AD |
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/_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 | }); |