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