Extjs 5.x 日期时间控件DateTime源码

/** * Created by jiawenjun on 2016/8/5. */Ext.define(‘Ux.picker.DateTime‘, {    extend: ‘Ext.Component‘,    requires: [        ‘Ext.XTemplate‘,        ‘Ext.button.Button‘,        ‘Ext.button.Split‘,        ‘Ext.util.ClickRepeater‘,        ‘Ext.util.KeyNav‘,        ‘Ext.fx.Manager‘,        ‘Ext.picker.Month‘    ],    alias: ‘widget.datetimepicker‘,    okText:‘确定‘,    okTip:‘确定‘,    isDatePicker: true,    focusable: false,    childEls: [        ‘innerEl‘, ‘eventEl‘, ‘prevEl‘, ‘nextEl‘, ‘middleBtnEl‘, ‘footerEl‘,‘timeEl‘    ],    border: true,    hideOnSelect:false,    renderTpl: [        ‘<div id="{id}-innerEl" data-ref="innerEl">‘,        ‘<div class="{baseCls}-header">‘,        ‘<div id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="button" title="{prevText}"></div>‘,        ‘<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month" role="heading">{%this.renderMonthBtn(values, out)%}</div>‘,        ‘<div id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="button" title="{nextText}"></div>‘,        ‘</div>‘,        ‘<table role="grid" id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" {%‘,        // If the DatePicker is focusable, make its eventEl tabbable.        // Note that we‘re looking at the `focusable` property because        // calling `isFocusable()` will always return false at that point        // as the picker is not yet rendered.        ‘if (values.$comp.focusable) {out.push("tabindex=\\\"0\\\"");}‘,        ‘%} cellspacing="0">‘,        ‘<thead><tr role="row">‘,        ‘<tpl for="dayNames">‘,        ‘<th role="columnheader" class="{parent.baseCls}-column-header" aria-label="{.}">‘,        ‘<div role="presentation" class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>‘,        ‘</th>‘,        ‘</tpl>‘,        ‘</tr></thead>‘,        ‘<tbody><tr role="row">‘,        ‘<tpl for="days">‘,        ‘{#:this.isEndOfWeek}‘,        ‘<td role="gridcell">‘,        ‘<div hidefocus="on" class="{parent.baseCls}-date"></div>‘,        ‘</td>‘,        ‘</tpl>‘,        ‘</tr></tbody>‘,        ‘</table>‘,        ‘<table role="gridTime" id="{id}-timeEl" data-ref="timeEl" style="table-layout:auto;width:auto;margin:0 3px;" class="{baseCls}-inner" cellspacing="0">‘,        ‘<tbody><tr>‘,        ‘<td>{%this.renderHourBtn(values,out)%}</td>‘,        ‘<td>{%this.renderMinuteBtn(values,out)%}</td>‘,        ‘<td>{%this.renderSecondBtn(values,out)%}</td>‘,        ‘</tr></tbody>‘,        ‘</table>‘,        ‘<tpl if="showToday">‘,        ‘<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer">{%this.renderOkBtn(values, out)%}{%this.renderTodayBtn(values, out)%}</div>‘,        ‘</tpl>‘,        ‘</div>‘,        {            firstInitial: function(value) {                return Ext.picker.Date.prototype.getDayInitial(value);            },            isEndOfWeek: function(value) {                // convert from 1 based index to 0 based                // by decrementing value once.                value--;                var end = value % 7 === 0 && value !== 0;                return end ? ‘</tr><tr role="row">‘ : ‘‘;            },            renderTodayBtn: function(values, out) {                Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);            },            renderMonthBtn: function(values, out) {                Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);            },            renderHourBtn: function (values, out) {                Ext.DomHelper.generateMarkup(values.$comp.hourBtn.getRenderTree(), out);            },            renderMinuteBtn: function (values, out) {                Ext.DomHelper.generateMarkup(values.$comp.minuteBtn.getRenderTree(), out);            },            renderSecondBtn: function (values, out) {                Ext.DomHelper.generateMarkup(values.$comp.secondBtn.getRenderTree(), out);            },            renderOkBtn: function (values, out) {                Ext.DomHelper.generateMarkup(values.$comp.okBtn.getRenderTree(), out);            }        }    ],    todayText: ‘现在‘,    ariaTitle: ‘Date Picker: {0}‘,    ariaTitleDateFormat: ‘F d‘,    todayTip: ‘‘,    minText: ‘This date is before the minimum date‘,    maxText: ‘This date is after the maximum date‘,    disabledDaysText: ‘Disabled‘,    disabledDatesText: ‘Disabled‘,    nextText: ‘下个月 (Control+Right)‘,    prevText: ‘上个月 (Control+Left)‘,    monthYearText: ‘选择一个月 (Control+Up/Down 来改变年份)‘,    monthYearFormat: ‘F Y‘,    startDay: 0,    showToday: true,    disableAnim: false,    baseCls: Ext.baseCSSPrefix + ‘datepicker‘,    longDayFormat: ‘F d, Y‘,    initHour: 12, // 24-hour format

numDays: 42,    initComponent: function() {        var me = this,            clearTime = function(v){return v};        //clearTime = Ext.Date.clearTime;

me.selectedCls = me.baseCls + ‘-selected‘;        me.disabledCellCls = me.baseCls + ‘-disabled‘;        me.prevCls = me.baseCls + ‘-prevday‘;        me.activeCls = me.baseCls + ‘-active‘;        me.cellCls = me.baseCls + ‘-cell‘;        me.nextCls = me.baseCls + ‘-prevday‘;        me.todayCls = me.baseCls + ‘-today‘;

if (!me.format) {            me.format = Ext.Date.defaultFormat;        }        if (!me.dayNames) {            me.dayNames = Ext.Date.dayNames;        }        me.dayNames = me.dayNames.slice(me.startDay).concat(me.dayNames.slice(0, me.startDay));

me.callParent();

me.value = me.value ? clearTime(me.value, true) : clearTime(new Date());

me.initDisabledDays();    },    okHandler: function () {        var me = this,            btn = me.okBtn;

if (btn && !btn.disabled) {            var d=me.value;            d.setHours(me.hourBtn.getValue());            d.setMinutes(me.minuteBtn.getValue());            d.setSeconds(me.secondBtn.getValue());            me.setValue(d);            me.fireEvent(‘select‘, me, me.value);            me.onSelect();        }        return me;    },    // Keep the tree structure correct for Ext.form.field.Picker input fields which poke a ‘pickerField‘ reference down into their pop-up pickers.    getRefOwner: function() {        return this.pickerField || this.callParent();    },

getRefItems: function() {        var results = [],            monthBtn = this.monthBtn,            todayBtn = this.todayBtn;

if (monthBtn) {            results.push(monthBtn);        }

if (todayBtn) {            results.push(todayBtn);        }        results.push(me.hourBtn);        results.push(me.minuteBtn);        results.push(me.secondBtn);        return results;    },

beforeRender: function() {        var me = this,            days = new Array(me.numDays),            today = Ext.Date.format(new Date(), me.format);

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

me.monthBtn = new Ext.button.Split({            ownerCt: me,            ownerLayout: me.getComponentLayout(),            text: ‘‘,            tooltip: me.monthYearText,            listeners: {                click: me.doShowMonthPicker,                arrowclick: me.doShowMonthPicker,                scope: me            }        });

if (me.showToday) {            me.todayBtn = new Ext.button.Button({                ownerCt: me,                ownerLayout: me.getComponentLayout(),                text: Ext.String.format(me.todayText, today),                tooltip: Ext.String.format(me.todayTip, today),                tooltipType: ‘title‘,                cls:‘my-action-close‘,                handler: me.selectToday,                scope: me            });        }        me.hourBtn = new Ext.form.field.Number({            minValue: 0,hideTrigger:false,            maxValue: 23,            step: 1,            width: 55        });        me.minuteBtn = new Ext.form.field.Number({            minValue: 0,hideTrigger:false,            maxValue: 59,            step: 1,            width: 70,            labelWidth: 10,            fieldLabel: ‘&nbsp;‘        });        me.secondBtn = new Ext.form.field.Number({            minValue: 0,hideTrigger:false,            maxValue: 59,            step: 1,            width: 70,            labelWidth: 10,            fieldLabel: ‘&nbsp;‘        });        me.okBtn = new Ext.button.Button({            ownerCt: me,            cls:‘my-action-close‘,            //ownerLayout: me.getComponentLayout(),            text: me.okText,            tooltip: me.okTip,            tooltipType: ‘title‘,            handler: me.okHandler,            scope: me        });

me.callParent();

Ext.applyIf(me, {            renderData: {}        });

Ext.apply(me.renderData, {            dayNames: me.dayNames,            showToday: me.showToday,            prevText: me.prevText,            nextText: me.nextText,            days: days        });

me.protoEl.unselectable();    },

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;‘            });

me.self.prototype.width = widthEl.getWidth() + padding.left + padding.right;        widthEl.destroy();    },    onRender: function(container, position) {        var me = this;

me.callParent(arguments);

me.cells = me.eventEl.select(‘tbody td‘);        me.textNodes = me.eventEl.query(‘tbody td div‘);

me.eventEl.set({ ‘aria-labelledby‘: me.monthBtn.id });

me.mon(me.eventEl, {            scope: me,            mousewheel: me.handleMouseWheel,            click: {                fn: me.handleDateClick,                delegate: ‘div.‘ + me.baseCls + ‘-date‘            }        });    },    initEvents: function(){        var me = this,            pickerField = me.pickerField,            eDate = Ext.Date,            day = eDate.DAY;

me.callParent();        if (!me.focusable) {            me.el.on({                mousedown: me.onMouseDown            });        }        me.prevRepeater = new Ext.util.ClickRepeater(me.prevEl, {            handler: me.showPrevMonth,            scope: me,            preventDefault: true,            stopDefault: true        });

me.nextRepeater = new Ext.util.ClickRepeater(me.nextEl, {            handler: me.showNextMonth,            scope: me,            preventDefault: true,            stopDefault: true        });

// Read key events through our pickerField if we are bound to one        me.keyNav = new Ext.util.KeyNav(pickerField ? pickerField.inputEl : me.eventEl, Ext.apply({            scope: me,

// Must capture event so that the Picker sees it before the Field.            capture: true,

left: function(e) {                if (e.ctrlKey) {                    me.showPrevMonth();                } else {                    me.update(eDate.add(me.activeDate, day, -1));                }            },

right: function(e){                if (e.ctrlKey) {                    me.showNextMonth();                } else {                    me.update(eDate.add(me.activeDate, day, 1));                }            },

up: function(e) {                if (e.ctrlKey) {                    me.showNextYear();                } else {                    me.update(eDate.add(me.activeDate, day, -7));                }            },

down: function(e) {                if (e.ctrlKey) {                    me.showPrevYear();                } else {                    me.update(eDate.add(me.activeDate, day, 7));                }            },

pageUp: function(e) {                if (e.ctrlKey) {                    me.showPrevYear();                } else {                    me.showPrevMonth();                }            },

pageDown: function(e) {                if (e.ctrlKey) {                    me.showNextYear();                } else {                    me.showNextMonth();                }            },

tab: function (e) {                me.handleTabClick(e);

// Allow default behaviour of TAB - it MUST be allowed to navigate.                return true;            },

enter: function(e) {                me.handleDateClick(e, me.activeCell.firstChild);            },

space: function() {                me.setValue(new Date(me.activeCell.firstChild.dateValue));                var startValue = me.startValue,                    value = me.value,                    pickerValue;

if (pickerField) {                    pickerValue = pickerField.getValue();                    if (pickerValue && startValue && pickerValue.getTime() === value.getTime()) {                        pickerField.setValue(startValue);                    } else {                        pickerField.setValue(value);                    }                }            },

home: function(e) {                me.update(eDate.getFirstDateOfMonth(me.activeDate));            },

end: function(e) {                me.update(eDate.getLastDateOfMonth(me.activeDate));            }        }, me.keyNavConfig));

if (me.disabled) {            me.syncDisabled(true);        }        me.update(me.value);    },

onMouseDown: function(e) {        //e.preventDefault();    },    handleTabClick: function (e) {        var me = this,            t = me.getSelectedDate(me.activeDate),            handler = me.handler;

if (!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) {            me.setValue(new Date(t.dateValue));            me.fireEvent(‘select‘, me, me.value);            if (handler) {                handler.call(me.scope || me, me, me.value);            }            me.onSelect();        }    },    getSelectedDate: function (date) {        var me = this,            t = date.getTime(),            cells = me.cells,            cls = me.selectedCls,            cellItems = cells.elements,            cLen = cellItems.length,            cell, c;

cells.removeCls(cls);

for (c = 0; c < cLen; c++) {            cell = cellItems[c].firstChild;            if (cell.dateValue == t) {                return cell;            }        }        return null;    },    initDisabledDays: function(){        var me = this,            dd = me.disabledDates,            re = ‘(?:‘,            len,            d, dLen, dI;

if(!me.disabledDatesRE && dd){            len = dd.length - 1;

dLen = dd.length;

for (d = 0; d < dLen; d++) {                dI = dd[d];

re += Ext.isDate(dI) ? ‘^‘ + Ext.String.escapeRegex(Ext.Date.dateFormat(dI, me.format)) + ‘$‘ : dI;                if (d !== len) {                    re += ‘|‘;                }            }

me.disabledDatesRE = new RegExp(re + ‘)‘);        }    },    setDisabledDates: function(dd){        var me = this;

if (Ext.isArray(dd)) {            me.disabledDates = dd;            me.disabledDatesRE = null;        } else {            me.disabledDatesRE = dd;        }        me.initDisabledDays();        me.update(me.value, true);        return me;    },    setDisabledDays: function(dd){        this.disabledDays = dd;        return this.update(this.value, true);    },    setMinDate: function(dt){        this.minDate = dt;        return this.update(this.value, true);    },    setMaxDate: function(dt){        this.maxDate = dt;        return this.update(this.value, true);    },    _valueSplit: function(v) {        if(Ext.isDate(v)) {            v = Ext.Date.format(v, ‘H:i:s‘);        }        var split = v.split(‘:‘);        return {            h: split.length > 0 ? split[0] : 0,            m: split.length > 1 ? split[1] : 0,            s: split.length > 2 ? split[2] : 0        };    },    setRawValue: function(value) {        var v = this._valueSplit(value);        this.hourBtn.setValue(v.h);        this.minuteBtn.setValue(v.m);        this.secondBtn.setValue(v.s);    },    setValue: function(value){        // If passed a null value just pass in a new date object.        this.value = value || new Date();        this.setRawValue(value);        return this.update(this.value);    },    getValue: function(){        return this.value;    },    getDayInitial: function(value){        return value.substr(0,1);    },    onEnable: function(){        this.callParent();        this.syncDisabled(false);        this.update(this.activeDate);

},    onShow: function(){        this.callParent();        this.syncDisabled(false);        if (this.pickerField) {            this.startValue = this.pickerField.getValue();        }    },    onHide: function(){        this.callParent();        this.syncDisabled(true);    },    onDisable: function(){        this.callParent();        this.syncDisabled(true);    },    getActive: function(){        return this.activeDate || this.value;    },    runAnimation: function(isHide){        var picker = this.monthPicker,            options = {                duration: 200,                callback: function() {                    picker.setVisible(!isHide);                }            };

if (isHide) {            picker.el.slideOut(‘t‘, options);        } else {            picker.el.slideIn(‘t‘, options);        }    },    hideMonthPicker: function(animate){        var me = this,            picker = me.monthPicker;

if (picker && picker.isVisible()) {            if (me.shouldAnimate(animate)) {                me.runAnimation(true);            } else {                picker.hide();            }        }        return me;    },

doShowMonthPicker: function(){        // Wrap in an extra call so we can prevent the button        // being passed as an animation parameter.        this.showMonthPicker();    },

doHideMonthPicker: function() {        // Wrap in an extra call so we can prevent this        // being passed as an animation parameter        this.hideMonthPicker();    },    showMonthPicker: function(animate) {        var me = this,            el = me.el,            picker;

if (me.rendered && !me.disabled) {            picker = me.createMonthPicker();            if (!picker.isVisible()) {                picker.setValue(me.getActive());                picker.setSize(el.getSize());

// Null out floatParent so that the [-1, -1] position is not made relative to this                picker.floatParent = null;                picker.setPosition(-el.getBorderWidth(‘l‘), -el.getBorderWidth(‘t‘));                if (me.shouldAnimate(animate)) {                    me.runAnimation(false);                } else {                    picker.show();                }            }        }        return me;    },    shouldAnimate: function(animate) {        return Ext.isDefined(animate) ? animate : !this.disableAnim;    },    createMonthPicker: function() {        var me = this,            picker = me.monthPicker;

if (!picker) {            me.monthPicker = picker = new Ext.picker.Month({                renderTo: me.el,                ownerCmp: me,                floating: true,                padding: me.padding,                shadow: false,                small: me.showToday === false,                listeners: {                    scope: me,                    cancelclick: me.onCancelClick,                    okclick: me.onOkClick,                    yeardblclick: me.onOkClick,                    monthdblclick: me.onOkClick                }            });            if (!me.disableAnim) {                // hide the element if we‘re animating to prevent an initial flicker                picker.el.setStyle(‘display‘, ‘none‘);            }            picker.hide();            me.on(‘beforehide‘, me.doHideMonthPicker, me);        }        return picker;    },    onOkClick: function(picker, value) {        var me = this,            month = value[0],            year = value[1],            date = new Date(year, month, me.getActive().getDate());

if (date.getMonth() !== month) {            // ‘fix‘ the JS rolling date conversion if needed            date = Ext.Date.getLastDateOfMonth(new Date(year, month, 1));        }        date.setHours(me.hourBtn.getValue());        date.setMinutes(me.minuteBtn.getValue());        date.setSeconds(me.secondBtn.getValue());        me.setValue(date);        me.hideMonthPicker();    },    onCancelClick: function() {        this.selectedUpdate(this.activeDate);        this.hideMonthPicker();    },    showPrevMonth: function(e) {        return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, -1));    },    showNextMonth: function(e) {        return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.MONTH, 1));    },    showPrevYear: function() {        return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, -1));    },    showNextYear: function() {        return this.setValue(Ext.Date.add(this.activeDate, Ext.Date.YEAR, 1));    },    handleMouseWheel: function(e) {        e.stopEvent();        if(!this.disabled){            var delta = e.getWheelDelta();            if(delta > 0){                this.showPrevMonth();            } else if(delta < 0){                this.showNextMonth();            }        }    },    handleDateClick: function(e, t) {        var me = this,            handler = me.handler;

e.stopEvent();        if(!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)){            var d=new Date(t.dateValue);            d.setHours(me.hourBtn.getValue());            d.setMinutes(me.minuteBtn.getValue());            d.setSeconds(me.secondBtn.getValue());            me.setValue(d);            me.fireEvent(‘select‘, me, me.value);            if (handler) {                handler.call(me.scope || me, me, me.value);            }            me.onSelect();        }    },    onSelect: function() {        if (this.hideOnSelect) {            this.hide();        }    },    selectToday: function() {        var me = this,            btn = me.todayBtn,            handler = me.handler;

if (btn && !btn.disabled) {            me.setValue(new Date());            me.fireEvent(‘select‘, me, me.value);            if (handler) {                handler.call(me.scope || me, me, me.value);            }            me.onSelect();        }        return me;    },    selectedUpdate: function(date) {        var me        = this,            //t         = date.getTime(),            tt=Ext.Date.clearTime(date,true),            t         = tt.getTime(),            cells     = me.cells,            cls       = me.selectedCls,            c,            cLen      = cells.getCount(),            cell;

cell = me.activeCell;        if (cell) {            Ext.fly(cell).removeCls(cls);            cell.setAttribute(‘aria-selected‘, false);        }

for (c = 0; c < cLen; c++) {            cell = cells.item(c);            if (me.textNodes[c].dateValue == t) {                me.activeCell = cell.dom;                me.eventEl.dom.setAttribute(‘aria-activedescendant‘, cell.dom.id);                cell.dom.setAttribute(‘aria-selected‘, true);                cell.addCls(cls);                me.fireEvent(‘highlightitem‘, me, cell);                break;            }        }    },    fullUpdate: function(date) {        var me = this,            cells = me.cells.elements,            textNodes = me.textNodes,            disabledCls = me.disabledCellCls,            eDate = Ext.Date,            i = 0,            extraDays = 0,            newDate = +eDate.clearTime(date, true),            today = +eDate.clearTime(new Date()),            min = me.minDate ? eDate.clearTime(me.minDate, true) : Number.NEGATIVE_INFINITY,            max = me.maxDate ? eDate.clearTime(me.maxDate, true) : Number.POSITIVE_INFINITY,            ddMatch = me.disabledDatesRE,            ddText = me.disabledDatesText,            ddays = me.disabledDays ? me.disabledDays.join(‘‘) : false,            ddaysText = me.disabledDaysText,            format = me.format,            days = eDate.getDaysInMonth(date),            firstOfMonth = eDate.getFirstDateOfMonth(date),            startingPos = firstOfMonth.getDay() - me.startDay,            previousMonth = eDate.add(date, eDate.MONTH, -1),            ariaTitleDateFormat = me.ariaTitleDateFormat,            prevStart, current, disableToday, tempDate, setCellClass, html, cls,            formatValue, value;

if (startingPos < 0) {            startingPos += 7;        }

days += startingPos;        prevStart = eDate.getDaysInMonth(previousMonth) - startingPos;        current = new Date(previousMonth.getFullYear(), previousMonth.getMonth(), prevStart, me.initHour);

if (me.showToday) {            tempDate = eDate.clearTime(new Date());            disableToday = (tempDate < min || tempDate > max ||            (ddMatch && format && ddMatch.test(eDate.dateFormat(tempDate, format))) ||            (ddays && ddays.indexOf(tempDate.getDay()) != -1));

if (!me.disabled) {                me.todayBtn.setDisabled(disableToday);            }        }

setCellClass = function(cellIndex, cls){            var cell = cells[cellIndex];

value = +eDate.clearTime(current, true);            cell.setAttribute(‘aria-label‘, eDate.format(current, ariaTitleDateFormat));            // store dateValue number as an expando            cell.firstChild.dateValue = value;            if (value == today) {                cls += ‘ ‘ + me.todayCls;                cell.firstChild.title = me.todayText;

// Extra element for ARIA purposes                me.todayElSpan = Ext.DomHelper.append(cell.firstChild, {                    tag: ‘span‘,                    cls: Ext.baseCSSPrefix + ‘hidden-clip‘,                    html: me.todayText                }, true);            }            if (value == newDate) {                me.activeCell = cell;                me.eventEl.dom.setAttribute(‘aria-activedescendant‘, cell.id);                cell.setAttribute(‘aria-selected‘, true);                cls += ‘ ‘ + me.selectedCls;                me.fireEvent(‘highlightitem‘, me, cell);            } else {                cell.setAttribute(‘aria-selected‘, false);            }

if (value < min) {                cls += ‘ ‘ + disabledCls;                cell.setAttribute(‘aria-label‘, me.minText);            }            else if (value > max) {                cls += ‘ ‘ + disabledCls;                cell.setAttribute(‘aria-label‘, me.maxText);            }            else if (ddays && ddays.indexOf(current.getDay()) !== -1){                cell.setAttribute(‘aria-label‘, ddaysText);                cls += ‘ ‘ + disabledCls;            }            else if (ddMatch && format){                formatValue = eDate.dateFormat(current, format);                if(ddMatch.test(formatValue)){                    cell.setAttribute(‘aria-label‘, ddText.replace(‘%0‘, formatValue));                    cls += ‘ ‘ + disabledCls;                }            }            cell.className = cls + ‘ ‘ + me.cellCls;        };

for(; i < me.numDays; ++i) {            if (i < startingPos) {                html = (++prevStart);                cls = me.prevCls;            } else if (i >= days) {                html = (++extraDays);                cls = me.nextCls;            } else {                html = i - startingPos + 1;                cls = me.activeCls;            }            textNodes[i].innerHTML = html;            current.setDate(current.getDate() + 1);            setCellClass(i, cls);        }

me.monthBtn.setText(Ext.Date.format(date, me.monthYearFormat));    },    update: function(date, forceRefresh) {        var me = this,            active = me.activeDate;

if (me.rendered) {            me.activeDate = date;            if(!forceRefresh && active && me.el && active.getMonth() == date.getMonth() && active.getFullYear() == date.getFullYear()){                me.selectedUpdate(date, active);            } else {                me.fullUpdate(date, active);            }        }        return me;    },    beforeDestroy: function() {        var me = this;        if (me.rendered) {            Ext.destroy(                me.keyNav,                me.monthPicker,                me.monthBtn,                me.nextRepeater,                me.prevRepeater,                me.todayBtn,                me.todayElSpan,                me.hourBtn,                me.minuteBtn,                me.secondBtn            );            delete me.textNodes;            delete me.cells.elements;        }        me.callParent();    },

privates: {        // TODO: Refactor as a Container.        finishRenderChildren: function () {            var me = this;

me.callParent();            me.monthBtn.finishRender();            if (me.showToday) {                me.todayBtn.finishRender();            }            me.hourBtn.finishRender();            me.minuteBtn.finishRender();            me.secondBtn.finishRender();            me.okBtn.finishRender();        },        getFocusEl: function() {            return this.eventEl;        },        syncDisabled: function (disabled) {            var me = this,                keyNav = me.keyNav;            if (keyNav) {                keyNav.setDisabled(disabled);                me.prevRepeater.setDisabled(disabled);                me.nextRepeater.setDisabled(disabled);                if (me.todayBtn) {                    me.todayBtn.setDisabled(disabled);                }            }        }    },    constrain:true});

Ext.define(‘Ux.form.field.DateTime‘, {    extend:‘Ext.form.field.Picker‘,    alias: ‘widget.datetimefield‘,    format: "Y-m-d H:i:s",    //format : "m/d/Y",    altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",    disabledDaysText : "",    disabledDatesText : "",    minText : "日期必须大于最小允许日期{0}",    maxText : "日期必须小于最大允许日期{0}",    invalidText : "{0} 无效的日期格式 - 必须符合此格式 {1}",    triggerCls : Ext.baseCSSPrefix + ‘form-date-trigger‘,    showToday : true,    useStrict: undefined,    initTime: ‘12‘, // 24 hour format

initTimeFormat: ‘H‘,

matchFieldWidth: false,    startDay: 0,    valuePublishEvent: [‘select‘, ‘blur‘],

initComponent : function(){        var me = this,            isString = Ext.isString,            min, max;

min = me.minValue;        max = me.maxValue;        if(isString(min)){            me.minValue = me.parseDate(min);        }        if(isString(max)){            me.maxValue = me.parseDate(max);        }        me.disabledDatesRE = null;        me.initDisabledDays();

me.callParent();    },

initValue: function() {        var me = this,            value = me.value;        if (Ext.isString(value)) {            me.value = me.rawToValue(value);        }

me.callParent();    },    initDisabledDays : function(){        if(this.disabledDates){            var dd   = this.disabledDates,                len  = dd.length - 1,                re   = "(?:",                d,                dLen = dd.length,                date;

for (d = 0; d < dLen; d++) {                date = dd[d];

re += Ext.isDate(date) ? ‘^‘ + Ext.String.escapeRegex(date.dateFormat(this.format)) + ‘$‘ : date;                if (d !== len) {                    re += ‘|‘;                }            }

this.disabledDatesRE = new RegExp(re + ‘)‘);        }    },    setDisabledDates : function(disabledDates){        var me = this,            picker = me.picker;

me.disabledDates = disabledDates;        me.initDisabledDays();        if (picker) {            picker.setDisabledDates(me.disabledDatesRE);        }    },    setDisabledDays : function(disabledDays){        var picker = this.picker;

this.disabledDays = disabledDays;        if (picker) {            picker.setDisabledDays(disabledDays);        }    },    setMinValue : function(value){        var me = this,            picker = me.picker,            minValue = (Ext.isString(value) ? me.parseDate(value) : value);

me.minValue = minValue;        if (picker) {            picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue));            picker.setMinDate(minValue);        }    },    setMaxValue : function(value){        var me = this,            picker = me.picker,            maxValue = (Ext.isString(value) ? me.parseDate(value) : value);

me.maxValue = maxValue;        if (picker) {            picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue));            picker.setMaxDate(maxValue);        }    },    getErrors: function(value) {        value = arguments.length > 0 ? value : this.formatDate(this.processRawValue(this.getRawValue()));

var me = this,            format = Ext.String.format,            clearTime = Ext.Date.clearTime,            errors = me.callParent([value]),            disabledDays = me.disabledDays,            disabledDatesRE = me.disabledDatesRE,            minValue = me.minValue,            maxValue = me.maxValue,            len = disabledDays ? disabledDays.length : 0,            i = 0,            svalue,            fvalue,            day,            time;

if (value === null || value.length < 1) { // if it‘s blank and textfield didn‘t flag it then it‘s valid            return errors;        }

svalue = value;        value = me.parseDate(value);        if (!value) {            errors.push(format(me.invalidText, svalue, Ext.Date.unescapeFormat(me.format)));            return errors;        }

time = value.getTime();        if (minValue && time < clearTime(minValue).getTime()) {            errors.push(format(me.minText, me.formatDateValid(minValue)));        }

if (maxValue && time > clearTime(maxValue).getTime()) {            errors.push(format(me.maxText, me.formatDateValid(maxValue)));        }

if (disabledDays) {            day = value.getDay();

for(; i < len; i++) {                if (day === disabledDays[i]) {                    errors.push(me.disabledDaysText);                    break;                }            }        }

fvalue = me.formatDate(value);        if (disabledDatesRE && disabledDatesRE.test(fvalue)) {            errors.push(format(me.disabledDatesText, fvalue));        }

return errors;    },

rawToValue: function(rawValue) {        return this.parseDate(rawValue) || rawValue || null;    },

valueToRaw: function(value) {        return this.formatDate(this.parseDate(value));    },    safeParse : function(value, format) {        var me = this,            utilDate = Ext.Date,            result = null,            strict = me.useStrict,            parsedDate;

if (utilDate.formatContainsHourInfo(format)) {            // if parse format contains hour information, no DST adjustment is necessary            result = utilDate.parse(value, format, strict);        } else {            // set time to 12 noon, then clear the time            parsedDate = utilDate.parse(value + ‘ ‘ + me.initTime, format + ‘ ‘ + me.initTimeFormat, strict);            if (parsedDate) {                result = utilDate.clearTime(parsedDate);            }        }        return result;    },    getSubmitValue: function() {        var format = this.submitFormat || this.format,            value = this.getValue();

return value ? Ext.Date.format(value, format) : ‘‘;    },    parseDate : function(value) {        if(!value || Ext.isDate(value)){            return value;        }

var me = this,            val = me.safeParse(value, me.format),            altFormats = me.altFormats,            altFormatsArray = me.altFormatsArray,            i = 0,            len;

if (!val && altFormats) {            altFormatsArray = altFormatsArray || altFormats.split(‘|‘);            len = altFormatsArray.length;            for (; i < len && !val; ++i) {                val = me.safeParse(value, altFormatsArray[i]);            }        }        return val;    },    formatDate: function(date){        return Ext.isDate(date) ? Ext.Date.dateFormat(date, this.format) : date;    },    formatDateValid:function(date){        return Ext.isDate(date) ? Ext.Date.dateFormat(date, "Y-m-d") : date;    },    createPicker: function() {        var me = this,            format = Ext.String.format;        return new Ux.picker.DateTime({            pickerField: me,            //ownerCt: me.ownerCt,            floating: true,            focusable: false,            //focusOnShow: true,            hidden: true,            minDate: me.minValue,            maxDate: me.maxValue,            disabledDatesRE: me.disabledDatesRE,            disabledDatesText: me.disabledDatesText,            disabledDays: me.disabledDays,            disabledDaysText: me.disabledDaysText,            format: me.format,            showToday: me.showToday,            startDay: me.startDay,            minText: format(me.minText, me.formatDate(me.minValue)),            maxText: format(me.maxText, me.formatDate(me.maxValue)),            listeners: {                scope: me,                select: me.onSelect            },            keyNavConfig: {                esc: function () {                    me.collapse();                }            }        });    },    onSelect: function(m, d) {        var me = this;        me.setValue(d);        me.fireEvent(‘select‘, me, d);        me.collapse();    },    onExpand: function() {        var value = this.getValue();        this.picker.setValue(Ext.isDate(value) ? value : new Date());    },

// private    onBlur: function(e) {        var me = this,            v = me.rawToValue(me.getRawValue());        if (Ext.isDate(v)) {            me.setValue(v);        }        me.callParent([e]);    },    collapseIf: function(e) {        var me = this;        me.isDestroyed=true;        var btns=me.picker.el.query(‘.my-action-close‘,false);        var okBtnEl=btns[0];        var nowEl=btns[1];        if(e.within(okBtnEl,false,true)||e.within(nowEl,false,true)||!me.owns(e.target) || e.within(me.bodyEl, false, true)){            me.isDestroyed=false;        }        if(e.within(me.picker.timeEl,false,true)){            me.isDestroyed=true;        }        if (!me.isDestroyed  && !me.owns(e.target)  && !e.within(me.bodyEl, false, true)) {            me.collapse(e);        }    }});
时间: 2024-11-06 03:35:51

Extjs 5.x 日期时间控件DateTime源码的相关文章

jquery-ui日期时间控件实现

日期控件和时间控件为独立控件,日期时间控件要同一时候导入日期控件和时间控件的js,然后在日期控件加入时间控件显示參数,没有导入时间控件js.日期控件函数设置的时间控件參将包错 日期控件官网网址:http://jqueryui.com/ 日期控件js:jquery-ui.js 相应函数及默认属性设置:function Datepicker() 时间控件官网网址:http://plugins.jquery.com/jt.timepicker/ 时间控件js:jquery-ui-timepicker-

精确到分钟的日期时间控件

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>精确到分钟的日期时间控件-格栅除污机-石家庄瑜伽馆</title> <meta http-equiv="content-type" content="text/html;charset=gb2312"> <

jquery 的日期时间控件(年月日时分秒)

<!-- import package --> <script type="text/javascript" src="JS/jquery.js"></script> <script type="text/javascript" src="JS/jquery-ui-1.7.3/ui/jquery-ui-1.7.3.custom.js"></script> <sc

日期时间的选择器ios源码

这个源码案例是一个日期时间的选择器,源码DVDatePickerTableViewCell,DVDatePickerTableViewCell是使用Swift写的cell.可以在tebleView中提供一个日期时间的选择器,并持续显示在Cell上.效果图: <ignore_js_op> 使用方法: DVDatePickerTableViewCell想平常使用cell那样使用即可. var cells:NSArray = [] cells = [[DVDatePickerTableViewCel

Android日期时间控件DatePickerDialog和TimePickerDialog

1.DatePickerDialog 在一些万年历.日程表等APP上我们经常可以看到日期选择控件,由于很少有用户会老老实实的手工输入日期,所以该控件的作用就是为了控制用户的输入格式,在Android中有一个日期选择控件叫DatePicker,但是该空间并非弹窗模式,而是在页面上占据一块区域,这种方式很影响布局的美观性,所以更多我们是采用弹窗作为日期控件的显示方式,这个以弹窗方式显示的日期控件叫做DatePickerDialog,显示效果如下 代码获取控件选择时间的方法如下: public cla

开源日历控件DatePicker源码解析

在一些项目开发中,会使用日历去标识事务,所以根据美工出的效果图,我们可以采用不同的方法去实现.比如通过GridView扣扣你敢.自定义View实现日历控件,这些都是我们解决问题的手段,我也实现过一个自定义日历控件(Android自定义控件之日历控件55993)),由于我只是粗糙的进行实现,并没有进行过多的在控件的可扩展性上进行打磨设计,所以在本篇文章中,我秉着学习的态度分析下爱哥的鼎力巨作DatePicker-DatePicker. DatePicker开源项目地址:[https://githu

Android下拉刷新控件SwipeRefreshLayout源码浅析

SwipeRefreshLayout是Android官方的下拉刷新控件,使用简单,界面美观,不熟悉的朋友可以随便搜索了解一下,这里就不废话了,直接进入正题. 这种下拉刷新控件的原理不难,基本就是监听手指的运动,获取手指的坐标,通过计算判断出是哪种操作,然后就是回调相应的接口了.SwipeRefreshLayout是继承自ViewGroup的,根据Android的事件分发机制,触摸事件应该是先传递到ViewGroup,根据onInterceptTouchEvent的返回值决定是否拦截事件的,那么就

手机端日期时间控件(mobiscroll)设置年月日时分秒及时间格式

mobiscroll是个很好用的jquery日期插件,它可以实现在移动端滚动选择日期. 网上有很多相关的介绍:别人写过的我在这里不再重复,只记录自己的一些经验 首选,我用的是mobiscroll-2.13.2.full.min.js:至于其他版本没测试过,不敢保证使用效果完全相同. 进入主题,项目需要时间选择器提供年月日时分秒的格式. 网上搜索了一圈,只发现年月日时分的设置方法. 最后在官网找到解决办法 直接上代码 timeWheels: 'HHiiss',//HH:24小时制:hh:12小时制

ECSTORE日期时间控件转换为时间戳的方法

如果你在后台使用<{input type=”time” name=”time”}>的话,后台获取到的表单数据为: 21 ["_DTYPE_TIME"]=> 22 array(1) { 23 [0]=> 24 string(4) "time" 25 } 26 ["time"]=> 27 string(9) "2014-11-7" 28 ["_DTIME_"]=> 29 ar