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);
}
}
});
posted @ 2017-08-23 12:12  拉风的帅猫  阅读(695)  评论(0编辑  收藏  举报