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; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
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.
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',
29 '<div id="{id}-bodyEl" class="{baseCls}-body">',
30 '<div class="{baseCls}-months">',
31 '<tpl for="months">',
32 '<div class="{parent.baseCls}-item {parent.baseCls}-month"><a href="#" hidefocus="on">{.}</a></div>',
35 '<div class="{baseCls}-years">',
36 '<div class="{baseCls}-yearnav">',
37 '<button id="{id}-prevEl" class="{baseCls}-yearnav-prev"></button>',
38 '<button id="{id}-nextEl" class="{baseCls}-yearnav-next"></button>',
40 '<tpl for="years">',
41 '<div class="{parent.baseCls}-item {parent.baseCls}-year"><a href="#" hidefocus="on">{.}</a></div>',
44 '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
46 '<tpl if="showButtons">',
47 '<div id="{id}-buttonsEl" class="{baseCls}-buttons"></div>',
51 <span id='Ext-picker-Month-cfg-okText'> /**
52 </span> * @cfg {String} okText The text to display on the ok button.
56 <span id='Ext-picker-Month-cfg-cancelText'> /**
57 </span> * @cfg {String} cancelText The text to display on the cancel button.
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 <tt>'x-monthpicker'</tt>
64 baseCls: Ext.baseCSSPrefix + 'monthpicker',
66 <span id='Ext-picker-Month-cfg-showButtons'> /**
67 </span> * @cfg {Boolean} showButtons True to show ok and cancel buttons below the picker.
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 * <tt>'x-monthpicker-selected'</tt>
76 <span id='Ext-picker-Month-cfg-value'> /**
77 </span> * @cfg {Date/Number[]} value The default value to set. See {@link #setValue}
81 // used when attached to date picker which isnt showing buttons
82 smallCls: Ext.baseCSSPrefix + 'monthpicker-small',
86 yearOffset: 5, // 10 years in total, 2 per row
87 monthOffset: 6, // 12 months, 2 per row
89 // private, inherit docs
90 initComponent: function(){
93 me.selectedCls = me.baseCls + '-selected';
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
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
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
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
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
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
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
151 me.addCls(me.smallCls);
153 me.setValue(me.value);
154 me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
158 // private, inherit docs
159 onRender: function(ct, position){
163 shortName = Ext.Date.getShortMonthName,
164 monthLen = me.monthOffset;
166 for (; i < monthLen; ++i) {
167 months.push(shortName(i), shortName(i + monthLen));
170 Ext.apply(me.renderData, {
172 years: me.getYears(),
173 showButtons: me.showButtons
176 me.addChildEls('bodyEl', 'prevEl', 'nextEl', 'buttonsEl');
178 me.callParent(arguments);
181 // private, inherit docs
182 afterRender: function(){
185 buttonsEl = me.buttonsEl;
189 me.mon(body, 'click', me.onBodyClick, me);
190 me.mon(body, 'dblclick', me.onBodyClick, me);
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');
196 if (me.showButtons) {
197 me.okBtn = Ext.create('Ext.button.Button', {
200 handler: me.onOkClick,
203 me.cancelBtn = Ext.create('Ext.button.Button', {
206 handler: me.onCancelClick,
211 me.backRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, {
212 handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears])
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])
219 me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');
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
229 setValue: function(value){
231 active = me.activeYear,
232 offset = me.monthOffset,
237 me.value = [null, null];
238 } else if (Ext.isDate(value)) {
239 me.value = [value.getMonth(), value.getFullYear()];
241 me.value = [value[0], value[1]];
247 if ((year < active || year > active + me.yearOffset)) {
248 me.activeYear = year - me.yearOffset + 1;
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
261 * @return {Number[]} The selected value
263 getValue: function(){
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
271 hasSelection: function(){
272 var value = this.value;
273 return value[0] !== null && value[1] !== null;
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.
280 * @return {Number[]} An array of years
282 getYears: function(){
284 offset = me.yearOffset,
285 start = me.activeYear, // put the "active" year on the left
286 end = start + offset,
290 for (; i < end; ++i) {
291 years.push(i, i + offset);
297 <span id='Ext-picker-Month-method-updateBody'> /**
298 </span> * Update the years in the body based on any change
301 updateBody: function(){
305 yearNumbers = me.getYears(),
306 cls = me.selectedCls,
307 value = me.getYear(null),
309 monthOffset = me.monthOffset,
313 years.removeCls(cls);
314 months.removeCls(cls);
315 years.each(function(el, all, index){
316 year = yearNumbers[index];
317 el.dom.innerHTML = year;
319 el.dom.className = cls;
322 if (month !== null) {
323 if (month < monthOffset) {
326 month = (month - monthOffset) * 2 + 1;
328 months.item(month).addCls(cls);
333 <span id='Ext-picker-Month-method-getYear'> /**
334 </span> * Gets the current year value, or the default.
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
340 getYear: function(defaultValue, offset) {
341 var year = this.value[1];
342 offset = offset || 0;
343 return year === null ? defaultValue : year + offset;
346 <span id='Ext-picker-Month-method-onBodyClick'> /**
347 </span> * React to clicks on the body
350 onBodyClick: function(e, t) {
352 isDouble = e.type == 'dblclick';
354 if (e.getTarget('.' + me.baseCls + '-month')) {
356 me.onMonthClick(t, isDouble);
357 } else if (e.getTarget('.' + me.baseCls + '-year')) {
359 me.onYearClick(t, isDouble);
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.
367 adjustYear: function(offset){
368 if (typeof offset != 'number') {
369 offset = this.totalYears;
371 this.activeYear += offset;
375 <span id='Ext-picker-Month-method-onOkClick'> /**
376 </span> * React to the ok button being pressed
379 onOkClick: function(){
380 this.fireEvent('okclick', this, this.value);
383 <span id='Ext-picker-Month-method-onCancelClick'> /**
384 </span> * React to the cancel button being pressed
387 onCancelClick: function(){
388 this.fireEvent('cancelclick', this);
391 <span id='Ext-picker-Month-method-onMonthClick'> /**
392 </span> * React to a month being clicked
394 * @param {HTMLElement} target The element that was clicked
395 * @param {Boolean} isDouble True if the event was a doubleclick
397 onMonthClick: function(target, isDouble){
399 me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset);
401 me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
402 me.fireEvent('select', me, me.value);
405 <span id='Ext-picker-Month-method-onYearClick'> /**
406 </span> * React to a year being clicked
408 * @param {HTMLElement} target The element that was clicked
409 * @param {Boolean} isDouble True if the event was a doubleclick
411 onYearClick: function(target, isDouble){
413 me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset);
415 me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
416 me.fireEvent('select', me, me.value);
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.
424 * @param {Object} index
425 * @param {Object} offset
426 * @return {Number} The correctly offsetted number
428 resolveOffset: function(index, offset){
429 if (index % 2 === 0) {
432 return offset + Math.floor(index / 2);
436 // private, inherit docs
437 beforeDestroy: function(){
439 me.years = me.months = null;
440 Ext.destroyMembers(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');