Ext7年份组件,只显示年份

Ext7年份组件,只显示年份

1.定义组件
此代码片段放在单独的js文件中,然后在html引入即可

Ext.define('ux.picker.Year', {
    extend: 'Ext.Component',
    alias: 'widget.uxYearpicker',
    alternateClassName: 'ux.uxYearpicker',
    cls: 'uxYearpicker',
    isYearPicker: true,

    focusable: true,

    childEls: [
        'bodyEl', 'prevEl', 'nextEl', 'yearEl'
    ],

    renderTpl: [
        '<div id="{id}-bodyEl" data-ref="bodyEl" class="{baseCls}-body">',
        '<div id="{id}-yearEl" data-ref="yearEl" class="{baseCls}-years uxYearpicker-years">',
        '<div class="{baseCls}-yearnav">',
        '<div class="{baseCls}-yearnav-button-ct">',
        '<a id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-yearnav-button {baseCls}-yearnav-prev" hidefocus="on" role="button"></a>',
        '</div>',
        '<div class="{baseCls}-yearnav-button-ct">',
        '<a id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-yearnav-button {baseCls}-yearnav-next" hidefocus="on" role="button"></a>',
        '</div>',
        '</div>',
        '<tpl for="years">',
        '<div class="{parent.baseCls}-item {parent.baseCls}-year">',
        '<a hidefocus="on" class="{parent.baseCls}-item-inner" role="button">{.}</a>',
        '</div>',
        '</tpl>',
        '</div>',
        '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
        '<tpl if="showButtons">',
        '<div 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>',
        '</div>'
    ],

    //<locale>
    /**
     * @cfg {String} okText The text to display on the ok button.
     */
    okText: '确定',
    //</locale>

    //<locale>
    /**
     * @cfg {String} cancelText The text to display on the cancel button.
     */
    cancelText: '取消',
    //</locale>

    /**
     * @cfg {String} [baseCls='x-monthpicker']
     *  The base CSS class to apply to the picker element.
     */
    baseCls: Ext.baseCSSPrefix + 'monthpicker',

    /**
     * @cfg {Boolean} showButtons True to show ok and cancel buttons below the picker.
     */
    showButtons: true,

    /**
     * @cfg {String} [selectedCls='x-monthpicker-selected'] The class to be added to selected items in the picker.
     */

    /**
     * @cfg {Date/Number[]} value The default value to set. See {@link #setValue}
     */

    /**
     * @cfg {String}
     * The {@link Ext.button.Button#ui} to use for the month picker's footer buttons.
     */
    footerButtonUI: 'default-toolbar',

    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: 0, // 12 months, 2 per row
    alignOnScroll: false,

    /**
     * @event cancelclick
     * Fires when the cancel button is pressed.
     * @param {Ext.picker.Month} this
     */

    /**
     * @event monthclick
     * Fires when a month is clicked.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @event monthdblclick
     * Fires when a month is clicked.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @event okclick
     * Fires when the ok button is pressed.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @event select
     * Fires when a month/year is selected.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @event yearclick
     * Fires when a year is clicked.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @event yeardblclick
     * Fires when a year is clicked.
     * @param {Ext.picker.Month} this
     * @param {Array} value The current value
     */

    /**
     * @inheritdoc
     * @private
     */
    initComponent: function () {
        var me = this;

        me.selectedCls = me.baseCls + '-selected';

        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({
                ui: me.footerButtonUI,
                text: me.okText,
                handler: me.onOkClick,
                scope: me
            });
            me.cancelBtn = new Ext.button.Button({
                ui: me.footerButtonUI,
                text: me.cancelText,
                handler: me.onCancelClick,
                scope: me
            });
        }

        this.callParent();
    },

    /**
     * @inheritdoc
     * @private
     */
    beforeRender: function () {
        var me = this;

        if (me.padding && !me.width) {
            me.cacheWidth();
        }

        me.callParent();

        Ext.apply(me.renderData, {
            years: me.getYears(),
            showButtons: me.showButtons
        });
    },

    cacheWidth: function () {
        var me = this,
            padding = me.parseBox(me.padding),
            widthEl = Ext.getBody().createChild({
                cls: me.baseCls + ' ' + me.borderBoxCls,
                style: 'position:absolute;top:-1000px;left:-1000px;',
                html: ' ' // required for opera 11.64 to measure a width
            });

        me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right;
        widthEl.destroy();
    },

    /**
     * @inheritdoc
     * @private
     */
    afterRender: function () {
        var me = this,
            body = me.bodyEl;

        me.callParent();

        me.el.on('mousedown', me.onElClick, me, {
            translate: false
        });

        body.on({
            scope: me,
            click: 'onBodyClick',
            dblclick: 'onBodyClick'
        });

        // keep a reference to the year/month elements since we'll be re-using them
        me.years = body.select('.' + me.baseCls + '-year 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();

    },

    /**
     * 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,
            year;

        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 {Number[]} 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 {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;
    },

    /**
     * Update the years in the body based on any change
     * @private
     */
    updateBody: function () {
        var me = this,
            years = me.years,
            yearNumbers = me.getYears(),
            cls = me.selectedCls,
            value = me.getYear(null),
            year,
            yearItems, y, yLen, el;

        if (me.rendered) {
            years.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.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;
    },

    onElClick: function (e) {
        e.stopEvent();
    },

    /**
     * React to clicks on the body
     * @private
     */
    onBodyClick: function (e, t) {
        var me = this,
            isDouble = e.type === 'dblclick';

        if (e.getTarget('.' + me.baseCls + '-year')) {
            e.stopEvent();
            me.onYearClick(t, isDouble);
        }
    },

    /**
     * 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();
    },

    /**
     * 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 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);
        }
        return offset + Math.floor(index / 2);
    },

    /**
     * @inheritdoc
     * @private
     */
    beforeDestroy: function () {
        var me = this;
        me.years = me.months = null;
        Ext.destroyMembers(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
        me.callParent();
    },

    onDestroy: function () {
        Ext.destroyMembers(this, 'okBtn', 'cancelBtn');
        this.callParent();
    },

    privates: {
        // 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();
            }
        }
    }
});

//只选择年的控件
Ext.define('Ext.ux.form.YearField', {
    extend: 'Ext.form.field.Date',
    alias: 'widget.uxYearfield',
    xtype: 'uxYearfield',
    requires: ['ux.picker.Year'],
    format: 'Y',
    selectYear: new Date(),
    createPicker: function () {
        var me = this;
        return new ux.picker.Year({
            value: new Date(),
            renderTo: document.body,
            floating: true,
            hidden: true,
            focusOnShow: true,
            listeners: {
                scope: me,
                select: me.onSelect,
                cancelclick: me.onCancelClick,
                okclick: me.onOKClick,
                yeardblclick: me.onOKClick,
                monthdblclick: me.onOKClick
            }
        });
    },
    onCancelClick: function () {
        var me = this;
        me.selectYear = null;
        me.collapse();
    },
    onOKClick: function () {
        var me = this;
        if (me.selectYear) {
            me.setValue(me.selectYear);
            me.fireEvent('select', me, me.selectYear);
        }
        me.collapse();
    },
    onSelect: function (m, d) {
        var me = this;
        me.selectYear = new Date((d[0] + 1) + '/1/' + d[1]);
    }
});

2.在html中引入上方js,上方js文件我定义的文件名为yearPick.js,如下图所示
在这里插入图片描述
3.设置组件的样式(主要为宽度)

.uxYearpicker{//组件宽度
	width:195px !important;
}
.uxYearpicker-years{//调整年份面板使其居中
	margin-left:17px;
}

以上两个类是在定义组件时添加的,如果需要更改,可以修改代码段1,如下图所示
在这里插入图片描述
在这里插入图片描述
3.代码中使用即可,如下方实例

var field = new Ext.ux.form.YearField({
		fieldLabel : '年份选择',
		id :"date_year",
		width:300,
		format : 'Y',
		renderTo : "yearTimeValue",
		value : new Date(),
		maxValue : new Date(),
		editable : false
});

效果如下图
在这里插入图片描述
请尊重原创,转载请注明出处

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值