source: Dev/trunk/src/client/dojox/calendar/CalendarBase.js @ 485

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

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 41.3 KB
Line 
1define([
2"dojo/_base/declare",
3"dojo/_base/sniff",
4"dojo/_base/event",
5"dojo/_base/lang",
6"dojo/_base/array",
7"dojo/cldr/supplemental",
8"dojo/dom",
9"dojo/dom-class",
10"dojo/dom-style",
11"dojo/dom-construct",
12"dojo/dom-geometry",
13"dojo/date",
14"dojo/date/locale",
15"dojo/_base/fx",
16"dojo/fx",
17"dojo/on",
18"dijit/_WidgetBase",
19"dijit/_TemplatedMixin",
20"dijit/_WidgetsInTemplateMixin",
21"./StoreMixin",
22"dojox/widget/_Invalidating",
23"dojox/widget/Selection",
24"dojox/calendar/time",
25"dojo/i18n!./nls/buttons"],     
26function(
27declare,
28has,
29event,
30lang,
31arr,
32cldr,
33dom,
34domClass,
35domStyle,
36domConstruct,
37domGeometry,
38date,
39locale,
40coreFx,
41fx,
42on, 
43_WidgetBase,
44_TemplatedMixin,
45_WidgetsInTemplateMixin,
46StoreMixin,
47_Invalidating,
48Selection,
49timeUtil,
50_nls){
51       
52        /*=====
53        var __HeaderClickEventArgs = {
54                // summary:
55                //              A column click event.
56                // index: Integer
57                //              The column index.
58                // date: Date
59                //              The date displayed by the column.
60                // triggerEvent: Event
61                //              The origin event.
62        };
63        =====*/
64       
65        /*=====
66        var __TimeIntervalChangeArgs = {
67                // summary:
68                //              An time interval change event, dispatched when the calendar displayed time range has changed.
69                // oldStartTime: Date
70                //              The start of the previously displayed time interval, if any.
71                // startTime: Date
72                //              The new start of the displayed time interval.
73                // oldEndTime: Date
74                //              The end of the previously displayed time interval, if any.
75                // endTime: Date
76                //              The new end of the displayed time interval.
77        };
78        =====*/
79       
80        /*=====
81        var __GridClickEventArgs = {
82                // summary:
83                //              The event dispatched when the grid is clicked or double-clicked.
84                // date: Date
85                //              The start of the previously displayed time interval, if any.
86                // triggerEvent: Event
87                //              The event at the origin of this event.
88        };
89        =====*/
90       
91        /*=====
92        var __ItemMouseEventArgs = {
93                // summary:
94                //              The event dispatched when an item is clicked, double-clicked or context-clicked.
95                // item: Object
96                //              The item clicked.
97                // renderer: dojox/calendar/_RendererMixin
98                //              The item renderer clicked.
99                // triggerEvent: Event
100                //              The event at the origin of this event.
101        };
102        =====*/
103       
104        /*=====
105        var __itemEditingEventArgs = {
106                // summary:
107                //              An item editing event.
108                // item: Object
109                //              The render item that is being edited. Set/get the startTime and/or endTime properties to customize editing behavior.
110                // storeItem: Object
111                //              The real data from the store. DO NOT change properties, but you may use properties of this item in the editing behavior logic.
112                // editKind: String
113                //              Kind of edit: "resizeBoth", "resizeStart", "resizeEnd" or "move".
114                // dates: Date[]
115                //              The computed date/time of the during the event editing. One entry per edited date (touch use case).
116                // startTime: Date?
117                //              The start time of data item.
118                // endTime: Date?
119                //              The end time of data item.
120                // sheet: String
121                //              For views with several sheets (columns view for example), the sheet when the event occurred.
122                // source: dojox/calendar/ViewBase
123                //              The view where the event occurred.
124                // eventSource: String
125                //              The device that triggered the event. This property can take the following values:
126                //
127                //              - "mouse",
128                //              - "keyboard",
129                //              - "touch"               
130                // triggerEvent: Event
131                //              The event at the origin of this event.
132        };
133        =====*/
134       
135        /*=====
136        var __rendererLifecycleEventArgs = {
137                // summary:
138                //              A renderer lifecycle event.
139                // renderer: Object
140                //              The renderer.           
141                // source: dojox/calendar/ViewBase
142                //              The view where the event occurred.
143                // item:Object?
144                //              The item that will be displayed by the renderer for the "rendererCreated" and "rendererReused" events.
145        };
146        =====*/
147       
148        /*=====
149        var __ExpandRendererClickEventArgs = {
150                // summary:
151                //              A expand renderer click event.
152                // columnIndex: Integer
153                //              The column index of the cell.
154                // rowIndex: Integer
155                //              The row index of the cell.
156                // date: Date
157                //              The date displayed by the cell.
158                // triggerEvent: Event
159                //              The origin event.
160        };
161        =====*/
162
163        return declare("dojox.calendar.CalendarBase", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, StoreMixin, _Invalidating, Selection], {
164               
165                // summary:             
166                //              This class defines a generic calendar widget that manages several views to display event in time.
167               
168                baseClass: "dojoxCalendar",
169               
170                // datePackage: Object
171                //              JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines at dojo.date by default.
172                datePackage: date,
173               
174                // startDate: Date
175                //              The start date of the displayed time interval.
176                startDate: null,
177
178                // endDate: Date
179                //              The end date of the displayed time interval (included).         
180                endDate: null,
181               
182                // date:Date
183                //              The reference date used to determine along with the <code>dateInterval</code>
184                //              and <code>dateIntervalSteps</code> properties the time interval to display.
185                date: null,
186       
187                // dateInterval:String
188                //              The date interval used to compute along with the <code>date</code> and
189                //              <code>dateIntervalSteps</code> the time interval to display.
190                //              Valid values are "day", "week" (default value) and "month".
191                dateInterval: "week",
192               
193                // dateIntervalSteps:Integer
194                //              The number of date intervals used to compute along with the <code>date</code> and
195                //              <code>dateInterval</code> the time interval to display.
196                //              Default value is 1.             
197                dateIntervalSteps: 1,           
198               
199                // viewContainer: Node
200                //              The DOM node that will contains the views.
201                viewContainer: null,
202               
203                // firstDayOfWeek: Integer
204                //              (Optional) The first day of week override. By default the first day of week is determined
205                //              for the current locale (extracted from the CLDR).
206                //              Special value -1 (default value), means use locale dependent value.
207                firstDayOfWeek: -1,
208               
209                // formatItemTimeFunc: Function?
210                //              Optional function to format the time of day of the item renderers.
211                //              The function takes the date and render data object as arguments and returns a String.
212                formatItemTimeFunc: null,
213               
214                // editable: Boolean
215                //              A flag that indicates whether or not the user can edit
216                //              items in the data provider.
217                //              If <code>true</code>, the item renderers in the control are editable.
218                //              The user can click on an item renderer, or use the keyboard or touch devices, to move or resize the associated event.
219                editable: true,
220               
221                // moveEnabled: Boolean
222                //              A flag that indicates whether the user can move items displayed.
223                //              If <code>true</code>, the user can move the items.
224                moveEnabled: true,
225               
226                // resizeEnabled: Boolean
227                //              A flag that indicates whether the items can be resized.
228                //              If <code>true</code>, the control supports resizing of items.
229                resizeEnabled: true,
230               
231                // columnView: dojox/calendar/ColumnView
232                //              The column view is displaying one day to seven days time intervals.
233                columnView: null,
234               
235                // matrixView: dojox/calendar/MatrixView
236                //              The column view is displaying time intervals that lasts more than seven days.
237                matrixView: null,
238               
239                // columnViewProps: Object
240                //              Map of property/value passed to the constructor of the column view.
241                columnViewProps: null,
242               
243                // matrixViewProps: Object
244                //              Map of property/value passed to the constructor of the matrix view.
245                matrixViewProps: null,
246               
247                // createOnGridClick: Boolean
248                //              Indicates whether the user can create new event by clicking and dragging the grid.
249                //              A createItem function must be defined on the view or the calendar object.
250                createOnGridClick: false,
251               
252                // createItemFunc: Function
253                //              A user supplied function that creates a new event.
254                //              This function is used when createOnGridClick is set to true and the user is clicking and dragging on the grid.
255                //              This view takes two parameters:
256                //
257                //              - view: the current view,
258                //              - d: the date at the clicked location.
259                createItemFunc: null,
260               
261                // currentView: ViewBase
262                //              The current view displayed by the Calendar object.
263                //              The currentViewChange event can be used to react on a view change.
264                currentView: null,
265                               
266                _currentViewIndex: -1,
267               
268                views: null,
269               
270                _calendar: "gregorian",
271               
272                constructor: function(/*Object*/args){
273                        this.views = [];
274                       
275                        this.invalidatingProperties = ["store", "items", "startDate", "endDate", "views",
276                                "date", "dateInterval", "dateIntervalSteps", "firstDayOfWeek"];
277                       
278                        args = args || {};
279                        this._calendar = args.datePackage ? args.datePackage.substr(args.datePackage.lastIndexOf(".")+1) : this._calendar;
280                        this.dateModule = args.datePackage ? lang.getObject(args.datePackage, false) : date;
281                        this.dateClassObj = this.dateModule.Date || Date;
282                        this.dateLocaleModule = args.datePackage ? lang.getObject(args.datePackage+".locale", false) : locale;
283                                                               
284                        this.invalidateRendering();
285                },
286                               
287                buildRendering: function(){
288                        this.inherited(arguments);
289                        if(this.views == null || this.views.length == 0){
290                                this.set("views", this._createDefaultViews()); 
291                        }                       
292                },
293               
294                _applyAttributes: function(){
295                        this._applyAttr = true;
296                        this.inherited(arguments);
297                        delete this._applyAttr;
298                },
299               
300                ////////////////////////////////////////////////////
301                //
302                // Getter / setters
303                //
304                ////////////////////////////////////////////////////
305                               
306                _setStartDateAttr: function(value){
307                        this._set("startDate", value);
308                        this._timeRangeInvalidated = true;
309                },
310               
311                _setEndDateAttr: function(value){
312                        this._set("endDate", value);
313                        this._timeRangeInvalidated = true;
314                },
315               
316                _setDateAttr: function(value){
317                        this._set("date", value);
318                        this._timeRangeInvalidated = true;
319                },
320               
321                _setDateIntervalAttr: function(value){
322                        this._set("dateInterval", value);
323                        this._timeRangeInvalidated = true;
324                },
325               
326                _setDateIntervalStepsAttr: function(value){
327                        this._set("dateIntervalSteps", value);
328                        this._timeRangeInvalidated = true;
329                },
330               
331                _setFirstDayOfWeekAttr: function(value){
332                        this._set("firstDayOfWeek", value);
333                        if(this.get("date") != null && this.get("dateInterval") == "week"){
334                                this._timeRangeInvalidated = true;
335                        }                       
336                },
337               
338                _setTextDirAttr: function(value){
339                        arr.forEach(this.views, function(view){
340                                view.set("textDir", value);
341                        });
342                },
343               
344                ///////////////////////////////////////////////////
345                //
346                // Validating
347                //
348                ///////////////////////////////////////////////////
349               
350                refreshRendering: function(){
351                        // summary:
352                        //              Refreshes all the visual rendering of the calendar.
353                        // tags:
354                        //              protected
355                        this.inherited(arguments);
356                        this._validateProperties();
357                },
358               
359                _refreshItemsRendering: function(){
360                        if(this.currentView){
361                                this.currentView._refreshItemsRendering();
362                        }
363                },
364               
365                resize: function(changeSize){
366                        if(changeSize){
367                                domGeometry.setMarginBox(this.domNode, changeSize);
368                        }
369                        if(this.currentView){
370                                // must not pass the size, children are sized depending on the parent by CSS.
371                                this.currentView.resize(); 
372                        }
373                },
374                               
375                _validateProperties: function(){
376                        // tags:
377                        //              private
378
379                        var cal = this.dateModule;
380                        var startDate = this.get("startDate");
381                        var endDate = this.get("endDate");
382                        var date = this.get("date");
383                       
384                        if(this.firstDayOfWeek < -1 || this.firstDayOfWeek > 6){
385                                this._set("firstDayOfWeek", 0);
386                        }
387                       
388                        if(date == null && (startDate != null || endDate != null)){
389                               
390                                if(startDate == null){
391                                        startDate = new this.dateClassObj();
392                                        this._set("startDate", startDate);
393                                        this._timeRangeInvalidated = true;
394                                }
395                               
396                                if(endDate == null){
397                                        endDate = new this.dateClassObj();
398                                        this._set("endDate", endDate);
399                                        this._timeRangeInvalidated = true;
400                                }
401                               
402                                if(cal.compare(startDate, endDate) >= 0){
403                                        endDate = cal.add(startDate, "day", 1);
404                                        this._set("endDate", endDate);
405                                        this._timeRangeInvalidated = true;
406                                }
407                       
408                        }else{
409                       
410                                if(this.date == null){
411                                        this._set("date", new this.dateClassObj());
412                                        this._timeRangeInvalidated = true;
413                                }
414                               
415                                var dint = this.get("dateInterval");
416                                if(dint != "day" && dint != "week" && dint != "month"){
417                                        this._set("dateInterval", "day");
418                                        this._timeRangeInvalidated = true;
419                                }
420                               
421                                var dis = this.get("dateIntervalSteps");
422                                if(lang.isString(dis)){
423                                        dis = parseInt(dis);
424                                        this._set("dateIntervalSteps", dis);
425                                }
426                                if(dis <= 0) {
427                                        this.set("dateIntervalSteps", 1);
428                                        this._timeRangeInvalidated = true;
429                                }
430                        }
431                       
432                        if(this._timeRangeInvalidated){
433                                this._timeRangeInvalidated = false;
434                                var timeInterval = this.computeTimeInterval();
435                               
436                                if(this._timeInterval == null ||
437                                         cal.compare(this._timeInterval[0], timeInterval[0]) != 0 ||
438                                         cal.compare(this._timeInterval[1], timeInterval[1]) != 0){
439                                        this.onTimeIntervalChange({
440                                                oldStartTime: this._timeInterval == null ? null : this._timeInterval[0],
441                                                oldEndTime: this._timeInterval == null ? null : this._timeInterval[1],
442                                                startTime: timeInterval[0],
443                                                endTime: timeInterval[1]
444                                        });
445                                }
446                               
447                                this._timeInterval = timeInterval;
448                               
449                                var duration = this.dateModule.difference(this._timeInterval[0], this._timeInterval[1], "day");
450                                var view = this._computeCurrentView(timeInterval[0], timeInterval[1], duration);
451                               
452                                var index = arr.indexOf(this.views, view);
453                               
454                                if(view == null || index == -1){
455                                        return;
456                                }
457                               
458                                if(this.animateRange && (!has("ie") || has("ie")>8) ){
459                                        if(this.currentView){ // there's a view to animate
460                                                var ltr = this.isLeftToRight();
461                                                var inLeft = this._animRangeInDir=="left" || this._animRangeInDir == null;
462                                                var outLeft = this._animRangeOutDir=="left" || this._animRangeOutDir == null;
463                                                this._animateRange(this.currentView.domNode, outLeft && ltr, false, 0, outLeft ? -100 : 100,
464                                                        lang.hitch(this, function(){
465                                                                this.animateRangeTimer = setTimeout(lang.hitch(this, function(){
466                                                                        this._applyViewChange(view, index, timeInterval, duration);
467                                                                        this._animateRange(this.currentView.domNode, inLeft && ltr, true, inLeft ? -100 : 100, 0);
468                                                                        this._animRangeInDir = null;
469                                                                        this._animRangeOutDir = null;
470                                                                }), 100);       // setTimeout give time for layout of view.                                                     
471                                                        }));
472                                        }else{
473                                                this._applyViewChange(view, index, timeInterval, duration);                                             
474                                        }
475                                }else{                                 
476                                        this._applyViewChange(view, index, timeInterval, duration);
477                                }
478                        }
479                },
480               
481                _applyViewChange: function(view, index, timeInterval, duration){                       
482                        // summary:
483                        //              Applies the changes of a view time and changes the currently visible view if needed.
484                        // view: ViewBase
485                        //              The view that is configured and is or will be shown.
486                        // index: Integer
487                        //              The view index in the internal structure.
488                        // timeInterval: Date[]
489                        //              The time interval displayed by the calendar.
490                        // duration: Integer
491                        //              The duration in days of the time interval.
492                        // tags:
493                        //              protected
494                       
495                        this._configureView(view, index, timeInterval, duration);
496                       
497                        if(index != this._currentViewIndex){
498                                if(this.currentView == null){
499                                        view.set("items", this.items);
500                                        this.set("currentView", view);                 
501                                }else{                                 
502                                        if(this.items == null || this.items.length == 0){
503                                                this.set("currentView", view);
504                                                if(this.animateRange && (!has("ie") || has("ie")>8) ){
505                                                        domStyle.set(this.currentView.domNode, "opacity", 0);
506                                                }
507                                                view.set("items", this.items);
508                                        }else{
509                                                this.currentView = view;
510                                                view.set("items", this.items);
511                                                this.set("currentView", view);
512                                                if(this.animateRange && (!has("ie") || has("ie")>8) ){
513                                                        domStyle.set(this.currentView.domNode, "opacity", 0);
514                                                }
515                                        }                                                                                                                                       
516                                }                                                                                       
517                        }
518                },
519               
520                _timeInterval: null,
521               
522                computeTimeInterval: function(){
523                        // summary:
524                        //              Computes the displayed time interval according to the date, dateInterval and
525                        //              dateIntervalSteps if date is not null or startDate and endDate properties otherwise.
526                        // tags:
527                        //              protected
528                                       
529                        var cal = this.dateModule;
530                        var d = this.get("date");
531                       
532                        if(d == null){
533                                return [ this.floorToDay(this.get("startDate")), cal.add(this.get("endDate"), "day", 1) ];
534                        }
535                               
536                        var s = this.floorToDay(d);
537                        var di = this.get("dateInterval");
538                        var dis = this.get("dateIntervalSteps");
539                        var e;
540                       
541                        switch(di){
542                                case "day":                                             
543                                        e = cal.add(s, "day", dis);
544                                        break;
545                                case "week":
546                                        s = this.floorToWeek(s);
547                                        e = cal.add(s, "week", dis);
548                                        break;
549                                case "month":
550                                        s.setDate(1);
551                                        e = cal.add(s, "month", dis);                                           
552                                        break;
553                        }                               
554                        return [s, e];                                         
555                },
556               
557                onTimeIntervalChange: function(e){
558                        // summary:
559                        //              Event dispatched when the displayed time interval has changed.
560                        // e: __TimeIntervalChangeArgs
561                        //              The time interval change event.
562                        // tags:
563                        //              callback
564                },
565               
566                /////////////////////////////////////////////////////
567                //
568                // View Management
569                //
570                /////////////////////////////////////////////////////
571               
572                // views: dojox.calendar.ViewBase[]
573                //              The views displayed by the widget.
574                //              To add/remove only one view, prefer, respectively, the addView() or removeView() methods.
575                views: null,
576               
577                _setViewsAttr: function(views){
578                        if(!this._applyAttr){
579                                // 1/ in create() the constructor parameters are mixed in the widget
580                                // 2/ in _applyAttributes(), every property with a setter is called.
581                                // So no need to call on view removed for a non added view....
582                                for(var i=0;i<this.views.length;i++){
583                                        this._onViewRemoved(this.views[i]);
584                                }
585                        }
586                        if(views != null){
587                                for(var i=0;i<views.length;i++){
588                                        this._onViewAdded(views[i]);
589                                }                       
590                        }
591                        this._set("views",  views == null ? [] : views.concat());                       
592                },
593               
594                _getViewsAttr: function(){
595                        return this.views.concat();
596                },
597               
598                _createDefaultViews: function(){
599                        // summary:
600                        //              Creates the default views.
601                        //              This method does nothing and is designed to be overridden.
602                        // tags:
603                        //              protected
604                },
605               
606                addView: function(view, index){
607                        // summary:
608                        //              Add a view to the calendar's view list.
609                        // view: dojox/calendar/ViewBase
610                        //              The view to add to the calendar.
611                        // index: Integer
612                        //              Optional, the index where to insert the view in current view list.
613                        // tags:
614                        //              protected
615
616                        if(index <= 0 || index > this.views.length){
617                                index = this.views.length;
618                        }
619                        this.views.splice(index, view);
620                        this._onViewAdded(view);
621                },
622               
623                removeView: function(view){
624                        // summary:
625                        //              Removes a view from the calendar's view list.
626                        // view: dojox/calendar/ViewBase
627                        //              The view to remove from the calendar.
628                        // tags:
629                        //              protected
630
631                        if(index < 0 || index >=  this.views.length){
632                                return;
633                        }
634                       
635                        this._onViewRemoved(this.views[index]);
636                        this.views.splice(index, 1);
637                },
638               
639                _onViewAdded: function(view){
640                        view.owner = this;
641                        view.buttonContainer = this.buttonContainer;
642                        view._calendar = this._calendar;
643                        view.datePackage = this.datePackage;
644                        view.dateModule = this.dateModule;
645                        view.dateClassObj = this.dateClassObj;
646                        view.dateLocaleModule = this.dateLocaleModule;
647                        domStyle.set(view.domNode, "display", "none");                 
648                        domClass.add(view.domNode, "view");
649                        domConstruct.place(view.domNode, this.viewContainer);
650                        this.onViewAdded(view);
651                },
652               
653                onViewAdded: function(view){
654                        // summary:
655                        //              Event dispatched when a view is added from the calendar.
656                        // view: dojox/calendar/ViewBase
657                        //              The view that has been added to the calendar.
658                        // tags:
659                        //              callback
660
661                },
662               
663                _onViewRemoved: function(view){
664                        view.owner = null;
665                        view.buttonContainer = null;
666                        domClass.remove(view.domNode, "view");
667                        this.viewContainer.removeChild(view.domNode);
668                        this.onViewRemoved(view);
669                },
670               
671                onViewRemoved: function(view){                 
672                        // summary:
673                        //              Event dispatched when a view is removed from the calendar.
674                        // view: dojox/calendar/ViewBase
675                        //              The view that has been removed from the calendar.
676                        // tags:
677                        //              callback
678
679                },
680               
681                _setCurrentViewAttr: function(view){
682                        var index = arr.indexOf(this.views, view);
683                        if(index != -1){
684                                var oldView = this.get("currentView");
685                                this._currentViewIndex = index;
686                                this._set("currentView", view);
687                               
688                                this._showView(oldView, view);
689                                this.onCurrentViewChange({
690                                        oldView: oldView,
691                                        newView: view
692                                });
693                        }                                       
694                },
695                               
696                _getCurrentViewAttr: function(){
697                        return this.views[this._currentViewIndex];             
698                },
699               
700                onCurrentViewChange: function(e){
701                        // summary:
702                        //              Event dispatched when the current view has changed.
703                        // e: Event
704                        //              Object that contains the oldView and newView properties.
705                        // tags:
706                        //              callback
707
708                },
709               
710                _configureView: function(view, index, timeInterval, duration){
711                        // summary:
712                        //              Configures the view to show the specified time interval.
713                        //              This method is computing and setting the following properties:
714                        //              - "startDate", "columnCount" for a column view,
715                        //              - "startDate", "columnCount", "rowCount", "refStartTime" and "refEndTime" for a matrix view.
716                        //              This method can be extended to configure other properties like layout properties for example.
717                        // view: dojox/calendar/ViewBase
718                        //              The view to configure.
719                        // index: Integer
720                        //              The index of the view in the Calendar view list.
721                        // timeInterval: Date[]
722                        //              The time interval that will be displayed by the view.
723                        // duration: Integer
724                        //              The duration, in days, of the displayed time interval.
725                        // tags:
726                        //              protected
727
728                        var cal = this.dateModule;
729                        if(view.viewKind == "columns"){
730                                view.set("startDate", timeInterval[0]);
731                                view.set("columnCount", duration);
732                        }else if(view.viewKind == "matrix"){
733                                if(duration > 7){ // show only full weeks.
734                                        var s = this.floorToWeek(timeInterval[0]);                                     
735                                        var e = this.floorToWeek(timeInterval[1]);
736                                        if(cal.compare(e, timeInterval[1]) != 0){
737                                                e = this.dateModule.add(e, "week", 1);
738                                        }                                       
739                                        duration = this.dateModule.difference(s, e, "day");
740                                        view.set("startDate", s);
741                                        view.set("columnCount", 7);
742                                        view.set("rowCount", Math.ceil(duration/7));
743                                        view.set("refStartTime", timeInterval[0]);
744                                        view.set("refEndTime", timeInterval[1]);                                       
745                                }else{
746                                        view.set("startDate", timeInterval[0]);
747                                        view.set("columnCount", duration);
748                                        view.set("rowCount", 1);
749                                        view.set("refStartTime", null);
750                                        view.set("refEndTime", null);
751                                }                               
752                        }
753                },
754               
755                _computeCurrentView: function(startDate, endDate, duration){
756                        // summary:
757                        //              If the time range is lasting less than seven days returns the column view or the matrix view otherwise.
758                        // startDate: Date
759                        //              The start date of the displayed time interval
760                        // endDate: Date
761                        //              The end date of the displayed time interval     
762                        // duration: Integer
763                        //              Duration of the                 
764                        // returns: dojox/calendar/ViewBase
765                        //              The view to display.
766                        // tags:
767                        //              protected
768
769                        return duration <= 7 ? this.columnView : this.matrixView;
770                },
771               
772                matrixViewRowHeaderClick: function(e){
773                        // summary:
774                        //              Function called when the cell of a row header of the matrix view is clicked.
775                        //              The implementation is doing the foolowing actions:
776                        //              - If another row is already expanded, collapse it and then expand the clicked row.
777                        //              - If the clicked row is already expadned, collapse it.
778                        //              - If no row is expanded, expand the click row.
779                        // e: Object
780                        //              The row header click event.
781                        // tags:
782                        //              protected
783
784                        var expIndex = this.matrixView.getExpandedRowIndex();
785                                if(expIndex == e.index){
786                                        this.matrixView.collapseRow();
787                                }else if(expIndex == -1){
788                                        this.matrixView.expandRow(e.index);
789                                }else{
790                                        var h = this.matrixView.on("expandAnimationEnd", lang.hitch(this, function(){
791                                                h.remove();
792                                                this.matrixView.expandRow(e.index);
793                                        }));
794                                        this.matrixView.collapseRow();
795                                }
796                },
797               
798                columnViewColumnHeaderClick: function(e){
799                        // summary:
800                        //              Function called when the cell of a column header of the column view is clicked.
801                        //              Show the time range defined by the clicked date.
802                        // e: Object
803                        //              The column header click event.
804                        // tags:
805                        //              protected
806
807                        var cal = this.dateModule;
808                        if(cal.compare(e.date, this._timeInterval[0]) == 0 && this.dateInterval == "day" && this.dateIntervalSteps == 1){
809                                this.set("dateInterval", "week");
810                        }else{
811                                this.set("date", e.date);
812                                this.set("dateInterval", "day");
813                                this.set("dateIntervalSteps", 1);
814                        }
815                },
816               
817                // viewFadeDuration: Integer
818                //              The duration in milliseconds of the fade animation when the current view is changing.
819                viewChangeDuration: 0,
820               
821                _showView: function(oldView, newView){
822                        // summary:
823                        //              Displays the current view.
824                        // oldView: dojox/calendar/ViewBase
825                        //              The previously displayed view or null.
826                        // newView: dojox/calendar/ViewBase
827                        //              The view to display.
828                        // tags:
829                        //              protected
830
831                        if(oldView != null){                                                                   
832                                domStyle.set(oldView.domNode, "display", "none");                                                       
833                        }
834                        if(newView != null){                                                                                           
835                                domStyle.set(newView.domNode, "display", "block");
836                                newView.resize();                               
837                                if(!has("ie") || has("ie") > 7){
838                                        domStyle.set(newView.domNode, "opacity", "1");
839                                }
840                        }
841                },
842               
843                ////////////////////////////////////////////////////
844                //
845                // Store & data
846                //
847                ////////////////////////////////////////////////////
848               
849                _setItemsAttr: function(value){
850                        this._set("items", value);
851                        if(this.currentView){
852                                this.currentView.set("items", value);
853                                if(!this._isEditing){
854                                        this.currentView.invalidateRendering();
855                                }
856                        }
857                },
858               
859                /////////////////////////////////////////////////////
860                //
861                // Time utilities
862                //
863                ////////////////////////////////////////////////////
864               
865                floorToDay: function(date, reuse){
866                        // summary:
867                        //              Floors the specified date to the start of day.
868                        // date: Date
869                        //              The date to floor.
870                        // reuse: Boolean
871                        //              Whether use the specified instance or create a new one. Default is false.
872                        // returns: Date
873                        return timeUtil.floorToDay(date, reuse, this.dateClassObj);
874                },
875               
876                floorToWeek: function(d){
877                        // summary:
878                        //              Floors the specified date to the beginning of week.
879                        // date: Date
880                        //              Date to floor.
881                        return timeUtil.floorToWeek(d, this.dateClassObj, this.dateModule, this.firstDayOfWeek, this.locale);
882                },
883               
884                newDate: function(obj){
885                        // summary:
886                        //              Creates a new Date object.
887                        // obj: Object
888                        //              This object can have several values:
889                        //              - the time in milliseconds since gregorian epoch.
890                        //              - a Date instance
891                        // returns: Date
892                        return timeUtil.newDate(obj, this.dateClassObj);                       
893                },
894               
895                isToday: function(date){
896                        // summary:
897                        //              Returns whether the specified date is in the current day.
898                        // date: Date
899                        //              The date to test.
900                        // renderData: Object
901                        //              The current renderData
902                        // returns: Boolean
903                        return timeUtil.isToday(date, this.dateClassObj);
904                },
905               
906                isStartOfDay: function(d){
907                        // summary:
908                        //              Tests if the specified date represents the starts of day.
909                        // d:Date
910                        //              The date to test.
911                        // returns: Boolean
912                        return timeUtil.isStartOfDay(d, this.dateClassObj, this.dateModule);
913                },
914               
915                floorDate: function(date, unit, steps, reuse){
916                        // summary:
917                        //              floors the date to the unit.
918                        // date: Date
919                        //              The date/time to floor.
920                        // unit: String
921                        //              The unit. Valid values are "minute", "hour", "day".
922                        // steps: Integer
923                        //              For "day" only 1 is valid.
924                        // reuse: Boolean
925                        //              Whether use the specified instance or create a new one. Default is false.                       
926                        // returns: Date
927                        return timeUtil.floor(date, unit, steps, reuse, this.classFuncObj);
928                },
929               
930                /////////////////////////////////////////////////////
931                //
932                // Time navigation
933                //
934                ////////////////////////////////////////////////////
935               
936               
937                // animateRange: Boolean
938                //              Indicates that the previous/next range method will be animated.
939                animateRange: true,
940               
941                // animationRangeDuration: Integer
942                //              The duration of the next/previous range animation.
943                animationRangeDuration: 400,
944               
945                _animateRange : function(node, toLeft, fadeIn, xFrom, xTo, onEnd){
946                        // summary:
947                        //              Animates the current view using a synchronous fade and horizontal translation.
948                        // toLeft: Boolean
949                        //              Whether the view is moved to the left or to the right.
950                        // fadeIn: Boolean
951                        //              Whether the view is faded in or out.
952                        // xFrom: Integer
953                        //              Position before the animation
954                        // xTo: Integer
955                        //              Position after the animation
956                        // onEnd: Function
957                        //              Function called when the animation is finished.
958                        // tags:
959                        //              protected
960
961                       
962                        if(this.animateRangeTimer){ // cleanup previous call not finished
963                                clearTimeout(this.animateRangeTimer);
964                                delete this.animateRangeTimer;
965                        }
966                       
967                        var fadeFunc = fadeIn ? coreFx.fadeIn : coreFx.fadeOut;                                                         
968                        domStyle.set(node, {left: xFrom + "px", right: (-xFrom) + "px"});
969                                               
970                        fx.combine([
971                                coreFx.animateProperty({
972                                        node: node,
973                                        properties: {left: xTo, right: -xTo},
974                                        duration: this.animationRangeDuration/2,
975                                        onEnd: onEnd                                                                   
976                                }),
977                                fadeFunc({node: node, duration: this.animationRangeDuration/2})
978                        ]).play();
979                },                     
980               
981                // _animRangeOutDir: Boolean
982                //              Direction of the range animation when the view 'leaving' the screen.
983                //              Valid values are:
984                //              - null: auto value,
985                //              - "left": hides to left side (right in right to left).
986                //              - "right": hides to right side (left in right to left).
987                _animRangeOutDir: null,
988
989                // _animRangeInDir: Boolean
990                //              Direction of the range animation when the view 'entering' the screen.
991                //              Valid values are:
992                //              - null: auto value,
993                //              - "left": shows from left side (right in right to left).
994                //              - "right": shows from  right side (left in right to left).
995                _animRangeOutDir: null,         
996               
997                nextRange: function(){
998                        this._animRangeOutDir = "left";
999                        this._animRangeInDir = "right";                 
1000                        this._navigate(1);                     
1001                },
1002               
1003                previousRange: function(){
1004                        this._animRangeOutDir = "right";
1005                        this._animRangeInDir =  "left";                 
1006                        this._navigate(-1);                     
1007                },
1008               
1009                _navigate: function(dir){
1010                        // tags:
1011                        //              private
1012
1013                        var d = this.get("date");
1014                        var cal = this.dateModule;
1015                       
1016                        if(d == null){
1017                                var s = this.get("startDate");
1018                                var e = this.get("endDate");
1019                                var dur = cal.difference(s, e, "day");
1020                                if(dir == 1){                                                           
1021                                        e = cal.add(e, "day", 1);
1022                                        this.set("startDate", e);
1023                                        this.set("endDate", cal.add(e, "day", dur));
1024                                }else{
1025                                        s = cal.add(s, "day", -1);
1026                                        this.set("startDate", cal.add(s, "day", -dur));
1027                                        this.set("endDate", s);
1028                                }
1029                        }else{
1030                                var di = this.get("dateInterval");
1031                                var dis = this.get("dateIntervalSteps");
1032                                this.set("date", cal.add(d, di, dir * dis));
1033                        }
1034                },
1035               
1036                goToday: function(){
1037                        // summary:
1038                        //              Changes the displayed time interval to show the current day.
1039                        //              Sets the date property to the current day, the dateInterval property to "day" and
1040                        //              the "dateIntervalSteps" to 1.
1041                        this.set("date", this.floorToDay(new this.dateClassObj(), true));
1042                        this.set("dateInterval", "day");
1043                        this.set("dateIntervalSteps", 1);                       
1044                },
1045               
1046                ////////////////////////////////////////////////////
1047                //
1048                // Buttons
1049                //
1050                ////////////////////////////////////////////////////
1051               
1052                postCreate: function(){
1053                        this.inherited(arguments);
1054                        this.configureButtons();
1055                },
1056               
1057                configureButtons: function(){
1058                        // summary:
1059                        //              Set the localized labels of the buttons and the event handlers.
1060                        // tags:
1061                        //              protected
1062
1063                        var rtl = !this.isLeftToRight();
1064                       
1065                        if(this.previousButton){
1066                                this.previousButton.set("label", _nls[rtl?"nextButton":"previousButton"]);
1067                                this.own(
1068                                        on(this.previousButton, "click", lang.hitch(this, this.previousRange))
1069                                );     
1070                        }
1071                       
1072                        if(this.nextButton){
1073                                this.nextButton.set("label", _nls[rtl?"previousButton":"nextButton"]);
1074                                this.own(
1075                                        on(this.nextButton, "click", lang.hitch(this, this.nextRange))
1076                                );     
1077                        }
1078                       
1079                        if(rtl && this.previousButton && this.nextButton){
1080                                var t = this.previousButton;
1081                                this.previousButton = this.nextButton;
1082                                this.nextButton = t;
1083                        }
1084                       
1085                        if(this.todayButton){
1086                                this.todayButton.set("label", _nls.todayButton);
1087                                this.own(
1088                                        on(this.todayButton, "click", lang.hitch(this, this.todayButtonClick))
1089                                );     
1090                        }
1091                       
1092                        if(this.dayButton){
1093                                this.dayButton.set("label", _nls.dayButton);
1094                                this.own(
1095                                        on(this.dayButton, "click", lang.hitch(this, this.dayButtonClick))
1096                                );
1097                        }               
1098                       
1099                        if(this.weekButton){
1100                                this.weekButton.set("label", _nls.weekButton);
1101                                this.own(
1102                                        on(this.weekButton, "click", lang.hitch(this, this.weekButtonClick))
1103                                );     
1104                        }               
1105
1106                        if(this.fourDaysButton){
1107                                this.fourDaysButton.set("label", _nls.fourDaysButton);
1108                                this.own(
1109                                        on(this.fourDaysButton, "click", lang.hitch(this, this.fourDaysButtonClick))
1110                                );
1111                        }
1112                       
1113                        if(this.monthButton){
1114                                this.monthButton.set("label", _nls.monthButton);
1115                                this.own(
1116                                        on(this.monthButton, "click", lang.hitch(this, this.monthButtonClick))
1117                                );     
1118                        }       
1119                },
1120               
1121                todayButtonClick: function(e){
1122                        // summary:
1123                        //              The action triggered when the today button is clicked.
1124                        //              By default, calls the goToday() method.
1125
1126                        this.goToday();                                                 
1127                },
1128                dayButtonClick: function(e){
1129                        // summary:
1130                        //              The action triggerred when the day button is clicked.
1131                        //              By default, sets the dateInterval property to "day" and
1132                        //              the "dateIntervalSteps" to 1.
1133
1134                        if(this.get("date") == null){
1135                                this.set("date", this.floorToDay(new this.dateClassObj(), true));
1136                        }                       
1137                        this.set("dateInterval", "day");
1138                        this.set("dateIntervalSteps", 1);                                                               
1139                },
1140               
1141                weekButtonClick: function(e){
1142                        // summary:
1143                        //              The action triggered when the week button is clicked.
1144                        //              By default, sets the dateInterval property to "week" and
1145                        //              the "dateIntervalSteps" to 1.
1146                        this.set("dateInterval", "week");
1147                        this.set("dateIntervalSteps", 1);                                               
1148                },
1149                fourDaysButtonClick: function(e){
1150                        // summary:
1151                        //              The action triggerred when the 4 days button is clicked.
1152                        //              By default, sets the dateInterval property to "day" and
1153                        //              the "dateIntervalSteps" to 4.
1154                        this.set("dateInterval", "day");
1155                        this.set("dateIntervalSteps", 4);               
1156                },
1157                monthButtonClick: function(e){
1158                        // summary:
1159                        //              The action triggered when the month button is clicked.
1160                        //              By default, sets the dateInterval property to "month" and
1161                        //              the "dateIntervalSteps" to 1.
1162                        this.set("dateInterval", "month");
1163                        this.set("dateIntervalSteps", 1);               
1164                },
1165                                       
1166                /////////////////////////////////////////////////////
1167                //
1168                // States item
1169                //
1170                ////////////////////////////////////////////////////
1171               
1172                updateRenderers: function(obj, stateOnly){
1173                        if(this.currentView){
1174                                this.currentView.updateRenderers(obj, stateOnly);
1175                        }                       
1176                },
1177
1178                getIdentity: function(item){
1179                        return item ? item.id : null;
1180                },
1181
1182                _setHoveredItem: function(item, renderer){                     
1183                        if(this.hoveredItem && item && this.hoveredItem.id != item.id ||
1184                                item == null || this.hoveredItem == null){
1185                                var old = this.hoveredItem;
1186                                this.hoveredItem = item;
1187                               
1188                                this.updateRenderers([old, this.hoveredItem], true);
1189                               
1190                                if(item && renderer){                                   
1191                                        this.currentView._updateEditingCapabilities(item._item ? item._item : item, renderer);
1192                                }
1193                        }
1194                },
1195               
1196                // hoveredItem: Object
1197                //              Current render item which is under the mouse cursor.
1198                hoveredItem: null,
1199               
1200                isItemHovered: function(item){
1201                        // summary:
1202                        //              Returns whether the specified item is hovered or not.
1203                        // item: Object
1204                        //              The item.
1205                        // returns: Boolean                                                             
1206                        return this.hoveredItem != null && this.hoveredItem.id == item.id;                     
1207                },
1208               
1209                ////////////////////////////////////////////////////////////////////////
1210                //
1211                // Editing
1212                //
1213                ////////////////////////////////////////////////////////////////////////
1214
1215                isItemEditable: function(item, rendererKind){
1216                        // summary:
1217                        //              Computes whether particular item renderer can be edited.
1218                        //              By default it is using the editable property value.
1219                        // item: Object
1220                        //              The data item represented by the renderer.
1221                        // rendererKind: String
1222                        //              The kind of renderer.
1223                        // returns: Boolean
1224                        return this.editable;
1225                },
1226               
1227                isItemMoveEnabled: function(item, rendererKind){
1228                        // summary:
1229                        //              Computes whether particular item renderer can be moved.
1230                        //              By default it is using the moveEnabled property value.
1231                        // item: Object
1232                        //              The data item represented by the renderer.
1233                        // rendererKind: String
1234                        //              The kind of renderer.
1235                        // returns: Boolean
1236                        return this.isItemEditable(item, rendererKind) && this.moveEnabled;
1237                },
1238               
1239                isItemResizeEnabled: function(item, rendererKind){
1240                        // summary:
1241                        //              Computes whether particular item renderer can be resized.
1242                        //              By default it is using the resizedEnabled property value.
1243                        // item: Object
1244                        //              The data item represented by the renderer.
1245                        // rendererKind: String
1246                        //              The kind of renderer.
1247                        // returns: Boolean
1248                       
1249                        return this.isItemEditable(item, rendererKind) && this.resizeEnabled;
1250                },
1251               
1252
1253                ////////////////////////////////////////////////////////////////////////
1254                //
1255                // Widget events
1256                //
1257                ////////////////////////////////////////////////////////////////////////
1258               
1259                onGridClick: function(e){
1260                        // summary:
1261                        //              Event dispatched when the grid has been clicked.
1262                        // e: __GridClickEventArgs
1263                        //              The event dispatched when the grid is clicked.
1264                        // tags:
1265                        //              callback
1266
1267                },
1268               
1269                onGridDoubleClick: function(e){
1270                        // summary:
1271                        //              Event dispatched when the grid has been double-clicked.
1272                        // e: __GridClickEventArgs
1273                        //              The event dispatched when the grid is double-clicked.
1274                        // tags:
1275                        //              callback
1276                },     
1277               
1278                onItemClick: function(e){
1279                        // summary:
1280                        //              Event dispatched when an item renderer has been clicked.
1281                        // e: __ItemMouseEventArgs
1282                        //              The event dispatched when an item is clicked.
1283                        // tags:
1284                        //              callback
1285                },
1286               
1287                onItemDoubleClick: function(e){
1288                        // summary:
1289                        //              Event dispatched when an item renderer has been double-clicked.
1290                        // e: __ItemMouseEventArgs
1291                        //              The event dispatched when an item is double-clicked.
1292                        // tags:
1293                        //              callback
1294                },
1295               
1296                onItemContextMenu: function(e){
1297                        // summary:
1298                        //              Event dispatched when an item renderer has been context-clicked.
1299                        // e: __ItemMouseEventArgs
1300                        //              The event dispatched when an item is context-clicked.
1301                        // tags:
1302                        //              callback
1303                },
1304               
1305                onItemEditBegin: function(e){
1306                        // summary:
1307                        //              Event dispatched when the item is entering the editing mode.
1308                        // e: __itemEditingEventArgs
1309                        //              The editing event.
1310                        // tags:
1311                        //              callback
1312                },
1313               
1314                onItemEditEnd: function(e){
1315                        // summary:
1316                        //              Event dispatched when the item is leaving the editing mode.
1317                        // e: __itemEditingEventArgs
1318                        //              The editing event.
1319                        // tags:
1320                        //              callback
1321                },
1322               
1323                onItemEditBeginGesture: function(e){
1324                        // summary:
1325                        //              Event dispatched when an editing gesture is beginning.
1326                        // e: __itemEditingEventArgs
1327                        //              The editing event.
1328                        // tags:
1329                        //              callback
1330                },
1331               
1332                onItemEditMoveGesture: function(e){
1333                        // summary:
1334                        //              Event dispatched during a move editing gesture.         
1335                        // e: __itemEditingEventArgs
1336                        //              The editing event.
1337                        // tags:
1338                        //              callback
1339                },
1340               
1341                onItemEditResizeGesture: function(e){
1342                        // summary:
1343                        //              Event dispatched during a resize editing gesture.
1344                        // e: __itemEditingEventArgs
1345                        //              The editing event.
1346                        // tags:
1347                        //              callback
1348                },
1349               
1350                onItemEditEndGesture: function(e){
1351                        // summary:
1352                        //              Event dispatched at the end of an editing gesture.
1353                        // e: __itemEditingEventArgs
1354                        //              The editing event.
1355                        // tags:
1356                        //              callback
1357                },
1358               
1359                onItemRollOver: function(e){
1360                        // Summary:
1361                        //              Event dispatched when the mouse cursor in going over an item renderer.
1362                        // e: __ItemMouseEventArgs
1363                        //              The event dispatched when the mouse cursor enters in the item renderer.
1364                        // tags:
1365                        //              callback
1366                },
1367               
1368                onItemRollOut: function(e){
1369                        // Summary:
1370                        //              Event dispatched when the mouse cursor in leaving an item renderer.
1371                        // e: __ItemMouseEventArgs
1372                        //              The event dispatched when the mouse cursor enters in the item renderer.
1373                        // tags:
1374                        //              callback
1375                },
1376               
1377                onColumnHeaderClick: function(e){
1378                        // summary:
1379                        //              Event dispatched when a column header cell is dispatched.
1380                        // e: __HeaderClickEventArgs
1381                        //              Header click event.
1382                        // tags:
1383                        //              callback
1384                },
1385                               
1386                onRowHeaderClick: function(e){
1387                        // summary:
1388                        //              Event dispatched when a row header cell is clicked.
1389                        // e: __HeaderClickEventArgs
1390                        //              Header click event.
1391                        // tags:
1392                        //              callback
1393                },
1394               
1395                onExpandRendererClick: function(e){
1396                        // summary:
1397                        //              Event dispatched when an expand renderer is clicked.
1398                        // e: __ExpandRendererClickEventArgs
1399                        //              Expand renderer click event.
1400                        // tags:
1401                        //              callback
1402                },
1403               
1404                _onRendererCreated: function(e){
1405                        this.onRendererCreated(e);
1406                },
1407               
1408                onRendererCreated: function(e){
1409                        // summary:
1410                        //              Event dispatched when an item renderer has been created.
1411                        // e: __rendererLifecycleEventArgs
1412                        //              The renderer lifecycle event.
1413                        // tags:
1414                        //              callback
1415                },
1416               
1417                _onRendererRecycled: function(e){
1418                        this.onRendererRecycled(e);
1419                },
1420               
1421                onRendererRecycled: function(e){
1422                        // summary:
1423                        //              Event dispatched when an item renderer has been recycled.
1424                        // e: __rendererLifecycleEventArgs
1425                        //              The renderer lifecycle event.
1426                        // tags:
1427                        //              callback
1428                },
1429               
1430                _onRendererReused: function(e){
1431                        this.onRendererReused(e);
1432                },
1433               
1434                onRendererReused: function(e){
1435                        // summary:
1436                        //              Event dispatched when an item renderer that was recycled is reused.
1437                        // e: __rendererLifecycleEventArgs
1438                        //              The renderer lifecycle event.
1439                        // tags:
1440                        //              callback
1441                },
1442               
1443                _onRendererDestroyed: function(e){
1444                        this.onRendererDestroyed(e);
1445                },
1446               
1447                onRendererDestroyed: function(e){
1448                        // summary:
1449                        //              Event dispatched when an item renderer is destroyed.
1450                        // e: __rendererLifecycleEventArgs
1451                        //              The renderer lifecycle event.
1452                        // tags:
1453                        //              callback
1454                },
1455               
1456                _onRenderersLayoutDone: function(view){
1457                        this.onRenderersLayoutDone(view);
1458                },
1459               
1460                onRenderersLayoutDone: function(view){
1461                        // summary:
1462                        //              Event triggered when item renderers layout has been done.
1463                        // view: dojox/calendar/ViewBase
1464                        //              The view that has been laid-out.
1465                        // tags:
1466                        //              callback
1467                }
1468
1469        });
1470});
Note: See TracBrowser for help on using the repository browser.