]> git.wh0rd.org - tt-rss.git/blame - lib/dijit/Calendar.js
upgrade Dojo to 1.6.1
[tt-rss.git] / lib / dijit / Calendar.js
CommitLineData
2f01fe57 1/*
81bea17a 2 Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
2f01fe57
AD
3 Available via Academic Free License >= 2.1 OR the modified BSD license.
4 see: http://dojotoolkit.org/license for details
5*/
6
7
81bea17a
AD
8if(!dojo._hasResource["dijit.Calendar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
9dojo._hasResource["dijit.Calendar"] = true;
2f01fe57
AD
10dojo.provide("dijit.Calendar");
11dojo.require("dojo.cldr.supplemental");
12dojo.require("dojo.date");
13dojo.require("dojo.date.locale");
14dojo.require("dijit._Widget");
15dojo.require("dijit._Templated");
16dojo.require("dijit._CssStateMixin");
81bea17a
AD
17dojo.require("dijit.form.DropDownButton");
18
19
20dojo.declare(
21 "dijit.Calendar",
22 [dijit._Widget, dijit._Templated, dijit._CssStateMixin],
23 {
24 // summary:
25 // A simple GUI for choosing a date in the context of a monthly calendar.
26 //
27 // description:
28 // A simple GUI for choosing a date in the context of a monthly calendar.
29 // This widget can't be used in a form because it doesn't serialize the date to an
30 // `<input>` field. For a form element, use dijit.form.DateTextBox instead.
31 //
32 // Note that the parser takes all dates attributes passed in the
33 // [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
34 // so that they are serializable and locale-independent.
35 //
36 // example:
37 // | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
38 //
39 // example:
40 // | <div dojoType="dijit.Calendar"></div>
41
42 templateString: dojo.cache("dijit", "templates/Calendar.html", "<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\" role=\"grid\" dojoAttachEvent=\"onkeypress: _onKeyPress\" aria-labelledby=\"${id}_year\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset dijitCalendarArrow' dojoAttachPoint=\"decrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarDecrease\" role=\"presentation\"/>\n\t\t\t\t<span dojoAttachPoint=\"decreaseArrowNode\" class=\"dijitA11ySideArrow\">-</span>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' colspan=\"5\">\n\t\t\t\t<div dojoType=\"dijit.form.DropDownButton\" dojoAttachPoint=\"monthDropDownButton\"\n\t\t\t\t\tid=\"${id}_mddb\" tabIndex=\"-1\">\n\t\t\t\t</div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset dijitCalendarArrow' dojoAttachPoint=\"incrementMonth\">\n\t\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitCalendarIncrementControl dijitCalendarIncrease\" role=\"presentation\"/>\n\t\t\t\t<span dojoAttachPoint=\"increaseArrowNode\" class=\"dijitA11ySideArrow\">+</span>\n\t\t\t</th>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<th class=\"dijitReset dijitCalendarDayLabelTemplate\" role=\"columnheader\"><span class=\"dijitCalendarDayLabel\"></span></th>\n\t\t</tr>\n\t</thead>\n\t<tbody dojoAttachEvent=\"onclick: _onDayClick, onmouseover: _onDayMouseOver, onmouseout: _onDayMouseOut, onmousedown: _onDayMouseDown, onmouseup: _onDayMouseUp\" class=\"dijitReset dijitCalendarBodyContainer\">\n\t\t<tr class=\"dijitReset dijitCalendarWeekTemplate\" role=\"row\">\n\t\t\t<td class=\"dijitReset dijitCalendarDateTemplate\" role=\"gridcell\"><span class=\"dijitCalendarDateLabel\"></span></td>\n\t\t</tr>\n\t</tbody>\n\t<tfoot class=\"dijitReset dijitCalendarYearContainer\">\n\t\t<tr>\n\t\t\t<td class='dijitReset' valign=\"top\" colspan=\"7\">\n\t\t\t\t<h3 class=\"dijitCalendarYearLabel\">\n\t\t\t\t\t<span dojoAttachPoint=\"previousYearLabelNode\" class=\"dijitInline dijitCalendarPreviousYear\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"currentYearLabelNode\" class=\"dijitInline dijitCalendarSelectedYear\" id=\"${id}_year\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"nextYearLabelNode\" class=\"dijitInline dijitCalendarNextYear\"></span>\n\t\t\t\t</h3>\n\t\t\t</td>\n\t\t</tr>\n\t</tfoot>\n</table>\n"),
43 widgetsInTemplate: true,
44
45 // value: Date
46 // The currently selected Date, initially set to invalid date to indicate no selection.
47 value: new Date(""),
48 // TODO: for 2.0 make this a string (ISO format) rather than a Date
49
50 // datePackage: String
51 // JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
52 // at dojo.date by default.
53 datePackage: "dojo.date",
54
55 // dayWidth: String
56 // How to represent the days of the week in the calendar header. See dojo.date.locale
57 dayWidth: "narrow",
58
59 // tabIndex: Integer
60 // Order fields are traversed when user hits the tab key
61 tabIndex: "0",
62
63 // currentFocus: Date
64 // Date object containing the currently focused date, or the date which would be focused
65 // if the calendar itself was focused. Also indicates which year and month to display,
66 // i.e. the current "page" the calendar is on.
67 currentFocus: new Date(),
68
69 baseClass:"dijitCalendar",
70
71 // Set node classes for various mouse events, see dijit._CssStateMixin for more details
72 cssStateNodes: {
73 "decrementMonth": "dijitCalendarArrow",
74 "incrementMonth": "dijitCalendarArrow",
75 "previousYearLabelNode": "dijitCalendarPreviousYear",
76 "nextYearLabelNode": "dijitCalendarNextYear"
77 },
78
79 _isValidDate: function(/*Date*/ value){
80 // summary:
81 // Runs various tests on the value, checking that it's a valid date, rather
82 // than blank or NaN.
83 // tags:
84 // private
85 return value && !isNaN(value) && typeof value == "object" &&
86 value.toString() != this.constructor.prototype.value.toString();
87 },
88
89 setValue: function(/*Date*/ value){
90 // summary:
91 // Deprecated. Use set('value', ...) instead.
92 // tags:
93 // deprecated
94 dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0");
95 this.set('value', value);
96 },
97
98 _getValueAttr: function(){
99 // summary:
100 // Support get('value')
101
102 // this.value is set to 1AM, but return midnight, local time for back-compat
103 var value = new this.dateClassObj(this.value);
104 value.setHours(0, 0, 0, 0);
105
106 // If daylight savings pushes midnight to the previous date, fix the Date
107 // object to point at 1am so it will represent the correct day. See #9366
108 if(value.getDate() < this.value.getDate()){
109 value = this.dateFuncObj.add(value, "hour", 1);
110 }
111 return value;
112 },
113
114 _setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
115 // summary:
116 // Support set("value", ...)
117 // description:
118 // Set the current date and update the UI. If the date is disabled, the value will
119 // not change, but the display will change to the corresponding month.
120 // value:
121 // Either a Date or the number of seconds since 1970.
122 // tags:
123 // protected
124 if(value){
125 // convert from Number to Date, or make copy of Date object so that setHours() call below
126 // doesn't affect original value
127 value = new this.dateClassObj(value);
128 }
129 if(this._isValidDate(value)){
130 if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
131 value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
132
133 if(!this.isDisabledDate(value, this.lang)){
134 this._set("value", value);
135
136 // Set focus cell to the new value. Arguably this should only happen when there isn't a current
137 // focus point. This will also repopulate the grid, showing the new selected value (and possibly
138 // new month/year).
139 this.set("currentFocus", value);
140
141 if(priorityChange || typeof priorityChange == "undefined"){
142 this.onChange(this.get('value'));
143 this.onValueSelected(this.get('value')); // remove in 2.0
144 }
145 }
146 }
147 }else{
148 // clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
149 this._set("value", null);
150 this.set("currentFocus", this.currentFocus);
151 }
152 },
153
154 _setText: function(node, text){
155 // summary:
156 // This just sets the content of node to the specified text.
157 // Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
158 // tags:
159 // private
160 while(node.firstChild){
161 node.removeChild(node.firstChild);
162 }
163 node.appendChild(dojo.doc.createTextNode(text));
164 },
165
166 _populateGrid: function(){
167 // summary:
168 // Fills in the calendar grid with each day (1-31)
169 // tags:
170 // private
171
172 var month = new this.dateClassObj(this.currentFocus);
173 month.setDate(1);
174
175 var firstDay = month.getDay(),
176 daysInMonth = this.dateFuncObj.getDaysInMonth(month),
177 daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
178 today = new this.dateClassObj(),
179 dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
180 if(dayOffset > firstDay){ dayOffset -= 7; }
181
182 // Iterate through dates in the calendar and fill in date numbers and style info
183 dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
184 i += dayOffset;
185 var date = new this.dateClassObj(month),
186 number, clazz = "dijitCalendar", adj = 0;
187
188 if(i < firstDay){
189 number = daysInPreviousMonth - firstDay + i + 1;
190 adj = -1;
191 clazz += "Previous";
192 }else if(i >= (firstDay + daysInMonth)){
193 number = i - firstDay - daysInMonth + 1;
194 adj = 1;
195 clazz += "Next";
196 }else{
197 number = i - firstDay + 1;
198 clazz += "Current";
199 }
200
201 if(adj){
202 date = this.dateFuncObj.add(date, "month", adj);
203 }
204 date.setDate(number);
205
206 if(!this.dateFuncObj.compare(date, today, "date")){
207 clazz = "dijitCalendarCurrentDate " + clazz;
208 }
209
210 if(this._isSelectedDate(date, this.lang)){
211 clazz = "dijitCalendarSelectedDate " + clazz;
212 }
213
214 if(this.isDisabledDate(date, this.lang)){
215 clazz = "dijitCalendarDisabledDate " + clazz;
216 }
217
218 var clazz2 = this.getClassForDate(date, this.lang);
219 if(clazz2){
220 clazz = clazz2 + " " + clazz;
221 }
222
223 template.className = clazz + "Month dijitCalendarDateTemplate";
224 template.dijitDateValue = date.valueOf(); // original code
225 dojo.attr(template, "dijitDateValue", date.valueOf()); // so I can dojo.query() it
226 var label = dojo.query(".dijitCalendarDateLabel", template)[0],
227 text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate();
228 this._setText(label, text);
229 }, this);
230
231 // Repopulate month drop down list based on current year.
232 // Need to do this to hide leap months in Hebrew calendar.
233 var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month);
234 this.monthDropDownButton.dropDown.set("months", monthNames);
235
236 // Set name of current month and also fill in spacer element with all the month names
237 // (invisible) so that the maximum width will affect layout. But not on IE6 because then
238 // the center <TH> overlaps the right <TH> (due to a browser bug).
239 this.monthDropDownButton.containerNode.innerHTML =
240 (dojo.isIE == 6 ? "" : "<div class='dijitSpacer'>" + this.monthDropDownButton.dropDown.domNode.innerHTML + "</div>") +
241 "<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" + monthNames[month.getMonth()] + "</div>";
242
243 // Fill in localized prev/current/next years
244 var y = month.getFullYear() - 1;
245 var d = new this.dateClassObj();
246 dojo.forEach(["previous", "current", "next"], function(name){
247 d.setFullYear(y++);
248 this._setText(this[name+"YearLabelNode"],
249 this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
250 }, this);
251 },
252
253 goToToday: function(){
254 // summary:
255 // Sets calendar's value to today's date
256 this.set('value', new this.dateClassObj());
257 },
258
259 constructor: function(/*Object*/args){
260 var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date";
261 this.dateClassObj = dojo.getObject(dateClass, false);
262 this.datePackage = args.datePackage || this.datePackage;
263 this.dateFuncObj = dojo.getObject(this.datePackage, false);
264 this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
265 },
266
267 postMixInProperties: function(){
268 // Parser.instantiate sometimes passes in NaN for IE. Use default value in prototype instead.
269 // TODO: remove this for 2.0 (thanks to #11511)
270 if(isNaN(this.value)){ delete this.value; }
271
272 this.inherited(arguments);
273 },
274
275 buildRendering: function(){
276 this.inherited(arguments);
277 dojo.setSelectable(this.domNode, false);
278
279 var cloneClass = dojo.hitch(this, function(clazz, n){
280 var template = dojo.query(clazz, this.domNode)[0];
281 for(var i=0; i<n; i++){
282 template.parentNode.appendChild(template.cloneNode(true));
283 }
284 });
285
286 // clone the day label and calendar day templates 6 times to make 7 columns
287 cloneClass(".dijitCalendarDayLabelTemplate", 6);
288 cloneClass(".dijitCalendarDateTemplate", 6);
289
290 // now make 6 week rows
291 cloneClass(".dijitCalendarWeekTemplate", 5);
292
293 // insert localized day names in the header
294 var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang);
295 var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
296 dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
297 this._setText(label, dayNames[(i + dayOffset) % 7]);
298 }, this);
299
300 var dateObj = new this.dateClassObj(this.currentFocus);
301
302 this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
303 id: this.id + "_mdd",
304 onChange: dojo.hitch(this, "_onMonthSelect")
305 });
306
307 this.set('currentFocus', dateObj, false); // draw the grid to the month specified by currentFocus
308
309 // Set up repeating mouse behavior for increment/decrement of months/years
310 var _this = this;
311 var typematic = function(nodeProp, dateProp, adj){
312 _this._connects.push(
313 dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
314 if(count >= 0){ _this._adjustDisplay(dateProp, adj); }
315 }, 0.8, 500)
316 );
317 };
318 typematic("incrementMonth", "month", 1);
319 typematic("decrementMonth", "month", -1);
320 typematic("nextYearLabelNode", "year", 1);
321 typematic("previousYearLabelNode", "year", -1);
322 },
323
324 _adjustDisplay: function(/*String*/ part, /*int*/ amount){
325 // summary:
326 // Moves calendar forwards or backwards by months or years
327 // part:
328 // "month" or "year"
329 // amount:
330 // Number of months or years
331 // tags:
332 // private
333 this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
334 },
335
336 _setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
337 // summary:
338 // If the calendar currently has focus, then focuses specified date,
339 // changing the currently displayed month/year if necessary.
340 // If the calendar doesn't have focus, updates currently
341 // displayed month/year, and sets the cell that will get focus.
342 // forceFocus:
343 // If true, will focus() the cell even if calendar itself doesn't have focus
344
345 var oldFocus = this.currentFocus,
346 oldCell = oldFocus ? dojo.query("[dijitDateValue=" + oldFocus.valueOf() + "]", this.domNode)[0] : null;
347
348 // round specified value to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
349 date = new this.dateClassObj(date);
350 date.setHours(1, 0, 0, 0);
351
352 this._set("currentFocus", date);
353
354 // TODO: only re-populate grid when month/year has changed
355 this._populateGrid();
356
357 // set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
358 var newCell = dojo.query("[dijitDateValue=" + date.valueOf() + "]", this.domNode)[0];
359 newCell.setAttribute("tabIndex", this.tabIndex);
360 if(this._focused || forceFocus){
361 newCell.focus();
362 }
363
364 // set tabIndex=-1 on old focusable cell
365 if(oldCell && oldCell != newCell){
366 if(dojo.isWebKit){ // see #11064 about webkit bug
367 oldCell.setAttribute("tabIndex", "-1");
368 }else{
369 oldCell.removeAttribute("tabIndex");
370 }
371 }
372 },
373
374 focus: function(){
375 // summary:
376 // Focus the calendar by focusing one of the calendar cells
377 this._setCurrentFocusAttr(this.currentFocus, true);
378 },
379
380 _onMonthSelect: function(/*Number*/ newMonth){
381 // summary:
382 // Handler for when user selects a month from the drop down list
383 // tags:
384 // protected
385
386 // move to selected month, bounding by the number of days in the month
387 // (ex: dec 31 --> jan 28, not jan 31)
388 this.currentFocus = this.dateFuncObj.add(this.currentFocus, "month",
389 newMonth - this.currentFocus.getMonth());
390 this._populateGrid();
391 },
392
393 _onDayClick: function(/*Event*/ evt){
394 // summary:
395 // Handler for day clicks, selects the date if appropriate
396 // tags:
397 // protected
398 dojo.stopEvent(evt);
399 for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
400 if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
401 this.set('value', node.dijitDateValue);
402 }
403 },
404
405 _onDayMouseOver: function(/*Event*/ evt){
406 // summary:
407 // Handler for mouse over events on days, sets hovered style
408 // tags:
409 // protected
410
411 // event can occur on <td> or the <span> inside the td,
412 // set node to the <td>.
413 var node =
414 dojo.hasClass(evt.target, "dijitCalendarDateLabel") ?
415 evt.target.parentNode :
416 evt.target;
417
418 if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){
419 dojo.addClass(node, "dijitCalendarHoveredDate");
420 this._currentNode = node;
421 }
422 },
423
424 _onDayMouseOut: function(/*Event*/ evt){
425 // summary:
426 // Handler for mouse out events on days, clears hovered style
427 // tags:
428 // protected
429
430 if(!this._currentNode){ return; }
431
432 // if mouse out occurs moving from <td> to <span> inside <td>, ignore it
433 if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
434 var cls = "dijitCalendarHoveredDate";
435 if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) {
436 cls += " dijitCalendarActiveDate";
437 }
438 dojo.removeClass(this._currentNode, cls);
439 this._currentNode = null;
440 },
441
442 _onDayMouseDown: function(/*Event*/ evt){
443 var node = evt.target.parentNode;
444 if(node && node.dijitDateValue){
445 dojo.addClass(node, "dijitCalendarActiveDate");
446 this._currentNode = node;
447 }
448 },
449
450 _onDayMouseUp: function(/*Event*/ evt){
451 var node = evt.target.parentNode;
452 if(node && node.dijitDateValue){
453 dojo.removeClass(node, "dijitCalendarActiveDate");
454 }
455 },
456
457//TODO: use typematic
458 handleKey: function(/*Event*/ evt){
459 // summary:
460 // Provides keyboard navigation of calendar.
461 // description:
462 // Called from _onKeyPress() to handle keypress on a stand alone Calendar,
463 // and also from `dijit.form._DateTimeTextBox` to pass a keypress event
464 // from the `dijit.form.DateTextBox` to be handled in this widget
465 // returns:
466 // False if the key was recognized as a navigation key,
467 // to indicate that the event was handled by Calendar and shouldn't be propogated
468 // tags:
469 // protected
470 var dk = dojo.keys,
471 increment = -1,
472 interval,
473 newValue = this.currentFocus;
474 switch(evt.keyCode){
475 case dk.RIGHT_ARROW:
476 increment = 1;
477 //fallthrough...
478 case dk.LEFT_ARROW:
479 interval = "day";
480 if(!this.isLeftToRight()){ increment *= -1; }
481 break;
482 case dk.DOWN_ARROW:
483 increment = 1;
484 //fallthrough...
485 case dk.UP_ARROW:
486 interval = "week";
487 break;
488 case dk.PAGE_DOWN:
489 increment = 1;
490 //fallthrough...
491 case dk.PAGE_UP:
492 interval = evt.ctrlKey || evt.altKey ? "year" : "month";
493 break;
494 case dk.END:
495 // go to the next month
496 newValue = this.dateFuncObj.add(newValue, "month", 1);
497 // subtract a day from the result when we're done
498 interval = "day";
499 //fallthrough...
500 case dk.HOME:
501 newValue = new this.dateClassObj(newValue);
502 newValue.setDate(1);
503 break;
504 case dk.ENTER:
505 case dk.SPACE:
506 this.set("value", this.currentFocus);
507 break;
508 default:
509 return true;
510 }
511
512 if(interval){
513 newValue = this.dateFuncObj.add(newValue, interval, increment);
514 }
515
516 this._setCurrentFocusAttr(newValue);
517
518 return false;
519 },
520
521 _onKeyPress: function(/*Event*/ evt){
522 // summary:
523 // For handling keypress events on a stand alone calendar
524 if(!this.handleKey(evt)){
525 dojo.stopEvent(evt);
526 }
527 },
528
529 onValueSelected: function(/*Date*/ date){
530 // summary:
531 // Notification that a date cell was selected. It may be the same as the previous value.
532 // description:
533 // Formerly used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
534 // to get notification when the user has clicked a date. Now onExecute() (above) is used.
535 // tags:
536 // protected
537 },
538
539 onChange: function(/*Date*/ date){
540 // summary:
541 // Called only when the selected date has changed
542 },
543
544 _isSelectedDate: function(/*Date*/ dateObject, /*String?*/ locale){
545 // summary:
546 // Extension point so developers can subclass Calendar to
547 // support multiple (concurrently) selected dates
548 // tags:
549 // protected extension
550 return this._isValidDate(this.value) && !this.dateFuncObj.compare(dateObject, this.value, "date")
551 },
552
553 isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
554 // summary:
555 // May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
556 // tags:
557 // extension
558/*=====
559 return false; // Boolean
560=====*/
561 },
562
563 getClassForDate: function(/*Date*/ dateObject, /*String?*/ locale){
564 // summary:
565 // May be overridden to return CSS classes to associate with the date entry for the given dateObject,
566 // for example to indicate a holiday in specified locale.
567 // tags:
568 // extension
569
570/*=====
571 return ""; // String
572=====*/
573 }
574 }
575);
576
577dojo.declare("dijit.Calendar._MonthDropDown", [dijit._Widget, dijit._Templated], {
578 // summary:
579 // The month drop down
580
581 // months: String[]
582 // List of names of months, possibly w/some undefined entries for Hebrew leap months
583 // (ex: ["January", "February", undefined, "April", ...])
584 months: [],
585
586 templateString: "<div class='dijitCalendarMonthMenu dijitMenu' " +
587 "dojoAttachEvent='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
588
589 _setMonthsAttr: function(/*String[]*/ months){
590 this.domNode.innerHTML = dojo.map(months, function(month, idx){
591 return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
592 }).join("");
593 },
594
595 _onClick: function(/*Event*/ evt){
596 this.onChange(dojo.attr(evt.target, "month"));
597 },
598
599 onChange: function(/*Number*/ month){
600 // summary:
601 // Callback when month is selected from drop down
602 },
603
604 _onMenuHover: function(evt){
605 dojo.toggleClass(evt.target, "dijitCalendarMonthLabelHover", evt.type == "mouseover");
606 }
2f01fe57 607});
81bea17a 608
2f01fe57 609}