X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..3789b528d8dd8aad4558e38e22d775bcab1cbd36:/docs/source/Month.html diff --git a/docs/source/Month.html b/docs/source/Month.html new file mode 100644 index 00000000..922d8cdd --- /dev/null +++ b/docs/source/Month.html @@ -0,0 +1,457 @@ + + + + + The source code + + + + + + +
/**
+ * @private
+ * @class Ext.picker.Month
+ * @extends Ext.Component
+ * <p>A month picker component. This class is used by the {@link Ext.picker.Date DatePicker} class
+ * to allow browsing and selection of year/months combinations.</p>
+ * @constructor
+ * Create a new MonthPicker
+ * @param {Object} config The config object
+ * @xtype monthpicker
+ * @private
+ */
+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',
+
+    renderTpl: [
+        '<div class="{baseCls}-body">',
+          '<div class="{baseCls}-months">',
+              '<tpl for="months">',
+                  '<div class="{parent.baseCls}-item {parent.baseCls}-month"><a href="#" hidefocus="on">{.}</a></div>',
+              '</tpl>',
+          '</div>',
+          '<div class="{baseCls}-years">',
+              '<div class="{baseCls}-yearnav">',
+                  '<button class="{baseCls}-yearnav-prev"></button>',
+                  '<button 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>',
+        '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
+        '<tpl if="showButtons">',
+          '<div class="{baseCls}-buttons"></div>',
+        '</tpl>'
+    ],
+
+    /**
+     * @cfg {String} okText The text to display on the ok button. Defaults to <tt>'OK'</tt>
+     */
+    okText: 'OK',
+
+    /**
+     * @cfg {String} cancelText The text to display on the cancel button. Defaults to <tt>'Cancel'</tt>
+     */
+    cancelText: 'Cancel',
+
+    /**
+     * @cfg {String} baseCls The base CSS class to apply to the picker element. Defaults to <tt>'x-monthpicker'</tt>
+     */
+    baseCls: Ext.baseCSSPrefix + 'monthpicker',
+
+    /**
+     * @cfg {Boolean} showButtons True to show ok and cancel buttons below the picker. Defaults to <tt>true</tt>.
+     */
+    showButtons: true,
+
+    /**
+     * @cfg {String} selectedCls The class to be added to selected items in the picker. Defaults to
+     * <tt>'x-monthpicker-selected'</tt>
+     */
+
+    /**
+     * @cfg {Date/Array} value The default value to set. See {#setValue setValue}
+     */
+
+    width: 175,
+
+    height: 195,
+
+
+    // 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(
+            /**
+             * @event cancelclick
+             * Fires when the cancel button is pressed.
+             * @param {Ext.picker.Month} this
+             */
+            'cancelclick',
+
+            /**
+             * @event monthclick
+             * Fires when a month is clicked.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'monthclick',
+
+            /**
+             * @event monthdblclick
+             * Fires when a month is clicked.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'monthdblclick',
+
+            /**
+             * @event okclick
+             * Fires when the ok button is pressed.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'okclick',
+
+            /**
+             * @event select
+             * Fires when a month/year is selected.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'select',
+
+            /**
+             * @event yearclick
+             * Fires when a year is clicked.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'yearclick',
+
+            /**
+             * @event yeardblclick
+             * Fires when a year is clicked.
+             * @param {Ext.picker.Month} this
+             * @param {Array} value The current value
+             */
+            'yeardblclick'
+        );
+
+        me.setValue(me.value);
+        me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
+        this.callParent();
+    },
+
+    // private, inherit docs
+    onRender: function(ct, position){
+        var me = this,
+            i = 0,
+            months = [],
+            shortName = Ext.Date.getShortMonthName,
+            monthLen = me.monthOffset;
+
+        for (; i < monthLen; ++i) {
+            months.push(shortName(i), shortName(i + monthLen));
+        }
+
+        Ext.apply(me.renderData, {
+            months: months,
+            years: me.getYears(),
+            showButtons: me.showButtons
+        });
+
+        Ext.apply(me.renderSelectors, {
+            bodyEl: '.' + me.baseCls + '-body',
+            prevEl: '.' + me.baseCls + '-yearnav-prev',
+            nextEl: '.' + me.baseCls + '-yearnav-next',
+            buttonsEl: '.' + me.baseCls + '-buttons'
+        });
+        this.callParent([ct, position]);
+    },
+
+    // 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');
+
+        if (me.showButtons) {
+            me.okBtn = Ext.create('Ext.button.Button', {
+                text: me.okText,
+                renderTo: buttonsEl,
+                handler: me.onOkClick,
+                scope: me
+            });
+            me.cancelBtn = Ext.create('Ext.button.Button', {
+                text: me.cancelText,
+                renderTo: buttonsEl,
+                handler: me.onCancelClick,
+                scope: me
+            });
+        }
+
+        me.backRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, {
+            handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears])
+        });
+
+        me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over');
+        me.nextRepeater = Ext.create('Ext.util.ClickRepeater', me.nextEl, {
+            handler: Ext.Function.bind(me.adjustYear, me, [me.totalYears])
+        });
+        me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over');
+        me.updateBody();
+    },
+
+    /**
+     * Set the value for the picker.
+     * @param {Date/Array} 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;
+    },
+
+    /**
+     * 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 {Array} The selected value
+     */
+    getValue: function(){
+        return this.value;
+    },
+
+    /**
+     * 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;
+    },
+
+    /**
+     * 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 {Array} 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;
+    },
+
+    /**
+     * 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;
+
+        if (me.rendered) {
+            years.removeCls(cls);
+            months.removeCls(cls);
+            years.each(function(el, all, index){
+                year = yearNumbers[index];
+                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);
+            }
+        }
+    },
+
+    /**
+     * 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;
+    },
+
+    /**
+     * 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);
+        }
+    },
+
+    /**
+     * Modify the year display by passing an offset.
+     * @param {Number} offset The offset to move by. If not specified, it defaults to 10.
+     */
+    adjustYear: function(offset){
+        if (typeof offset != 'number') {
+            offset = this.totalYears;
+        }
+        this.activeYear += offset;
+        this.updateBody();
+    },
+
+    /**
+     * React to the ok button being pressed
+     * @private
+     */
+    onOkClick: function(){
+        this.fireEvent('okclick', this, this.value);
+    },
+
+    /**
+     * React to the cancel button being pressed
+     * @private
+     */
+    onCancelClick: function(){
+        this.fireEvent('cancelclick', this);
+    },
+
+    /**
+     * 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);
+    },
+
+    /**
+     * 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);
+
+    },
+
+    /**
+     * 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('backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
+        this.callParent();
+    }
+});
+
+ +