Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / docs / source / MonthView.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.MonthView"></div>/**\r
16  * @class Ext.calendar.MonthView\r
17  * @extends Ext.calendar.CalendarView\r
18  * <p>Displays a calendar view by month. This class does not usually need ot be used directly as you can\r
19  * use a {@link Ext.calendar.CalendarPanel CalendarPanel} to manage multiple calendar views at once including\r
20  * the month view.</p>\r
21  * @constructor\r
22  * @param {Object} config The config object\r
23  */\r
24 Ext.calendar.MonthView = Ext.extend(Ext.calendar.CalendarView, {\r
25     <div id="cfg-Ext.calendar.MonthView-showTime"></div>/**\r
26      * @cfg {Boolean} showTime\r
27      * True to display the current time in today's box in the calendar, false to not display it (defautls to true)\r
28      */\r
29     showTime: true,\r
30     <div id="cfg-Ext.calendar.MonthView-showTodayText"></div>/**\r
31      * @cfg {Boolean} showTodayText\r
32      * True to display the {@link #todayText} string in today's box in the calendar, false to not display it (defautls to true)\r
33      */\r
34     showTodayText: true,\r
35     <div id="cfg-Ext.calendar.MonthView-todayText"></div>/**\r
36      * @cfg {String} todayText\r
37      * The text to display in the current day's box in the calendar when {@link #showTodayText} is true (defaults to 'Today')\r
38      */\r
39     todayText: 'Today',\r
40     <div id="cfg-Ext.calendar.MonthView-showHeader"></div>/**\r
41      * @cfg {Boolean} showHeader\r
42      * True to display a header beneath the navigation bar containing the week names above each week's column, false not to \r
43      * show it and instead display the week names in the first row of days in the calendar (defaults to false).\r
44      */\r
45     showHeader: false,\r
46     <div id="cfg-Ext.calendar.MonthView-showWeekLinks"></div>/**\r
47      * @cfg {Boolean} showWeekLinks\r
48      * True to display an extra column before the first day in the calendar that links to the {@link Ext.calendar.WeekView view}\r
49      * for each individual week, false to not show it (defaults to false). If true, the week links can also contain the week \r
50      * number depending on the value of {@link #showWeekNumbers}.\r
51      */\r
52     showWeekLinks: false,\r
53     <div id="cfg-Ext.calendar.MonthView-showWeekNumbers"></div>/**\r
54      * @cfg {Boolean} showWeekNumbers\r
55      * True to show the week number for each week in the calendar in the week link column, false to show nothing (defaults to false).\r
56      * Note that if {@link #showWeekLinks} is false this config will have no affect even if true.\r
57      */\r
58     showWeekNumbers: false,\r
59     <div id="cfg-Ext.calendar.MonthView-weekLinkOverClass"></div>/**\r
60      * @cfg {String} weekLinkOverClass\r
61      * The CSS class name applied when the mouse moves over a week link element (only applies when {@link #showWeekLinks} is true,\r
62      * defaults to 'ext-week-link-over').\r
63      */\r
64     weekLinkOverClass: 'ext-week-link-over',\r
65 \r
66     //private properties -- do not override:\r
67     daySelector: '.ext-cal-day',\r
68     moreSelector: '.ext-cal-ev-more',\r
69     weekLinkSelector: '.ext-cal-week-link',\r
70     weekCount: -1,\r
71     // defaults to auto by month\r
72     dayCount: 7,\r
73     moreElIdDelimiter: '-more-',\r
74     weekLinkIdDelimiter: 'ext-cal-week-',\r
75 \r
76     // private\r
77     initComponent: function() {\r
78         Ext.calendar.MonthView.superclass.initComponent.call(this);\r
79         this.addEvents({\r
80             <div id="event-Ext.calendar.MonthView-dayclick"></div>/**\r
81              * @event dayclick\r
82              * Fires after the user clicks within the view container and not on an event element\r
83              * @param {Ext.calendar.MonthView} this\r
84              * @param {Date} dt The date/time that was clicked on\r
85              * @param {Boolean} allday True if the day clicked on represents an all-day box, else false. Clicks within the \r
86              * MonthView always return true for this param.\r
87              * @param {Ext.Element} el The Element that was clicked on\r
88              */\r
89             dayclick: true,\r
90             <div id="event-Ext.calendar.MonthView-weekclick"></div>/**\r
91              * @event weekclick\r
92              * Fires after the user clicks within a week link (when {@link #showWeekLinks is true)\r
93              * @param {Ext.calendar.MonthView} this\r
94              * @param {Date} dt The start date of the week that was clicked on\r
95              */\r
96             weekclick: true,\r
97             // inherited docs\r
98             dayover: true,\r
99             // inherited docs\r
100             dayout: true\r
101         });\r
102     },\r
103 \r
104     // private\r
105     initDD: function() {\r
106         var cfg = {\r
107             view: this,\r
108             createText: this.ddCreateEventText,\r
109             moveText: this.ddMoveEventText,\r
110             ddGroup: 'MonthViewDD'\r
111         };\r
112 \r
113         this.dragZone = new Ext.calendar.DragZone(this.el, cfg);\r
114         this.dropZone = new Ext.calendar.DropZone(this.el, cfg);\r
115     },\r
116 \r
117     // private\r
118     onDestroy: function() {\r
119         Ext.destroy(this.ddSelector);\r
120         Ext.destroy(this.dragZone);\r
121         Ext.destroy(this.dropZone);\r
122         Ext.calendar.MonthView.superclass.onDestroy.call(this);\r
123     },\r
124 \r
125     // private\r
126     afterRender: function() {\r
127         if (!this.tpl) {\r
128             this.tpl = new Ext.calendar.MonthViewTemplate({\r
129                 id: this.id,\r
130                 showTodayText: this.showTodayText,\r
131                 todayText: this.todayText,\r
132                 showTime: this.showTime,\r
133                 showHeader: this.showHeader,\r
134                 showWeekLinks: this.showWeekLinks,\r
135                 showWeekNumbers: this.showWeekNumbers\r
136             });\r
137         }\r
138         this.tpl.compile();\r
139         this.addClass('ext-cal-monthview ext-cal-ct');\r
140 \r
141         Ext.calendar.MonthView.superclass.afterRender.call(this);\r
142     },\r
143 \r
144     // private\r
145     onResize: function() {\r
146         if (this.monitorResize) {\r
147             this.maxEventsPerDay = this.getMaxEventsPerDay();\r
148             this.refresh();\r
149         }\r
150     },\r
151 \r
152     // private\r
153     forceSize: function() {\r
154         // Compensate for the week link gutter width if visible\r
155         if (this.showWeekLinks && this.el && this.el.child) {\r
156             var hd = this.el.select('.ext-cal-hd-days-tbl'),\r
157             bgTbl = this.el.select('.ext-cal-bg-tbl'),\r
158             evTbl = this.el.select('.ext-cal-evt-tbl'),\r
159             wkLinkW = this.el.child('.ext-cal-week-link').getWidth(),\r
160             w = this.el.getWidth() - wkLinkW;\r
161 \r
162             hd.setWidth(w);\r
163             bgTbl.setWidth(w);\r
164             evTbl.setWidth(w);\r
165         }\r
166         Ext.calendar.MonthView.superclass.forceSize.call(this);\r
167     },\r
168 \r
169     //private\r
170     initClock: function() {\r
171         if (Ext.fly(this.id + '-clock') !== null) {\r
172             this.prevClockDay = new Date().getDay();\r
173             if (this.clockTask) {\r
174                 Ext.TaskMgr.stop(this.clockTask);\r
175             }\r
176             this.clockTask = Ext.TaskMgr.start({\r
177                 run: function() {\r
178                     var el = Ext.fly(this.id + '-clock'),\r
179                     t = new Date();\r
180 \r
181                     if (t.getDay() == this.prevClockDay) {\r
182                         if (el) {\r
183                             el.update(t.format('g:i a'));\r
184                         }\r
185                     }\r
186                     else {\r
187                         this.prevClockDay = t.getDay();\r
188                         this.moveTo(t);\r
189                     }\r
190                 },\r
191                 scope: this,\r
192                 interval: 1000\r
193             });\r
194         }\r
195     },\r
196 \r
197     // inherited docs\r
198     getEventBodyMarkup: function() {\r
199         if (!this.eventBodyMarkup) {\r
200             this.eventBodyMarkup = ['{Title}',\r
201             '<tpl if="_isReminder">',\r
202             '<i class="ext-cal-ic ext-cal-ic-rem">&nbsp;</i>',\r
203             '</tpl>',\r
204             '<tpl if="_isRecurring">',\r
205             '<i class="ext-cal-ic ext-cal-ic-rcr">&nbsp;</i>',\r
206             '</tpl>',\r
207             '<tpl if="spanLeft">',\r
208             '<i class="ext-cal-spl">&nbsp;</i>',\r
209             '</tpl>',\r
210             '<tpl if="spanRight">',\r
211             '<i class="ext-cal-spr">&nbsp;</i>',\r
212             '</tpl>'\r
213             ].join('');\r
214         }\r
215         return this.eventBodyMarkup;\r
216     },\r
217 \r
218     // inherited docs\r
219     getEventTemplate: function() {\r
220         if (!this.eventTpl) {\r
221             var tpl,\r
222             body = this.getEventBodyMarkup();\r
223 \r
224             tpl = !(Ext.isIE || Ext.isOpera) ?\r
225             new Ext.XTemplate(\r
226             '<div id="{_elId}" class="{_selectorCls} {_colorCls} {values.spanCls} ext-cal-evt ext-cal-evr">',\r
227             body,\r
228             '</div>'\r
229             )\r
230             : new Ext.XTemplate(\r
231             '<tpl if="_renderAsAllDay">',\r
232             '<div id="{_elId}" class="{_selectorCls} {values.spanCls} {_colorCls} ext-cal-evt ext-cal-evo">',\r
233             '<div class="ext-cal-evm">',\r
234             '<div class="ext-cal-evi">',\r
235             '</tpl>',\r
236             '<tpl if="!_renderAsAllDay">',\r
237             '<div id="{_elId}" class="{_selectorCls} {_colorCls} ext-cal-evt ext-cal-evr">',\r
238             '</tpl>',\r
239             body,\r
240             '<tpl if="_renderAsAllDay">',\r
241             '</div>',\r
242             '</div>',\r
243             '</tpl>',\r
244             '</div>'\r
245             );\r
246             tpl.compile();\r
247             this.eventTpl = tpl;\r
248         }\r
249         return this.eventTpl;\r
250     },\r
251 \r
252     // private\r
253     getTemplateEventData: function(evt) {\r
254         var M = Ext.calendar.EventMappings,\r
255         selector = this.getEventSelectorCls(evt[M.EventId.name]),\r
256         title = evt[M.Title.name];\r
257 \r
258         return Ext.applyIf({\r
259             _selectorCls: selector,\r
260             _colorCls: 'ext-color-' + (evt[M.CalendarId.name] ?\r
261             evt[M.CalendarId.name] : 'default') + (evt._renderAsAllDay ? '-ad': ''),\r
262             _elId: selector + '-' + evt._weekIndex,\r
263             _isRecurring: evt.Recurrence && evt.Recurrence != '',\r
264             _isReminder: evt[M.Reminder.name] && evt[M.Reminder.name] != '',\r
265             Title: (evt[M.IsAllDay.name] ? '': evt[M.StartDate.name].format('g:ia ')) + (!title || title.length == 0 ? '(No title)': title)\r
266         },\r
267         evt);\r
268     },\r
269 \r
270     // private\r
271     refresh: function() {\r
272         if (this.detailPanel) {\r
273             this.detailPanel.hide();\r
274         }\r
275         Ext.calendar.MonthView.superclass.refresh.call(this);\r
276 \r
277         if (this.showTime !== false) {\r
278             this.initClock();\r
279         }\r
280     },\r
281 \r
282     // private\r
283     renderItems: function() {\r
284         Ext.calendar.WeekEventRenderer.render({\r
285             eventGrid: this.allDayOnly ? this.allDayGrid: this.eventGrid,\r
286             viewStart: this.viewStart,\r
287             tpl: this.getEventTemplate(),\r
288             maxEventsPerDay: this.maxEventsPerDay,\r
289             id: this.id,\r
290             templateDataFn: this.getTemplateEventData.createDelegate(this),\r
291             evtMaxCount: this.evtMaxCount,\r
292             weekCount: this.weekCount,\r
293             dayCount: this.dayCount\r
294         });\r
295         this.fireEvent('eventsrendered', this);\r
296     },\r
297 \r
298     // private\r
299     getDayEl: function(dt) {\r
300         return Ext.get(this.getDayId(dt));\r
301     },\r
302 \r
303     // private\r
304     getDayId: function(dt) {\r
305         if (Ext.isDate(dt)) {\r
306             dt = dt.format('Ymd');\r
307         }\r
308         return this.id + this.dayElIdDelimiter + dt;\r
309     },\r
310 \r
311     // private\r
312     getWeekIndex: function(dt) {\r
313         var el = this.getDayEl(dt).up('.ext-cal-wk-ct');\r
314         return parseInt(el.id.split('-wk-')[1], 10);\r
315     },\r
316 \r
317     // private\r
318     getDaySize: function(contentOnly) {\r
319         var box = this.el.getBox(),\r
320         w = box.width / this.dayCount,\r
321         h = box.height / this.getWeekCount();\r
322 \r
323         if (contentOnly) {\r
324             var hd = this.el.select('.ext-cal-dtitle').first().parent('tr');\r
325             h = hd ? h - hd.getHeight(true) : h;\r
326         }\r
327         return {\r
328             height: h,\r
329             width: w\r
330         };\r
331     },\r
332 \r
333     // private\r
334     getEventHeight: function() {\r
335         if (!this.eventHeight) {\r
336             var evt = this.el.select('.ext-cal-evt').first();\r
337             this.eventHeight = evt ? evt.parent('tr').getHeight() : 18;\r
338         }\r
339         return this.eventHeight;\r
340     },\r
341 \r
342     // private\r
343     getMaxEventsPerDay: function() {\r
344         var dayHeight = this.getDaySize(true).height,\r
345             h = this.getEventHeight(),\r
346             max = Math.max(Math.floor((dayHeight - h) / h), 0);\r
347 \r
348         return max;\r
349     },\r
350 \r
351     // private\r
352     getDayAt: function(x, y) {\r
353         var box = this.el.getBox(),\r
354             daySize = this.getDaySize(),\r
355             dayL = Math.floor(((x - box.x) / daySize.width)),\r
356             dayT = Math.floor(((y - box.y) / daySize.height)),\r
357             days = (dayT * 7) + dayL,\r
358             dt = this.viewStart.add(Date.DAY, days);\r
359         return {\r
360             date: dt,\r
361             el: this.getDayEl(dt)\r
362         };\r
363     },\r
364 \r
365     // inherited docs\r
366     moveNext: function() {\r
367         return this.moveMonths(1);\r
368     },\r
369 \r
370     // inherited docs\r
371     movePrev: function() {\r
372         return this.moveMonths( - 1);\r
373     },\r
374 \r
375     // private\r
376     onInitDrag: function() {\r
377         Ext.calendar.MonthView.superclass.onInitDrag.call(this);\r
378         Ext.select(this.daySelector).removeClass(this.dayOverClass);\r
379         if (this.detailPanel) {\r
380             this.detailPanel.hide();\r
381         }\r
382     },\r
383 \r
384     // private\r
385     onMoreClick: function(dt) {\r
386         if (!this.detailPanel) {\r
387             this.detailPanel = new Ext.Panel({\r
388                 id: this.id + '-details-panel',\r
389                 title: dt.format('F j'),\r
390                 layout: 'fit',\r
391                 floating: true,\r
392                 renderTo: Ext.getBody(),\r
393                 tools: [{\r
394                     id: 'close',\r
395                     handler: function(e, t, p) {\r
396                         p.hide();\r
397                     }\r
398                 }],\r
399                 items: {\r
400                     xtype: 'monthdaydetailview',\r
401                     id: this.id + '-details-view',\r
402                     date: dt,\r
403                     view: this,\r
404                     store: this.store,\r
405                     listeners: {\r
406                         'eventsrendered': this.onDetailViewUpdated.createDelegate(this)\r
407                     }\r
408                 }\r
409             });\r
410         }\r
411         else {\r
412             this.detailPanel.setTitle(dt.format('F j'));\r
413         }\r
414         this.detailPanel.getComponent(this.id + '-details-view').update(dt);\r
415     },\r
416 \r
417     // private\r
418     onDetailViewUpdated: function(view, dt, numEvents) {\r
419         var p = this.detailPanel,\r
420         frameH = p.getFrameHeight(),\r
421         evtH = this.getEventHeight(),\r
422         bodyH = frameH + (numEvents * evtH) + 3,\r
423         dayEl = this.getDayEl(dt),\r
424         box = dayEl.getBox();\r
425 \r
426         p.updateBox(box);\r
427         p.setHeight(bodyH);\r
428         p.setWidth(Math.max(box.width, 220));\r
429         p.show();\r
430         p.getPositionEl().alignTo(dayEl, 't-t?');\r
431     },\r
432 \r
433     // private\r
434     onHide: function() {\r
435         Ext.calendar.MonthView.superclass.onHide.call(this);\r
436         if (this.detailPanel) {\r
437             this.detailPanel.hide();\r
438         }\r
439     },\r
440 \r
441     // private\r
442     onClick: function(e, t) {\r
443         if (this.detailPanel) {\r
444             this.detailPanel.hide();\r
445         }\r
446         if (Ext.calendar.MonthView.superclass.onClick.apply(this, arguments)) {\r
447             // The superclass handled the click already so exit\r
448             return;\r
449         }\r
450         if (this.dropZone) {\r
451             this.dropZone.clearShims();\r
452         }\r
453         var el = e.getTarget(this.weekLinkSelector, 3),\r
454             dt,\r
455             parts;\r
456         if (el) {\r
457             dt = el.id.split(this.weekLinkIdDelimiter)[1];\r
458             this.fireEvent('weekclick', this, Date.parseDate(dt, 'Ymd'));\r
459             return;\r
460         }\r
461         el = e.getTarget(this.moreSelector, 3);\r
462         if (el) {\r
463             dt = el.id.split(this.moreElIdDelimiter)[1];\r
464             this.onMoreClick(Date.parseDate(dt, 'Ymd'));\r
465             return;\r
466         }\r
467         el = e.getTarget('td', 3);\r
468         if (el) {\r
469             if (el.id && el.id.indexOf(this.dayElIdDelimiter) > -1) {\r
470                 parts = el.id.split(this.dayElIdDelimiter);\r
471                 dt = parts[parts.length - 1];\r
472 \r
473                 this.fireEvent('dayclick', this, Date.parseDate(dt, 'Ymd'), false, Ext.get(this.getDayId(dt)));\r
474                 return;\r
475             }\r
476         }\r
477     },\r
478 \r
479     // private\r
480     handleDayMouseEvent: function(e, t, type) {\r
481         var el = e.getTarget(this.weekLinkSelector, 3, true);\r
482         if (el) {\r
483             el[type == 'over' ? 'addClass': 'removeClass'](this.weekLinkOverClass);\r
484             return;\r
485         }\r
486         Ext.calendar.MonthView.superclass.handleDayMouseEvent.apply(this, arguments);\r
487     }\r
488 });\r
489 \r
490 Ext.reg('monthview', Ext.calendar.MonthView);\r
491 </pre>    
492 </body>
493 </html>