/** * 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: ‘ ‘ }); me.secondBtn = new Ext.form.field.Number({ minValue: 0,hideTrigger:false, maxValue: 59, step: 1, width: 70, labelWidth: 10, fieldLabel: ‘ ‘ }); 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