Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / docs / source / CalendarPanel.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 <div id="cls-Ext.calendar.CalendarPanel"></div>/**
16  * @class Ext.calendar.CalendarPanel
17  * @extends Ext.Panel
18  * <p>This is the default container for Ext calendar views. It supports day, week and month views as well
19  * as a built-in event edit form. The only requirement for displaying a calendar is passing in a valid
20  * {@link #calendarStore} config containing records of type {@link Ext.calendar.EventRecord EventRecord}. In order
21  * to make the calendar interactive (enable editing, drag/drop, etc.) you can handle any of the various
22  * events fired by the underlying views and exposed through the CalendarPanel.</p>
23  * {@link #layoutConfig} option if needed.</p>
24  * @constructor
25  * @param {Object} config The config object
26  * @xtype calendarpanel
27  */
28 Ext.calendar.CalendarPanel = Ext.extend(Ext.Panel, {
29     <div id="cfg-Ext.calendar.CalendarPanel-showDayView"></div>/**
30      * @cfg {Boolean} showDayView
31      * True to include the day view (and toolbar button), false to hide them (defaults to true).
32      */
33     showDayView: true,
34     <div id="cfg-Ext.calendar.CalendarPanel-showWeekView"></div>/**
35      * @cfg {Boolean} showWeekView
36      * True to include the week view (and toolbar button), false to hide them (defaults to true).
37      */
38     showWeekView: true,
39     <div id="cfg-Ext.calendar.CalendarPanel-showMonthView"></div>/**
40      * @cfg {Boolean} showMonthView
41      * True to include the month view (and toolbar button), false to hide them (defaults to true).
42      * If the day and week views are both hidden, the month view will show by default even if
43      * this config is false.
44      */
45     showMonthView: true,
46     <div id="cfg-Ext.calendar.CalendarPanel-showNavBar"></div>/**
47      * @cfg {Boolean} showNavBar
48      * True to display the calendar navigation toolbar, false to hide it (defaults to true). Note that
49      * if you hide the default navigation toolbar you'll have to provide an alternate means of navigating the calendar.
50      */
51     showNavBar: true,
52     <div id="cfg-Ext.calendar.CalendarPanel-todayText"></div>/**
53      * @cfg {String} todayText
54      * Alternate text to use for the 'Today' nav bar button.
55      */
56     todayText: 'Today',
57     <div id="cfg-Ext.calendar.CalendarPanel-showTodayText"></div>/**
58      * @cfg {Boolean} showTodayText
59      * True to show the value of {@link #todayText} instead of today's date in the calendar's current day box,
60      * false to display the day number(defaults to true).
61      */
62     showTodayText: true,
63     <div id="cfg-Ext.calendar.CalendarPanel-showTime"></div>/**
64      * @cfg {Boolean} showTime
65      * True to display the current time next to the date in the calendar's current day box, false to not show it 
66      * (defaults to true).
67      */
68     showTime: true,
69     <div id="cfg-Ext.calendar.CalendarPanel-dayText"></div>/**
70      * @cfg {String} dayText
71      * Alternate text to use for the 'Day' nav bar button.
72      */
73     dayText: 'Day',
74     <div id="cfg-Ext.calendar.CalendarPanel-weekText"></div>/**
75      * @cfg {String} weekText
76      * Alternate text to use for the 'Week' nav bar button.
77      */
78     weekText: 'Week',
79     <div id="cfg-Ext.calendar.CalendarPanel-monthText"></div>/**
80      * @cfg {String} monthText
81      * Alternate text to use for the 'Month' nav bar button.
82      */
83     monthText: 'Month',
84
85     // private
86     layoutConfig: {
87         layoutOnCardChange: true,
88         deferredRender: true
89     },
90
91     // private property
92     startDate: new Date(),
93
94     // private
95     initComponent: function() {
96         this.tbar = {
97             cls: 'ext-cal-toolbar',
98             border: true,
99             buttonAlign: 'center',
100             items: [{
101                 id: this.id + '-tb-prev',
102                 handler: this.onPrevClick,
103                 scope: this,
104                 iconCls: 'x-tbar-page-prev'
105             }]
106         };
107
108         this.viewCount = 0;
109
110         if (this.showDayView) {
111             this.tbar.items.push({
112                 id: this.id + '-tb-day',
113                 text: this.dayText,
114                 handler: this.onDayClick,
115                 scope: this,
116                 toggleGroup: 'tb-views'
117             });
118             this.viewCount++;
119         }
120         if (this.showWeekView) {
121             this.tbar.items.push({
122                 id: this.id + '-tb-week',
123                 text: this.weekText,
124                 handler: this.onWeekClick,
125                 scope: this,
126                 toggleGroup: 'tb-views'
127             });
128             this.viewCount++;
129         }
130         if (this.showMonthView || this.viewCount == 0) {
131             this.tbar.items.push({
132                 id: this.id + '-tb-month',
133                 text: this.monthText,
134                 handler: this.onMonthClick,
135                 scope: this,
136                 toggleGroup: 'tb-views'
137             });
138             this.viewCount++;
139             this.showMonthView = true;
140         }
141         this.tbar.items.push({
142             id: this.id + '-tb-next',
143             handler: this.onNextClick,
144             scope: this,
145             iconCls: 'x-tbar-page-next'
146         });
147         this.tbar.items.push('->');
148
149         var idx = this.viewCount - 1;
150         this.activeItem = this.activeItem === undefined ? idx: (this.activeItem > idx ? idx: this.activeItem);
151
152         if (this.showNavBar === false) {
153             delete this.tbar;
154             this.addClass('x-calendar-nonav');
155         }
156
157         Ext.calendar.CalendarPanel.superclass.initComponent.call(this);
158
159         this.addEvents({
160             <div id="event-Ext.calendar.CalendarPanel-eventadd"></div>/**
161              * @event eventadd
162              * Fires after a new event is added to the underlying store
163              * @param {Ext.calendar.CalendarPanel} this
164              * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was added
165              */
166             eventadd: true,
167             <div id="event-Ext.calendar.CalendarPanel-eventupdate"></div>/**
168              * @event eventupdate
169              * Fires after an existing event is updated
170              * @param {Ext.calendar.CalendarPanel} this
171              * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was updated
172              */
173             eventupdate: true,
174             <div id="event-Ext.calendar.CalendarPanel-eventdelete"></div>/**
175              * @event eventdelete
176              * Fires after an event is removed from the underlying store
177              * @param {Ext.calendar.CalendarPanel} this
178              * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was removed
179              */
180             eventdelete: true,
181             <div id="event-Ext.calendar.CalendarPanel-eventcancel"></div>/**
182              * @event eventcancel
183              * Fires after an event add/edit operation is canceled by the user and no store update took place
184              * @param {Ext.calendar.CalendarPanel} this
185              * @param {Ext.calendar.EventRecord} rec The new {@link Ext.calendar.EventRecord record} that was canceled
186              */
187             eventcancel: true,
188             <div id="event-Ext.calendar.CalendarPanel-viewchange"></div>/**
189              * @event viewchange
190              * Fires after a different calendar view is activated (but not when the event edit form is activated)
191              * @param {Ext.calendar.CalendarPanel} this
192              * @param {Ext.CalendarView} view The view being activated (any valid {@link Ext.calendar.CalendarView CalendarView} subclass)
193              * @param {Object} info Extra information about the newly activated view. This is a plain object 
194              * with following properties:<div class="mdetail-params"><ul>
195              * <li><b><code>activeDate</code></b> : <div class="sub-desc">The currently-selected date</div></li>
196              * <li><b><code>viewStart</code></b> : <div class="sub-desc">The first date in the new view range</div></li>
197              * <li><b><code>viewEnd</code></b> : <div class="sub-desc">The last date in the new view range</div></li>
198              * </ul></div>
199              */
200             viewchange: true
201
202             //
203             // NOTE: CalendarPanel also relays the following events from contained views as if they originated from this:
204             //
205             <div id="event-Ext.calendar.CalendarPanel-eventsrendered"></div>/**
206              * @event eventsrendered
207              * Fires after events are finished rendering in the view
208              * @param {Ext.calendar.CalendarPanel} this 
209              */
210             <div id="event-Ext.calendar.CalendarPanel-eventclick"></div>/**
211              * @event eventclick
212              * Fires after the user clicks on an event element
213              * @param {Ext.calendar.CalendarPanel} this
214              * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was clicked on
215              * @param {HTMLNode} el The DOM node that was clicked on
216              */
217             <div id="event-Ext.calendar.CalendarPanel-eventover"></div>/**
218              * @event eventover
219              * Fires anytime the mouse is over an event element
220              * @param {Ext.calendar.CalendarPanel} this
221              * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor is over
222              * @param {HTMLNode} el The DOM node that is being moused over
223              */
224             <div id="event-Ext.calendar.CalendarPanel-eventout"></div>/**
225              * @event eventout
226              * Fires anytime the mouse exits an event element
227              * @param {Ext.calendar.CalendarPanel} this
228              * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that the cursor exited
229              * @param {HTMLNode} el The DOM node that was exited
230              */
231             <div id="event-Ext.calendar.CalendarPanel-datechange"></div>/**
232              * @event datechange
233              * Fires after the start date of the view changes
234              * @param {Ext.calendar.CalendarPanel} this
235              * @param {Date} startDate The start date of the view (as explained in {@link #getStartDate}
236              * @param {Date} viewStart The first displayed date in the view
237              * @param {Date} viewEnd The last displayed date in the view
238              */
239             <div id="event-Ext.calendar.CalendarPanel-rangeselect"></div>/**
240              * @event rangeselect
241              * Fires after the user drags on the calendar to select a range of dates/times in which to create an event
242              * @param {Ext.calendar.CalendarPanel} this
243              * @param {Object} dates An object containing the start (StartDate property) and end (EndDate property) dates selected
244              * @param {Function} callback A callback function that MUST be called after the event handling is complete so that
245              * the view is properly cleaned up (shim elements are persisted in the view while the user is prompted to handle the
246              * range selection). The callback is already created in the proper scope, so it simply needs to be executed as a standard
247              * function call (e.g., callback()).
248              */
249             <div id="event-Ext.calendar.CalendarPanel-eventmove"></div>/**
250              * @event eventmove
251              * Fires after an event element is dragged by the user and dropped in a new position
252              * @param {Ext.calendar.CalendarPanel} this
253              * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was moved with
254              * updated start and end dates
255              */
256             <div id="event-Ext.calendar.CalendarPanel-initdrag"></div>/**
257              * @event initdrag
258              * Fires when a drag operation is initiated in the view
259              * @param {Ext.calendar.CalendarPanel} this
260              */
261             <div id="event-Ext.calendar.CalendarPanel-eventresize"></div>/**
262              * @event eventresize
263              * Fires after the user drags the resize handle of an event to resize it
264              * @param {Ext.calendar.CalendarPanel} this
265              * @param {Ext.calendar.EventRecord} rec The {@link Ext.calendar.EventRecord record} for the event that was resized
266              * containing the updated start and end dates
267              */
268             <div id="event-Ext.calendar.CalendarPanel-dayclick"></div>/**
269              * @event dayclick
270              * Fires after the user clicks within a day/week view container and not on an event element
271              * @param {Ext.calendar.CalendarPanel} this
272              * @param {Date} dt The date/time that was clicked on
273              * @param {Boolean} allday True if the day clicked on represents an all-day box, else false.
274              * @param {Ext.Element} el The Element that was clicked on
275              */
276         });
277
278         this.layout = 'card';
279         // do not allow override
280         if (this.showDayView) {
281             var day = Ext.apply({
282                 xtype: 'dayview',
283                 title: this.dayText,
284                 showToday: this.showToday,
285                 showTodayText: this.showTodayText,
286                 showTime: this.showTime
287             },
288             this.dayViewCfg);
289
290             day.id = this.id + '-day';
291             day.store = day.store || this.eventStore;
292             this.initEventRelay(day);
293             this.add(day);
294         }
295         if (this.showWeekView) {
296             var wk = Ext.applyIf({
297                 xtype: 'weekview',
298                 title: this.weekText,
299                 showToday: this.showToday,
300                 showTodayText: this.showTodayText,
301                 showTime: this.showTime
302             },
303             this.weekViewCfg);
304
305             wk.id = this.id + '-week';
306             wk.store = wk.store || this.eventStore;
307             this.initEventRelay(wk);
308             this.add(wk);
309         }
310         if (this.showMonthView) {
311             var month = Ext.applyIf({
312                 xtype: 'monthview',
313                 title: this.monthText,
314                 showToday: this.showToday,
315                 showTodayText: this.showTodayText,
316                 showTime: this.showTime,
317                 listeners: {
318                     'weekclick': {
319                         fn: function(vw, dt) {
320                             this.showWeek(dt);
321                         },
322                         scope: this
323                     }
324                 }
325             },
326             this.monthViewCfg);
327
328             month.id = this.id + '-month';
329             month.store = month.store || this.eventStore;
330             this.initEventRelay(month);
331             this.add(month);
332         }
333
334         this.add(Ext.applyIf({
335             xtype: 'eventeditform',
336             id: this.id + '-edit',
337             calendarStore: this.calendarStore,
338             listeners: {
339                 'eventadd': {
340                     scope: this,
341                     fn: this.onEventAdd
342                 },
343                 'eventupdate': {
344                     scope: this,
345                     fn: this.onEventUpdate
346                 },
347                 'eventdelete': {
348                     scope: this,
349                     fn: this.onEventDelete
350                 },
351                 'eventcancel': {
352                     scope: this,
353                     fn: this.onEventCancel
354                 }
355             }
356         },
357         this.editViewCfg));
358     },
359
360     // private
361     initEventRelay: function(cfg) {
362         cfg.listeners = cfg.listeners || {};
363         cfg.listeners.afterrender = {
364             fn: function(c) {
365                 // relay the view events so that app code only has to handle them in one place
366                 this.relayEvents(c, ['eventsrendered', 'eventclick', 'eventover', 'eventout', 'dayclick',
367                 'eventmove', 'datechange', 'rangeselect', 'eventdelete', 'eventresize', 'initdrag']);
368             },
369             scope: this,
370             single: true
371         };
372     },
373
374     // private
375     afterRender: function() {
376         Ext.calendar.CalendarPanel.superclass.afterRender.call(this);
377         this.fireViewChange();
378     },
379
380     // private
381     onLayout: function() {
382         Ext.calendar.CalendarPanel.superclass.onLayout.call(this);
383         if (!this.navInitComplete) {
384             this.updateNavState();
385             this.navInitComplete = true;
386         }
387     },
388
389     // private
390     onEventAdd: function(form, rec) {
391         rec.data[Ext.calendar.EventMappings.IsNew.name] = false;
392         this.eventStore.add(rec);
393         this.hideEditForm();
394         this.fireEvent('eventadd', this, rec);
395     },
396
397     // private
398     onEventUpdate: function(form, rec) {
399         rec.commit();
400         this.hideEditForm();
401         this.fireEvent('eventupdate', this, rec);
402     },
403
404     // private
405     onEventDelete: function(form, rec) {
406         this.eventStore.remove(rec);
407         this.hideEditForm();
408         this.fireEvent('eventdelete', this, rec);
409     },
410
411     // private
412     onEventCancel: function(form, rec) {
413         this.hideEditForm();
414         this.fireEvent('eventcancel', this, rec);
415     },
416
417     <div id="method-Ext.calendar.CalendarPanel-showEditForm"></div>/**
418      * Shows the built-in event edit form for the passed in event record.  This method automatically
419      * hides the calendar views and navigation toolbar.  To return to the calendar, call {@link #hideEditForm}.
420      * @param {Ext.calendar.EventRecord} record The event record to edit
421      * @return {Ext.calendar.CalendarPanel} this
422      */
423     showEditForm: function(rec) {
424         this.preEditView = this.layout.activeItem.id;
425         this.setActiveView(this.id + '-edit');
426         this.layout.activeItem.loadRecord(rec);
427         return this;
428     },
429
430     <div id="method-Ext.calendar.CalendarPanel-hideEditForm"></div>/**
431      * Hides the built-in event edit form and returns to the previous calendar view. If the edit form is
432      * not currently visible this method has no effect.
433      * @return {Ext.calendar.CalendarPanel} this
434      */
435     hideEditForm: function() {
436         if (this.preEditView) {
437             this.setActiveView(this.preEditView);
438             delete this.preEditView;
439         }
440         return this;
441     },
442
443     // private
444     setActiveView: function(id) {
445         var l = this.layout;
446         l.setActiveItem(id);
447
448         if (id == this.id + '-edit') {
449             this.getTopToolbar().hide();
450             this.doLayout();
451         }
452         else {
453             l.activeItem.refresh();
454             this.getTopToolbar().show();
455             this.updateNavState();
456         }
457         this.activeView = l.activeItem;
458         this.fireViewChange();
459     },
460
461     // private
462     fireViewChange: function() {
463         var info = null,
464             view = this.layout.activeItem;
465
466         if (view.getViewBounds) {
467             vb = view.getViewBounds();
468             info = {
469                 activeDate: view.getStartDate(),
470                 viewStart: vb.start,
471                 viewEnd: vb.end
472             };
473         };
474         this.fireEvent('viewchange', this, view, info);
475     },
476
477     // private
478     updateNavState: function() {
479         if (this.showNavBar !== false) {
480             var item = this.layout.activeItem,
481             suffix = item.id.split(this.id + '-')[1];
482
483             var btn = Ext.getCmp(this.id + '-tb-' + suffix);
484             btn.toggle(true);
485         }
486     },
487
488     <div id="method-Ext.calendar.CalendarPanel-setStartDate"></div>/**
489      * Sets the start date for the currently-active calendar view.
490      * @param {Date} dt
491      */
492     setStartDate: function(dt) {
493         this.layout.activeItem.setStartDate(dt, true);
494         this.updateNavState();
495         this.fireViewChange();
496     },
497
498     // private
499     showWeek: function(dt) {
500         this.setActiveView(this.id + '-week');
501         this.setStartDate(dt);
502     },
503
504     // private
505     onPrevClick: function() {
506         this.startDate = this.layout.activeItem.movePrev();
507         this.updateNavState();
508         this.fireViewChange();
509     },
510
511     // private
512     onNextClick: function() {
513         this.startDate = this.layout.activeItem.moveNext();
514         this.updateNavState();
515         this.fireViewChange();
516     },
517
518     // private
519     onDayClick: function() {
520         this.setActiveView(this.id + '-day');
521     },
522
523     // private
524     onWeekClick: function() {
525         this.setActiveView(this.id + '-week');
526     },
527
528     // private
529     onMonthClick: function() {
530         this.setActiveView(this.id + '-month');
531     },
532
533     <div id="method-Ext.calendar.CalendarPanel-getActiveView"></div>/**
534      * Return the calendar view that is currently active, which will be a subclass of
535      * {@link Ext.calendar.CalendarView CalendarView}.
536      * @return {Ext.calendar.CalendarView} The active view
537      */
538     getActiveView: function() {
539         return this.layout.activeItem;
540     }
541 });
542
543 Ext.reg('calendarpanel', Ext.calendar.CalendarPanel);</pre>    
544 </body>
545 </html>