| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>  <style type="text/css">    .highlight { display: block; background-color: #ddd; }  </style>  <script type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-picker-Month'>/**</span> * @private * A month picker component. This class is used by the {@link Ext.picker.Date Date picker} class * to allow browsing and selection of year/months combinations. */Ext.define('Ext.picker.Month', {    extend: 'Ext.Component',    requires: [        'Ext.XTemplate',         'Ext.util.ClickRepeater',         'Ext.Date',         'Ext.button.Button'    ],    alias: 'widget.monthpicker',    alternateClassName: 'Ext.MonthPicker',    childEls: [        'bodyEl', 'prevEl', 'nextEl', 'buttonsEl', 'monthEl', 'yearEl'    ],    renderTpl: [        '<div id="{id}-bodyEl" class="{baseCls}-body">',          '<div id="{id}-monthEl" class="{baseCls}-months">',              '<tpl for="months">',                  '<div class="{parent.baseCls}-item {parent.baseCls}-month"><a style="{parent.monthStyle}" href="#" hidefocus="on">{.}</a></div>',              '</tpl>',          '</div>',          '<div id="{id}-yearEl" class="{baseCls}-years">',              '<div class="{baseCls}-yearnav">',                  '<button id="{id}-prevEl" class="{baseCls}-yearnav-prev"></button>',                  '<button id="{id}-nextEl" class="{baseCls}-yearnav-next"></button>',              '</div>',              '<tpl for="years">',                  '<div class="{parent.baseCls}-item {parent.baseCls}-year"><a href="#" hidefocus="on">{.}</a></div>',              '</tpl>',          '</div>',          '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',        '</div>',        '<tpl if="showButtons">',            '<div id="{id}-buttonsEl" class="{baseCls}-buttons">{%',                'var me=values.$comp, okBtn=me.okBtn, cancelBtn=me.cancelBtn;',                'okBtn.ownerLayout = cancelBtn.ownerLayout = me.componentLayout;',                'okBtn.ownerCt = cancelBtn.ownerCt = me;',                'Ext.DomHelper.generateMarkup(okBtn.getRenderTree(), out);',                'Ext.DomHelper.generateMarkup(cancelBtn.getRenderTree(), out);',            '%}</div>',        '</tpl>'    ],    //<locale><span id='Ext-picker-Month-cfg-okText'>    /**</span>     * @cfg {String} okText The text to display on the ok button.     */    okText: 'OK',    //</locale>    //<locale><span id='Ext-picker-Month-cfg-cancelText'>    /**</span>     * @cfg {String} cancelText The text to display on the cancel button.     */    cancelText: 'Cancel',    //</locale><span id='Ext-picker-Month-cfg-baseCls'>    /**</span>     * @cfg {String} [baseCls='x-monthpicker']     *  The base CSS class to apply to the picker element.     */    baseCls: Ext.baseCSSPrefix + 'monthpicker',<span id='Ext-picker-Month-cfg-showButtons'>    /**</span>     * @cfg {Boolean} showButtons True to show ok and cancel buttons below the picker.     */    showButtons: true,<span id='Ext-picker-Month-cfg-selectedCls'>    /**</span>     * @cfg {String} [selectedCls='x-monthpicker-selected'] The class to be added to selected items in the picker.     */<span id='Ext-picker-Month-cfg-value'>    /**</span>     * @cfg {Date/Number[]} value The default value to set. See {@link #setValue}     */            width: 178,    measureWidth: 35,    measureMaxHeight: 20,    // used when attached to date picker which isnt showing buttons    smallCls: Ext.baseCSSPrefix + 'monthpicker-small',    // private    totalYears: 10,    yearOffset: 5, // 10 years in total, 2 per row    monthOffset: 6, // 12 months, 2 per row    // private, inherit docs    initComponent: function(){        var me = this;        me.selectedCls = me.baseCls + '-selected';        me.addEvents(<span id='Ext-picker-Month-event-cancelclick'>            /**</span>             * @event cancelclick             * Fires when the cancel button is pressed.             * @param {Ext.picker.Month} this             */            'cancelclick',<span id='Ext-picker-Month-event-monthclick'>            /**</span>             * @event monthclick             * Fires when a month is clicked.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'monthclick',<span id='Ext-picker-Month-event-monthdblclick'>            /**</span>             * @event monthdblclick             * Fires when a month is clicked.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'monthdblclick',<span id='Ext-picker-Month-event-okclick'>            /**</span>             * @event okclick             * Fires when the ok button is pressed.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'okclick',<span id='Ext-picker-Month-event-select'>            /**</span>             * @event select             * Fires when a month/year is selected.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'select',<span id='Ext-picker-Month-event-yearclick'>            /**</span>             * @event yearclick             * Fires when a year is clicked.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'yearclick',<span id='Ext-picker-Month-event-yeardblclick'>            /**</span>             * @event yeardblclick             * Fires when a year is clicked.             * @param {Ext.picker.Month} this             * @param {Array} value The current value             */            'yeardblclick'        );        if (me.small) {            me.addCls(me.smallCls);        }        me.setValue(me.value);        me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);        if (me.showButtons) {            me.okBtn = new Ext.button.Button({                text: me.okText,                handler: me.onOkClick,                scope: me            });            me.cancelBtn = new Ext.button.Button({                text: me.cancelText,                handler: me.onCancelClick,                scope: me            });        }        this.callParent();    },    // private, inherit docs    beforeRender: function(){        var me = this,            i = 0,            months = [],            shortName = Ext.Date.getShortMonthName,            monthLen = me.monthOffset,            margin = me.monthMargin,            style = '';        me.callParent();        for (; i < monthLen; ++i) {            months.push(shortName(i), shortName(i + monthLen));        }                if (Ext.isDefined(margin)) {            style = 'margin: 0 ' + margin + 'px;';        }        Ext.apply(me.renderData, {            months: months,            years: me.getYears(),            showButtons: me.showButtons,            monthStyle: style        });    },    // private, inherit docs    afterRender: function(){        var me = this,            body = me.bodyEl,            buttonsEl = me.buttonsEl;        me.callParent();        me.mon(body, 'click', me.onBodyClick, me);        me.mon(body, 'dblclick', me.onBodyClick, me);        // keep a reference to the year/month elements since we'll be re-using them        me.years = body.select('.' + me.baseCls + '-year a');        me.months = body.select('.' + me.baseCls + '-month a');        me.backRepeater = new Ext.util.ClickRepeater(me.prevEl, {            handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears])        });        me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over');        me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, {            handler: Ext.Function.bind(me.adjustYear, me, [me.totalYears])        });        me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');        me.updateBody();                if (!Ext.isDefined(me.monthMargin)) {            Ext.picker.Month.prototype.monthMargin = me.calculateMonthMargin();        }    },        calculateMonthMargin: function(){        // We use this method for locales where the short month name        // may be longer than we see in English. For example in the         // zh_TW locale the month ends up spanning lines, so we loosen        // the margins to get some extra space        var me = this,            monthEl = me.monthEl,            months = me.months,            first = months.first(),            itemMargin = first.getMargin('l');                    while (itemMargin && me.getLargest() > me.measureMaxHeight) {            --itemMargin;            months.setStyle('margin', '0 ' + itemMargin + 'px');        }        return itemMargin;    },        getLargest: function(months){        var largest = 0;        this.months.each(function(item){            var h = item.getHeight();            if (h > largest) {                largest = h;            }        });        return largest;            },<span id='Ext-picker-Month-method-setValue'>    /**</span>     * Set the value for the picker.     * @param {Date/Number[]} value The value to set. It can be a Date object, where the month/year will be extracted, or     * it can be an array, with the month as the first index and the year as the second.     * @return {Ext.picker.Month} this     */    setValue: function(value){        var me = this,            active = me.activeYear,            offset = me.monthOffset,            year,            index;        if (!value) {            me.value = [null, null];        } else if (Ext.isDate(value)) {            me.value = [value.getMonth(), value.getFullYear()];        } else {            me.value = [value[0], value[1]];        }        if (me.rendered) {            year = me.value[1];            if (year !== null) {                if ((year < active || year > active + me.yearOffset)) {                    me.activeYear = year - me.yearOffset + 1;                }            }            me.updateBody();        }        return me;    },<span id='Ext-picker-Month-method-getValue'>    /**</span>     * Gets the selected value. It is returned as an array [month, year]. It may     * be a partial value, for example [null, 2010]. The month is returned as     * 0 based.     * @return {Number[]} The selected value     */    getValue: function(){        return this.value;    },<span id='Ext-picker-Month-method-hasSelection'>    /**</span>     * Checks whether the picker has a selection     * @return {Boolean} Returns true if both a month and year have been selected     */    hasSelection: function(){        var value = this.value;        return value[0] !== null && value[1] !== null;    },<span id='Ext-picker-Month-method-getYears'>    /**</span>     * Get an array of years to be pushed in the template. It is not in strict     * numerical order because we want to show them in columns.     * @private     * @return {Number[]} An array of years     */    getYears: function(){        var me = this,            offset = me.yearOffset,            start = me.activeYear, // put the "active" year on the left            end = start + offset,            i = start,            years = [];        for (; i < end; ++i) {            years.push(i, i + offset);        }        return years;    },<span id='Ext-picker-Month-method-updateBody'>    /**</span>     * Update the years in the body based on any change     * @private     */    updateBody: function(){        var me = this,            years = me.years,            months = me.months,            yearNumbers = me.getYears(),            cls = me.selectedCls,            value = me.getYear(null),            month = me.value[0],            monthOffset = me.monthOffset,            year,            yearItems, y, yLen, el;        if (me.rendered) {            years.removeCls(cls);            months.removeCls(cls);            yearItems = years.elements;            yLen      = yearItems.length;            for (y = 0; y < yLen; y++) {                el = Ext.fly(yearItems[y]);                year = yearNumbers[y];                el.dom.innerHTML = year;                if (year == value) {                    el.dom.className = cls;                }            }            if (month !== null) {                if (month < monthOffset) {                    month = month * 2;                } else {                    month = (month - monthOffset) * 2 + 1;                }                months.item(month).addCls(cls);            }        }    },<span id='Ext-picker-Month-method-getYear'>    /**</span>     * Gets the current year value, or the default.     * @private     * @param {Number} defaultValue The default value to use if the year is not defined.     * @param {Number} offset A number to offset the value by     * @return {Number} The year value     */    getYear: function(defaultValue, offset) {        var year = this.value[1];        offset = offset || 0;        return year === null ? defaultValue : year + offset;    },<span id='Ext-picker-Month-method-onBodyClick'>    /**</span>     * React to clicks on the body     * @private     */    onBodyClick: function(e, t) {        var me = this,            isDouble = e.type == 'dblclick';        if (e.getTarget('.' + me.baseCls + '-month')) {            e.stopEvent();            me.onMonthClick(t, isDouble);        } else if (e.getTarget('.' + me.baseCls + '-year')) {            e.stopEvent();            me.onYearClick(t, isDouble);        }    },<span id='Ext-picker-Month-method-adjustYear'>    /**</span>     * Modify the year display by passing an offset.     * @param {Number} [offset=10] The offset to move by.     */    adjustYear: function(offset){        if (typeof offset != 'number') {            offset = this.totalYears;        }        this.activeYear += offset;        this.updateBody();    },<span id='Ext-picker-Month-method-onOkClick'>    /**</span>     * React to the ok button being pressed     * @private     */    onOkClick: function(){        this.fireEvent('okclick', this, this.value);    },<span id='Ext-picker-Month-method-onCancelClick'>    /**</span>     * React to the cancel button being pressed     * @private     */    onCancelClick: function(){        this.fireEvent('cancelclick', this);    },<span id='Ext-picker-Month-method-onMonthClick'>    /**</span>     * React to a month being clicked     * @private     * @param {HTMLElement} target The element that was clicked     * @param {Boolean} isDouble True if the event was a doubleclick     */    onMonthClick: function(target, isDouble){        var me = this;        me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset);        me.updateBody();        me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value);        me.fireEvent('select', me, me.value);    },<span id='Ext-picker-Month-method-onYearClick'>    /**</span>     * React to a year being clicked     * @private     * @param {HTMLElement} target The element that was clicked     * @param {Boolean} isDouble True if the event was a doubleclick     */    onYearClick: function(target, isDouble){        var me = this;        me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset);        me.updateBody();        me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value);        me.fireEvent('select', me, me.value);    },<span id='Ext-picker-Month-method-resolveOffset'>    /**</span>     * Returns an offsetted number based on the position in the collection. Since our collections aren't     * numerically ordered, this function helps to normalize those differences.     * @private     * @param {Object} index     * @param {Object} offset     * @return {Number} The correctly offsetted number     */    resolveOffset: function(index, offset){        if (index % 2 === 0) {            return (index / 2);        } else {            return offset + Math.floor(index / 2);        }    },    // private, inherit docs    beforeDestroy: function(){        var me = this;        me.years = me.months = null;        Ext.destroyMembers(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');        me.callParent();    },    // Do the job of a container layout at this point even though we are not a Container.    // TODO: Refactor as a Container.    finishRenderChildren: function () {        var me = this;        this.callParent(arguments);        if (this.showButtons) {            me.okBtn.finishRender();            me.cancelBtn.finishRender();        }    },    onDestroy: function() {        Ext.destroyMembers(this, 'okBtn', 'cancelBtn');        this.callParent();    }    });</pre></body></html>
 |