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