Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Month.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-picker-Month'>/**
19 </span> * @private
20  * @class Ext.picker.Month
21  * @extends Ext.Component
22  * &lt;p&gt;A month picker component. This class is used by the {@link Ext.picker.Date DatePicker} class
23  * to allow browsing and selection of year/months combinations.&lt;/p&gt;
24  */
25 Ext.define('Ext.picker.Month', {
26     extend: 'Ext.Component',
27     requires: ['Ext.XTemplate', 'Ext.util.ClickRepeater', 'Ext.Date', 'Ext.button.Button'],
28     alias: 'widget.monthpicker',
29     alternateClassName: 'Ext.MonthPicker',
30
31     renderTpl: [
32         '&lt;div class=&quot;{baseCls}-body&quot;&gt;',
33           '&lt;div class=&quot;{baseCls}-months&quot;&gt;',
34               '&lt;tpl for=&quot;months&quot;&gt;',
35                   '&lt;div class=&quot;{parent.baseCls}-item {parent.baseCls}-month&quot;&gt;&lt;a href=&quot;#&quot; hidefocus=&quot;on&quot;&gt;{.}&lt;/a&gt;&lt;/div&gt;',
36               '&lt;/tpl&gt;',
37           '&lt;/div&gt;',
38           '&lt;div class=&quot;{baseCls}-years&quot;&gt;',
39               '&lt;div class=&quot;{baseCls}-yearnav&quot;&gt;',
40                   '&lt;button class=&quot;{baseCls}-yearnav-prev&quot;&gt;&lt;/button&gt;',
41                   '&lt;button class=&quot;{baseCls}-yearnav-next&quot;&gt;&lt;/button&gt;',
42               '&lt;/div&gt;',
43               '&lt;tpl for=&quot;years&quot;&gt;',
44                   '&lt;div class=&quot;{parent.baseCls}-item {parent.baseCls}-year&quot;&gt;&lt;a href=&quot;#&quot; hidefocus=&quot;on&quot;&gt;{.}&lt;/a&gt;&lt;/div&gt;',
45               '&lt;/tpl&gt;',
46           '&lt;/div&gt;',
47         '&lt;/div&gt;',
48         '&lt;div class=&quot;' + Ext.baseCSSPrefix + 'clear&quot;&gt;&lt;/div&gt;',
49         '&lt;tpl if=&quot;showButtons&quot;&gt;',
50           '&lt;div class=&quot;{baseCls}-buttons&quot;&gt;&lt;/div&gt;',
51         '&lt;/tpl&gt;'
52     ],
53
54 <span id='Ext-picker-Month-cfg-okText'>    /**
55 </span>     * @cfg {String} okText The text to display on the ok button. Defaults to &lt;tt&gt;'OK'&lt;/tt&gt;
56      */
57     okText: 'OK',
58
59 <span id='Ext-picker-Month-cfg-cancelText'>    /**
60 </span>     * @cfg {String} cancelText The text to display on the cancel button. Defaults to &lt;tt&gt;'Cancel'&lt;/tt&gt;
61      */
62     cancelText: 'Cancel',
63
64 <span id='Ext-picker-Month-cfg-baseCls'>    /**
65 </span>     * @cfg {String} baseCls The base CSS class to apply to the picker element. Defaults to &lt;tt&gt;'x-monthpicker'&lt;/tt&gt;
66      */
67     baseCls: Ext.baseCSSPrefix + 'monthpicker',
68
69 <span id='Ext-picker-Month-cfg-showButtons'>    /**
70 </span>     * @cfg {Boolean} showButtons True to show ok and cancel buttons below the picker. Defaults to &lt;tt&gt;true&lt;/tt&gt;.
71      */
72     showButtons: true,
73
74 <span id='Ext-picker-Month-cfg-selectedCls'>    /**
75 </span>     * @cfg {String} selectedCls The class to be added to selected items in the picker. Defaults to
76      * &lt;tt&gt;'x-monthpicker-selected'&lt;/tt&gt;
77      */
78
79 <span id='Ext-picker-Month-cfg-value'>    /**
80 </span>     * @cfg {Date/Array} value The default value to set. See {#setValue setValue}
81      */
82     width: 178,
83     
84     // used when attached to date picker which isnt showing buttons
85     smallCls: Ext.baseCSSPrefix + 'monthpicker-small',
86
87     // private
88     totalYears: 10,
89     yearOffset: 5, // 10 years in total, 2 per row
90     monthOffset: 6, // 12 months, 2 per row
91
92     // private, inherit docs
93     initComponent: function(){
94         var me = this;
95
96         me.selectedCls = me.baseCls + '-selected';
97         me.addEvents(
98 <span id='Ext-picker-Month-event-cancelclick'>            /**
99 </span>             * @event cancelclick
100              * Fires when the cancel button is pressed.
101              * @param {Ext.picker.Month} this
102              */
103             'cancelclick',
104
105 <span id='Ext-picker-Month-event-monthclick'>            /**
106 </span>             * @event monthclick
107              * Fires when a month is clicked.
108              * @param {Ext.picker.Month} this
109              * @param {Array} value The current value
110              */
111             'monthclick',
112
113 <span id='Ext-picker-Month-event-monthdblclick'>            /**
114 </span>             * @event monthdblclick
115              * Fires when a month is clicked.
116              * @param {Ext.picker.Month} this
117              * @param {Array} value The current value
118              */
119             'monthdblclick',
120
121 <span id='Ext-picker-Month-event-okclick'>            /**
122 </span>             * @event okclick
123              * Fires when the ok button is pressed.
124              * @param {Ext.picker.Month} this
125              * @param {Array} value The current value
126              */
127             'okclick',
128
129 <span id='Ext-picker-Month-event-select'>            /**
130 </span>             * @event select
131              * Fires when a month/year is selected.
132              * @param {Ext.picker.Month} this
133              * @param {Array} value The current value
134              */
135             'select',
136
137 <span id='Ext-picker-Month-event-yearclick'>            /**
138 </span>             * @event yearclick
139              * Fires when a year is clicked.
140              * @param {Ext.picker.Month} this
141              * @param {Array} value The current value
142              */
143             'yearclick',
144
145 <span id='Ext-picker-Month-event-yeardblclick'>            /**
146 </span>             * @event yeardblclick
147              * Fires when a year is clicked.
148              * @param {Ext.picker.Month} this
149              * @param {Array} value The current value
150              */
151             'yeardblclick'
152         );
153         if (me.small) {
154             me.addCls(me.smallCls);
155         }
156         me.setValue(me.value);
157         me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
158         this.callParent();
159     },
160
161     // private, inherit docs
162     onRender: function(ct, position){
163         var me = this,
164             i = 0,
165             months = [],
166             shortName = Ext.Date.getShortMonthName,
167             monthLen = me.monthOffset;
168
169         for (; i &lt; monthLen; ++i) {
170             months.push(shortName(i), shortName(i + monthLen));
171         }
172
173         Ext.apply(me.renderData, {
174             months: months,
175             years: me.getYears(),
176             showButtons: me.showButtons
177         });
178
179         Ext.apply(me.renderSelectors, {
180             bodyEl: '.' + me.baseCls + '-body',
181             prevEl: '.' + me.baseCls + '-yearnav-prev',
182             nextEl: '.' + me.baseCls + '-yearnav-next',
183             buttonsEl: '.' + me.baseCls + '-buttons'
184         });
185         this.callParent([ct, position]);
186     },
187
188     // private, inherit docs
189     afterRender: function(){
190         var me = this,
191             body = me.bodyEl,
192             buttonsEl = me.buttonsEl;
193
194         me.callParent();
195
196         me.mon(body, 'click', me.onBodyClick, me);
197         me.mon(body, 'dblclick', me.onBodyClick, me);
198
199         // keep a reference to the year/month elements since we'll be re-using them
200         me.years = body.select('.' + me.baseCls + '-year a');
201         me.months = body.select('.' + me.baseCls + '-month a');
202
203         if (me.showButtons) {
204             me.okBtn = Ext.create('Ext.button.Button', {
205                 text: me.okText,
206                 renderTo: buttonsEl,
207                 handler: me.onOkClick,
208                 scope: me
209             });
210             me.cancelBtn = Ext.create('Ext.button.Button', {
211                 text: me.cancelText,
212                 renderTo: buttonsEl,
213                 handler: me.onCancelClick,
214                 scope: me
215             });
216         }
217
218         me.backRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, {
219             handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears])
220         });
221
222         me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over');
223         me.nextRepeater = Ext.create('Ext.util.ClickRepeater', me.nextEl, {
224             handler: Ext.Function.bind(me.adjustYear, me, [me.totalYears])
225         });
226         me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');
227         me.updateBody();
228     },
229
230 <span id='Ext-picker-Month-method-setValue'>    /**
231 </span>     * Set the value for the picker.
232      * @param {Date/Array} value The value to set. It can be a Date object, where the month/year will be extracted, or
233      * it can be an array, with the month as the first index and the year as the second.
234      * @return {Ext.picker.Month} this
235      */
236     setValue: function(value){
237         var me = this,
238             active = me.activeYear,
239             offset = me.monthOffset,
240             year,
241             index;
242
243         if (!value) {
244             me.value = [null, null];
245         } else if (Ext.isDate(value)) {
246             me.value = [value.getMonth(), value.getFullYear()];
247         } else {
248             me.value = [value[0], value[1]];
249         }
250
251         if (me.rendered) {
252             year = me.value[1];
253             if (year !== null) {
254                 if ((year &lt; active || year &gt; active + me.yearOffset)) {
255                     me.activeYear = year - me.yearOffset + 1;
256                 }
257             }
258             me.updateBody();
259         }
260
261         return me;
262     },
263
264 <span id='Ext-picker-Month-method-getValue'>    /**
265 </span>     * Gets the selected value. It is returned as an array [month, year]. It may
266      * be a partial value, for example [null, 2010]. The month is returned as
267      * 0 based.
268      * @return {Array} The selected value
269      */
270     getValue: function(){
271         return this.value;
272     },
273
274 <span id='Ext-picker-Month-method-hasSelection'>    /**
275 </span>     * Checks whether the picker has a selection
276      * @return {Boolean} Returns true if both a month and year have been selected
277      */
278     hasSelection: function(){
279         var value = this.value;
280         return value[0] !== null &amp;&amp; value[1] !== null;
281     },
282
283 <span id='Ext-picker-Month-method-getYears'>    /**
284 </span>     * Get an array of years to be pushed in the template. It is not in strict
285      * numerical order because we want to show them in columns.
286      * @private
287      * @return {Array} An array of years
288      */
289     getYears: function(){
290         var me = this,
291             offset = me.yearOffset,
292             start = me.activeYear, // put the &quot;active&quot; year on the left
293             end = start + offset,
294             i = start,
295             years = [];
296
297         for (; i &lt; end; ++i) {
298             years.push(i, i + offset);
299         }
300
301         return years;
302     },
303
304 <span id='Ext-picker-Month-method-updateBody'>    /**
305 </span>     * Update the years in the body based on any change
306      * @private
307      */
308     updateBody: function(){
309         var me = this,
310             years = me.years,
311             months = me.months,
312             yearNumbers = me.getYears(),
313             cls = me.selectedCls,
314             value = me.getYear(null),
315             month = me.value[0],
316             monthOffset = me.monthOffset,
317             year;
318
319         if (me.rendered) {
320             years.removeCls(cls);
321             months.removeCls(cls);
322             years.each(function(el, all, index){
323                 year = yearNumbers[index];
324                 el.dom.innerHTML = year;
325                 if (year == value) {
326                     el.dom.className = cls;
327                 }
328             });
329             if (month !== null) {
330                 if (month &lt; monthOffset) {
331                     month = month * 2;
332                 } else {
333                     month = (month - monthOffset) * 2 + 1;
334                 }
335                 months.item(month).addCls(cls);
336             }
337         }
338     },
339
340 <span id='Ext-picker-Month-method-getYear'>    /**
341 </span>     * Gets the current year value, or the default.
342      * @private
343      * @param {Number} defaultValue The default value to use if the year is not defined.
344      * @param {Number} offset A number to offset the value by
345      * @return {Number} The year value
346      */
347     getYear: function(defaultValue, offset) {
348         var year = this.value[1];
349         offset = offset || 0;
350         return year === null ? defaultValue : year + offset;
351     },
352
353 <span id='Ext-picker-Month-method-onBodyClick'>    /**
354 </span>     * React to clicks on the body
355      * @private
356      */
357     onBodyClick: function(e, t) {
358         var me = this,
359             isDouble = e.type == 'dblclick';
360
361         if (e.getTarget('.' + me.baseCls + '-month')) {
362             e.stopEvent();
363             me.onMonthClick(t, isDouble);
364         } else if (e.getTarget('.' + me.baseCls + '-year')) {
365             e.stopEvent();
366             me.onYearClick(t, isDouble);
367         }
368     },
369
370 <span id='Ext-picker-Month-method-adjustYear'>    /**
371 </span>     * Modify the year display by passing an offset.
372      * @param {Number} offset The offset to move by. If not specified, it defaults to 10.
373      */
374     adjustYear: function(offset){
375         if (typeof offset != 'number') {
376             offset = this.totalYears;
377         }
378         this.activeYear += offset;
379         this.updateBody();
380     },
381
382 <span id='Ext-picker-Month-method-onOkClick'>    /**
383 </span>     * React to the ok button being pressed
384      * @private
385      */
386     onOkClick: function(){
387         this.fireEvent('okclick', this, this.value);
388     },
389
390 <span id='Ext-picker-Month-method-onCancelClick'>    /**
391 </span>     * React to the cancel button being pressed
392      * @private
393      */
394     onCancelClick: function(){
395         this.fireEvent('cancelclick', this);
396     },
397
398 <span id='Ext-picker-Month-method-onMonthClick'>    /**
399 </span>     * React to a month being clicked
400      * @private
401      * @param {HTMLElement} target The element that was clicked
402      * @param {Boolean} isDouble True if the event was a doubleclick
403      */
404     onMonthClick: function(target, isDouble){
405         var me = this;
406         me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset);
407         me.updateBody();
408         me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
409         me.fireEvent('select', me, me.value);
410     },
411
412 <span id='Ext-picker-Month-method-onYearClick'>    /**
413 </span>     * React to a year being clicked
414      * @private
415      * @param {HTMLElement} target The element that was clicked
416      * @param {Boolean} isDouble True if the event was a doubleclick
417      */
418     onYearClick: function(target, isDouble){
419         var me = this;
420         me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset);
421         me.updateBody();
422         me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
423         me.fireEvent('select', me, me.value);
424
425     },
426
427 <span id='Ext-picker-Month-method-resolveOffset'>    /**
428 </span>     * Returns an offsetted number based on the position in the collection. Since our collections aren't
429      * numerically ordered, this function helps to normalize those differences.
430      * @private
431      * @param {Object} index
432      * @param {Object} offset
433      * @return {Number} The correctly offsetted number
434      */
435     resolveOffset: function(index, offset){
436         if (index % 2 === 0) {
437             return (index / 2);
438         } else {
439             return offset + Math.floor(index / 2);
440         }
441     },
442
443     // private, inherit docs
444     beforeDestroy: function(){
445         var me = this;
446         me.years = me.months = null;
447         Ext.destroyMembers('backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
448         this.callParent();
449     }
450 });
451 </pre>
452 </body>
453 </html>