source: Dev/trunk/src/client/dijit/Calendar.js @ 487

Last change on this file since 487 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

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