source: Dev/branches/rest-dojo-ui/client/dijit/Calendar.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 10.1 KB
RevLine 
[256]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/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});
Note: See TracBrowser for help on using the repository browser.