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; }
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'>/**
20 * @class Ext.picker.Month
21 * @extends Ext.Component
22 * <p>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.</p>
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',
32 '<div class="{baseCls}-body">',
33 '<div class="{baseCls}-months">',
34 '<tpl for="months">',
35 '<div class="{parent.baseCls}-item {parent.baseCls}-month"><a href="#" hidefocus="on">{.}</a></div>',
38 '<div class="{baseCls}-years">',
39 '<div class="{baseCls}-yearnav">',
40 '<button class="{baseCls}-yearnav-prev"></button>',
41 '<button class="{baseCls}-yearnav-next"></button>',
43 '<tpl for="years">',
44 '<div class="{parent.baseCls}-item {parent.baseCls}-year"><a href="#" hidefocus="on">{.}</a></div>',
48 '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
49 '<tpl if="showButtons">',
50 '<div class="{baseCls}-buttons"></div>',
54 <span id='Ext-picker-Month-cfg-okText'> /**
55 </span> * @cfg {String} okText The text to display on the ok button. Defaults to <tt>'OK'</tt>
59 <span id='Ext-picker-Month-cfg-cancelText'> /**
60 </span> * @cfg {String} cancelText The text to display on the cancel button. Defaults to <tt>'Cancel'</tt>
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 <tt>'x-monthpicker'</tt>
67 baseCls: Ext.baseCSSPrefix + 'monthpicker',
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 <tt>true</tt>.
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 * <tt>'x-monthpicker-selected'</tt>
79 <span id='Ext-picker-Month-cfg-value'> /**
80 </span> * @cfg {Date/Array} value The default value to set. See {#setValue setValue}
84 // used when attached to date picker which isnt showing buttons
85 smallCls: Ext.baseCSSPrefix + 'monthpicker-small',
89 yearOffset: 5, // 10 years in total, 2 per row
90 monthOffset: 6, // 12 months, 2 per row
92 // private, inherit docs
93 initComponent: function(){
96 me.selectedCls = me.baseCls + '-selected';
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
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
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
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
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
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
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
154 me.addCls(me.smallCls);
156 me.setValue(me.value);
157 me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
161 // private, inherit docs
162 onRender: function(ct, position){
166 shortName = Ext.Date.getShortMonthName,
167 monthLen = me.monthOffset;
169 for (; i < monthLen; ++i) {
170 months.push(shortName(i), shortName(i + monthLen));
173 Ext.apply(me.renderData, {
175 years: me.getYears(),
176 showButtons: me.showButtons
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'
185 this.callParent([ct, position]);
188 // private, inherit docs
189 afterRender: function(){
192 buttonsEl = me.buttonsEl;
196 me.mon(body, 'click', me.onBodyClick, me);
197 me.mon(body, 'dblclick', me.onBodyClick, me);
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');
203 if (me.showButtons) {
204 me.okBtn = Ext.create('Ext.button.Button', {
207 handler: me.onOkClick,
210 me.cancelBtn = Ext.create('Ext.button.Button', {
213 handler: me.onCancelClick,
218 me.backRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, {
219 handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears])
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])
226 me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');
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
236 setValue: function(value){
238 active = me.activeYear,
239 offset = me.monthOffset,
244 me.value = [null, null];
245 } else if (Ext.isDate(value)) {
246 me.value = [value.getMonth(), value.getFullYear()];
248 me.value = [value[0], value[1]];
254 if ((year < active || year > active + me.yearOffset)) {
255 me.activeYear = year - me.yearOffset + 1;
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
268 * @return {Array} The selected value
270 getValue: function(){
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
278 hasSelection: function(){
279 var value = this.value;
280 return value[0] !== null && value[1] !== null;
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.
287 * @return {Array} An array of years
289 getYears: function(){
291 offset = me.yearOffset,
292 start = me.activeYear, // put the "active" year on the left
293 end = start + offset,
297 for (; i < end; ++i) {
298 years.push(i, i + offset);
304 <span id='Ext-picker-Month-method-updateBody'> /**
305 </span> * Update the years in the body based on any change
308 updateBody: function(){
312 yearNumbers = me.getYears(),
313 cls = me.selectedCls,
314 value = me.getYear(null),
316 monthOffset = me.monthOffset,
320 years.removeCls(cls);
321 months.removeCls(cls);
322 years.each(function(el, all, index){
323 year = yearNumbers[index];
324 el.dom.innerHTML = year;
326 el.dom.className = cls;
329 if (month !== null) {
330 if (month < monthOffset) {
333 month = (month - monthOffset) * 2 + 1;
335 months.item(month).addCls(cls);
340 <span id='Ext-picker-Month-method-getYear'> /**
341 </span> * Gets the current year value, or the default.
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
347 getYear: function(defaultValue, offset) {
348 var year = this.value[1];
349 offset = offset || 0;
350 return year === null ? defaultValue : year + offset;
353 <span id='Ext-picker-Month-method-onBodyClick'> /**
354 </span> * React to clicks on the body
357 onBodyClick: function(e, t) {
359 isDouble = e.type == 'dblclick';
361 if (e.getTarget('.' + me.baseCls + '-month')) {
363 me.onMonthClick(t, isDouble);
364 } else if (e.getTarget('.' + me.baseCls + '-year')) {
366 me.onYearClick(t, isDouble);
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.
374 adjustYear: function(offset){
375 if (typeof offset != 'number') {
376 offset = this.totalYears;
378 this.activeYear += offset;
382 <span id='Ext-picker-Month-method-onOkClick'> /**
383 </span> * React to the ok button being pressed
386 onOkClick: function(){
387 this.fireEvent('okclick', this, this.value);
390 <span id='Ext-picker-Month-method-onCancelClick'> /**
391 </span> * React to the cancel button being pressed
394 onCancelClick: function(){
395 this.fireEvent('cancelclick', this);
398 <span id='Ext-picker-Month-method-onMonthClick'> /**
399 </span> * React to a month being clicked
401 * @param {HTMLElement} target The element that was clicked
402 * @param {Boolean} isDouble True if the event was a doubleclick
404 onMonthClick: function(target, isDouble){
406 me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset);
408 me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
409 me.fireEvent('select', me, me.value);
412 <span id='Ext-picker-Month-method-onYearClick'> /**
413 </span> * React to a year being clicked
415 * @param {HTMLElement} target The element that was clicked
416 * @param {Boolean} isDouble True if the event was a doubleclick
418 onYearClick: function(target, isDouble){
420 me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset);
422 me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value);
423 me.fireEvent('select', me, me.value);
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.
431 * @param {Object} index
432 * @param {Object} offset
433 * @return {Number} The correctly offsetted number
435 resolveOffset: function(index, offset){
436 if (index % 2 === 0) {
439 return offset + Math.floor(index / 2);
443 // private, inherit docs
444 beforeDestroy: function(){
446 me.years = me.months = null;
447 Ext.destroyMembers('backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');