注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

百鬼夜行

身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。

 
 
 

日志

 
 

MonthField (重写Ext的DateField作为月历/季度历使用)  

2010-12-22 17:09:33|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

/**
 * @class CExt.form.MonthPicker
 * @extends Ext.Component
 * <p>A popup month picker. This class is used by the {@link CExt.form.MonthField MonthField} class
 * to allow browsing and selection of valid months/seasons.</p>
 * @constructor
 * Create a new MonthPicker
 * @param {Object} config The config object
 * @xtype monthpicker
 */
CExt.form.MonthPicker = Ext.extend(Ext.BoxComponent, {
    /**
     * @cfg {Array} yearsData
     * 配置可选年度的区间  [1999,2010]
     */

    /**
     * @cfg {Boolean} seasonMode 季度模式,默认false月份模式
     */

    /**
     * @cfg {String} rawValueSeparator 返回值分隔符,默认'-'
     */
    rawValueSeparator: '-',

    /**
     * @cfg {Object} buttonText 按钮文字
     */
    buttonText: {
        clear: 'Clear',
        current: 'Current',
        close: 'Close'
    },

    /**
     * @cfg {String} seasonText '季度'显示文本
     */
    seasonText: 'Quarter',

    // private
    initComponent: function() {
        CExt.form.MonthPicker.superclass.initComponent.call(this);

        this.value = this.value ? this.value : [new Date().getFullYear(), this.rawValueSeparator, this.getCurrentPeriod()].join('');

        this.addEvents(
                       /**
                        * @event select
                        * Fires when a month is selected
                        * @param {CExt.form.MonthPicker} this
                        * @param {String} value <p>选中的值</p><p>The selected value</p>
                        */
                       'select');
        this.addEvents(
                       /**
                        * @event clear
                        * Fires when press the clear button.
                        * @param {CExt.form.MonthPicker} this
                        * @param {String} value <p>清空前的值</p><p>The value that before cleared.</p>
                        */
                       'clear');

    },

    // private
    onRender: function(ct, pos) {
        var m =
                ['<table cellspacing="0">', '<tr><td class="x-date-left"><a href="#" title="', this.prevText, '">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText, '">&#160;</a></td></tr>', '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead style="visibility:hidden"><tr>'], i;

        for (i = 0; i < (this.seasonMode ? 2 : 4); i++) {
            m.push('<th><span></span></th>');
        }
        m[m.length] = '</tr></thead><tbody><tr>';
        for (i = 0; i < (this.seasonMode ? 4 : 12); i++) {
            if (i % (this.seasonMode ? 2 : 4) === 0 && i !== 0) {
                m[m.length] = '</tr><tr>';
            }
            m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span>' + (this.seasonMode ? ((i + 1) + this.seasonText) : (i + 1)) + '</span></em></a></td>';
        }
        m.push('</tr></tbody></table></td></tr>', '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>', '</table>');

        var el = document.createElement('div');
        el.className = 'x-date-picker';
        el.innerHTML = m.join('');
        ct.dom.insertBefore(el, pos);

        this.el = Ext.get(el);
        this.eventEl = Ext.get(el.firstChild);
        this.cells = this.el.select('table.x-date-inner tbody td');

        var curY = new Date().getFullYear();
        var midEl = this.el.query('td.x-date-middle')[0];
        if (Ext.isArray(this.yearsData)) {
            midEl.innerHTML = this.yearsData[this.yearsData.length - 1];
            for (var i = this.yearsData[0]; i <= this.yearsData[this.yearsData.length - 1]; i++) {
                if (i == curY) {
                    midEl.innerHTML = curY;
                }
            }
        }

        new Ext.Container({
            renderTo: this.el.child('td.x-date-bottom', true),
            layout: 'table',
            layoutConfig: {
                columns: 3
            },
            items: [this.clearBtn = new Ext.Button({
                text: this.buttonText.clear,
                tooltip: this.buttonText.clear,
                handler: this.clearCellSelect,
                scope: this
            }), this.currentBtn = new Ext.Button({
                text: this.buttonText.current,
                tooltip: this.buttonText.current,
                handler: this.setCurrentSelect,
                scope: this
            }), this.closeBtn = new Ext.Button({
                text: this.buttonText.close,
                tooltip: this.buttonText.close,
                scope: this
            })]
        });

        this.setMonthCls();

        this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
            handler: this.showPrevYear,
            scope: this,
            preventDefault: true,
            stopDefault: true
        });
        this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
            handler: this.showNextYear,
            scope: this,
            preventDefault: true,
            stopDefault: true
        });

        this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
        this.mon(this.eventEl, 'click', this.handleMonthClick, this, {
            delegate: 'a.x-date-date'
        });

        var main = this.el.dom.firstChild, w = main.offsetWidth, h = main.offsetHeight;
        Ext.fly(main).setWidth(w);
        Ext.fly(main).setHeight(h);

        this.el.unselectable();
    },

    //private
    setMonthCls: function() {
        for (var j = 0; j < this.cells.elements.length; j++) {
            this.cells.elements[j].firstChild.monthValue = (j + 1);
            if (this.el.query('td.x-date-middle')[0].innerHTML == new Date().getFullYear() && this.getCurrentPeriod() == (j + 1)) {
                Ext.fly(this.cells.elements[j]).addClass('x-date-today');
                if (this.value.split(this.rawValueSeparator)[1] == this.getCurrentPeriod()) {
                    this.setCellSelect(this.cells.elements[j].firstChild);
                }
            } else {
                Ext.fly(this.cells.elements[j]).removeClass('x-date-today');
            }
        }
    },

    //private
    showPrevYear: function() {
        var last = parseInt(this.el.query('td.x-date-middle')[0].innerHTML);
        if (last > this.yearsData[0]) {
            this.el.query('td.x-date-middle')[0].innerHTML = last - 1;
        }
    },

    //private
    showNextYear: function() {
        var last = parseInt(this.el.query('td.x-date-middle')[0].innerHTML);
        if (last < this.yearsData[this.yearsData.length - 1]) {
            this.el.query('td.x-date-middle')[0].innerHTML = last + 1;
        }
    },

    // private
    handleMouseWheel: function(e) {
        e.stopEvent();
        var delta = e.getWheelDelta();
        if (delta > 0) {
            this.showPrevYear();
        } else if (delta < 0) {
            this.showNextYear();
        }
        this.setMonthCls();
    },

    // private
    handleMonthClick: function(e, t) {
        e.stopEvent();
        if (t.monthValue) {
            this.setValue([parseInt(this.el.query('td.x-date-middle')[0].innerHTML), this.rawValueSeparator, t.monthValue].join(''));
            this.setCellSelect(t);
            this.fireEvent('select', this, this.getValue());
        }
    },

    //private
    setCellSelect: function(cell) {
        this.cells.removeClass('x-date-selected');
        Ext.fly(cell.parentNode).addClass('x-date-selected');
    },

    //private
    clearCellSelect: function() {
        this.cells.removeClass('x-date-selected');
        this.setValue('');
        this.fireEvent('clear', this, this.getValue());
    },

    //private
    setCurrentSelect: function() {
        this.update(new Date().getFullYear());

        this.setValue([parseInt(this.el.query('td.x-date-middle')[0].innerHTML), this.rawValueSeparator, this.getCurrentPeriod()].join(''));

        this.fireEvent('select', this, this.getValue());
    },

    //private
    getCurrentPeriod: function() {
        if (this.seasonMode) {
            var curMonth = (new Date().getMonth() + 1);
            var monthValue;
            if (curMonth <= 3) {
                monthValue = 1;
            } else if (curMonth <= 6) {
                monthValue = 2;
            } else if (curMonth <= 9) {
                monthValue = 3;
            } else if (curMonth <= 12) {
                monthValue = 4;
            }
        } else {
            var monthValue = (new Date().getMonth() + 1);
        }
        return monthValue;
    },

    /**
     * Sets the value of the month field
     * @param {String} value The value to set
     */
    setValue: function(value) {
        if (value) {
            this.value = value;
            var v = value.split(this.rawValueSeparator);
            this.update(v[0], v[1]);
        }
    },

    /**
     * Gets the current selected value of the month field
     * @return {Array} The selected year/month
     */
    getValue: function() {
        return this.value ? this.value.split(this.rawValueSeparator) : '';
    },

    //private
    update: function(year, month) {
        if (month) {
            var m = month;
        } else {
            var m = this.getCurrentPeriod();
        }
        this.el.query('td.x-date-middle')[0].innerHTML = year;
        for (var j = 0; j < this.cells.elements.length; j++) {
            if (this.cells.elements[j].firstChild.monthValue == m) {
                this.setCellSelect(this.cells.elements[j].firstChild);
            }
            Ext.fly(this.cells.elements[j]).removeClass('x-date-today');
            if (this.el.query('td.x-date-middle')[0].innerHTML == new Date().getFullYear() && this.getCurrentPeriod() == (j + 1)) {
                Ext.fly(this.cells.elements[j]).addClass('x-date-today');
            }
        }
    }
});

Ext.reg('monthpicker', CExt.form.MonthPicker);

/**
 * @class CExt.form.MonthField
 * @extends Ext.form.TriggerField
 *
 * <p>月份/季度选择框</p>
 *
 * @xtype cemonthfield
 */
CExt.form.MonthField = Ext.extend(Ext.form.TriggerField, {
    /**
     * @cfg {Array} yearsData
     * 配置可选年度的区间  [1999,2010] 默认为当前年的前后10年
     */

    /**
     * @cfg {String} format
     * <p>月历/季度历格式,可在配置中自定义,默认为<tt>'Y-m'</tt></p>
     * <p>The default value format string which can be overriden for localization support.</p>(defaults to <tt>'Y-m'</tt>).
     */
    format: "Y-m",

    /**
     * @cfg {String} altFormats
     * <p>月历/季度历可匹配的其他默认格式,以"<tt>|</tt>"为分隔符,默认为<tt>'Y-m|Y/m|m/Y|m-Y'</tt></p>
     * <p>Multiple value formats separated by "<tt>|</tt>" to try when parsing a config value</p>
     * <p>and it does not match the default format.</p> (defaults to <tt>'Y-m|Y/m|m/Y|m-Y'</tt>).
     */
    altFormats: "Y-m|Y/m|m/Y|m-Y",

    /**
     * @cfg {String} triggerClass
     * <p>默认trigger按钮样式</p>
     * An additional CSS class used to style the trigger button.  The trigger will always get the
     * class <tt>'x-form-trigger'</tt> and <tt>triggerClass</tt> will be <b>appended</b> if specified
     * (defaults to <tt>'x-form-date-trigger'</tt> which displays a calendar icon).
     */
    triggerClass: 'x-form-date-trigger',

    // private
    defaultAutoCreate: {
        tag: "input",
        type: "text",
        size: "20",
        autocomplete: "off"
    },

    /**
     * @cfg {String} pickerId
     * An id to assign to the underlying month picker. Defaults to <tt>null</tt>.
     */
    pickerId: null,

    /**
     * @cfg {String} rawValueSeparator 返回值分隔符,默认'-'
     */
    rawValueSeparator: '-',

    /**
     * @cfg {Boolean} seasonMode 季度选择模式, 默认false
     */
    seasonMode: false,

    /**
     * @cfg {String} seasonText '季度'显示文本
     */
    seasonText: 'Quarter',

    initComponent: function() {
        CExt.form.MonthField.superclass.initComponent.call(this);

        this.addEvents(
                       /**
                        * @event select
                        * Fires when a month is selected via the month picker.
                        * @param {CExt.form.MonthField} this
                        * @param {String} value <p>选中的值</p><p>The value of MonthField that was selected</p>
                        */
                       'select');

        this.addEvents(
                       /**
                        * @event clear
                        * Fires when press the clear button.
                        * @param {CExt.form.MonthField} this
                        * @param {String} value <p>清空前的值</p><p>The value that before cleared.</p>
                        */
                       'clear');

        this.initMonthMenu();
    },

    initEvents: function() {
        CExt.form.MonthField.superclass.initEvents.call(this);
        this.keyNav = new Ext.KeyNav(this.el, {
            "down": function(e) {
                this.onTriggerClick();
            },
            scope: this,
            forceKeyDown: true
        });
    },

    //private
    initMonthMenu: function() {
        if (this.menu == null) {
            this.menu = new Ext.menu.Menu({
                cls: 'x-date-menu',
                hideOnClick: false,
                focusOnSelect: false,
                plain: true,
                showSeparator: false,
                items: this.picker = new CExt.form.MonthPicker(Ext.applyIf({
                    seasonMode: this.seasonMode,
                    seasonText: this.seasonText,
                    rawValueSeparator: this.rawValueSeparator,
                    yearsData: this.yearsData ? this.yearsData : [new Date().getFullYear() - 10, new Date().getFullYear() + 10],
                    ctCls: 'x-menu-date-item',
                    id: this.pickerId
                }, this.initialConfig))
            });

            this.menu.relayEvents(this.picker, ['select']);
        }
    },

    /**
     * @method onTriggerClick
     * @hide
     */
    // private
    // Implements the default empty TriggerField.onTriggerClick function to display the MonthPicker
    onTriggerClick: function() {
        this.onFocus();
        this.menu.show(this.el, "tl-bl?");
        this.menuEvents('on');

        var el = this.picker.getEl();
        el.setWidth(el.getWidth()); //nasty hack for IE7 strict mode

        this.picker.setValue(this.getValue());
    },

    //private
    menuEvents: function(method) {
        this.menu[method]('select', this.onSelect, this);
        this.picker.clearBtn.on('click', this.onClear, this);
        this.picker.closeBtn.on('click', function() {
            this.menu.hide();
        }, this);
    },

    onSelect: function(m, d) {
        d = d[0] + this.rawValueSeparator + d[1];
        this.setValue(d);
        this.fireEvent('select', this, d);
        this.menu.hide();
    },

    //private
    onClear: function(m) {
        this.setValue('');
    },

    // private
    onDestroy: function() {
        Ext.destroy(this.menu, this.picker, this.keyNav);
        CExt.form.MonthField.superclass.onDestroy.call(this);
    },

    /**
     * <p>设置CExt.form.MonthField值</p>
     * <p>可传入格式为<tt>{@link #altFormats}</tt>的字符串.默认格式为<tt>"Y-m"</tt></p>
     * <p>Sets the value of the month field.  </p>
     * <p>You can pass a string using <tt>{@link #altFormats}</tt> as the allowed format</p>,
     * (the default format used is <tt>"Y-m"</tt>).
     * <br />Usage:
     * <pre><code>
    //以下格式设置同样的月份/季度,(June, 2006)/(Second quarter of 2006)
    //All of these calls set the same month/season (June, 2006)/(Second quarter of 2006)
   
    //传入默认格式
    //Pass a month/season string (default format 'Y-m'):
        monthField.setValue('2006-6');
        monthField.setValue('2006-06');
   
    //传入自定义格式
    //Pass a month/season string (custom format):
        monthField.format = 'm,Y';
        monthField.setValue('6,2006');
        monthField.setValue('06,2006');
    </code></pre>
     * @param {String} value
     * @return {CExt.form.MonthField} this
     */
    setValue: function(v) {
        v = this.formatValue(v);
        this.value = v;
        if (this.rendered) {
            if (this.seasonMode) {
                this.el.dom.value = (Ext.isEmpty(v) ? '' : (v.split(this.rawValueSeparator)[0] + CExt.form.DateTimeBox.prototype.yearText + v.split(this.rawValueSeparator)[1] + this.seasonText));
            } else {
                this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
            }
        }
        this.validate();
        return this;
    },

    /**
     * <p>返回月份/季度选中值</p>
     * Returns the current month/season value of this field.
     * @return {String} value
     */
    getValue: function() {
        return this.value;
    },

    //private
    formatValue: function(v) {
        if (v != '') {
            var charReg = /[a-zA-Z]/g, monthReg = /^([1-9]|0[1-9]|1[0-2])$/, monthIdf = /m|s/, monthIdx, defSpliter = this.format.replace(charReg, ''), y, m, value = '', vSplit = v.split(defSpliter);

            Ext.each(this.format.split(defSpliter), function(c, i) {
                if (monthIdf.test(c)) {
                    monthIdx = i;
                }
            }, this);
            if (vSplit[0] != v && monthReg.test(vSplit[monthIdx])) {
                m = parseInt(vSplit[monthIdx], 10).toString();
                vSplit.splice(monthIdx, 1);
                if (vSplit.length == 1) {
                    y = vSplit[0].toString();
                }
                value = y + this.rawValueSeparator + m;
            } else {
                var af = this.altFormats, spliter = /\d+/.test(v) ? v.replace(/\d+/g, '') : '', resultArray = [], afa = af.split("|");
                for (var i = 0, len = afa.length; i < len; i++) {
                    afa[i] = afa[i].replace(charReg, '');

                    if (spliter == afa[i]) {
                        resultArray = v.split(spliter);
                        break;
                    } else {
                        value = '';
                    }
                }
                Ext.each(resultArray, function(c, i) {
                    if (monthReg.test(c)) {
                        m = parseInt(c, 10).toString();
                        resultArray.splice(i, 1);
                        if (resultArray.length == 1) {
                            y = resultArray[0].toString();
                        }
                        value = y + this.rawValueSeparator + m;
                    }
                }, this);
            }
            return value;
        } else {
            return '';
        }
    }
});
Ext.reg('cemonthfield', CExt.form.MonthField);

  评论这张
 
阅读(2558)| 评论(1)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018