初学这个extjs,还停留在使用的阶段,也没有时间去深入学习,然后突发奇想,想用个时间搜索,但是在5.0的版本中,是不支持日期和时间同时存在的,我只用了个日期,但是感觉有点别扭,虽然不是很强制一定要日期+时间.国际惯例,百度一下.发现上面有很多自定义的模板,然后我就拿来改了改,,然后为什么要写一个这样的博客,emmmm....也记录下学习过程的感悟吧.
先附上前辈的博客地址:https://blog.csdn.net/yangholmes_blog/article/details/51330555
然后因为自己也改动了一部分,所以全部记录下来吧!
TimePickerField:
Ext.define('Ext.ux.TimePickerField', {
extend: 'Ext.form.field.Base',
alias: 'widget.timepicker',
alternateClassName: 'Ext.form.field.TimePickerField',
requires: ['Ext.form.field.Number'],
inputType: 'text',
fieldLabel: '时间',
labelWidth: 40,
style: 'padding:4px 0; margin: 0; ',
value: null,
spinnerCfg: {
width: 50,
},
initComponent: function() {
var me = this;
me.value = me.value || Ext.Date.format(new Date(), 'H:i:s');
me.callParent(arguments);
me.spinners = [];
var cfg = Ext.apply({}, me.spinnerCfg, {
// readOnly: me.readOnly,
disabled: me.disabled,
style: 'float: left',
listeners: {
change: {
fn: me.onSpinnerChange,
scope: me
}
}
});
me.hoursSpinner = Ext.create('Ext.form.field.Number', Ext.apply({}, cfg, {
// minValue: -1,
// maxValue: 24,
minNum: 0,
maxNum: 23,
}));
me.minutesSpinner = Ext.create('Ext.form.field.Number', Ext.apply({}, cfg, {
// minValue: -1,
// maxValue: 60,
minNum: 0,
maxNum: 59,
}));
me.secondsSpinner = Ext.create('Ext.form.field.Number', Ext.apply({}, cfg, {
// minValue: -1,
// MAXVALUE: 60,
minNum: 0,
maxNum: 59,
}));
me.spinners.push(me.hoursSpinner, me.minutesSpinner, me.secondsSpinner);
},
onRender: function() {
var me = this, spinnerWrapDom, spinnerWrap;
me.callParent(arguments);
spinnerWrap = Ext.get(Ext.DomQuery.selectNode('div', this.el.dom));
me.callSpinnersFunction('render', spinnerWrap);
this.el.dom.getElementsByTagName('input')[0].style.display = 'none';
var newTimePicker = Ext.DomHelper.append(spinnerWrap, {
tag: 'div',
cls: 'x-form-clear-left'
}, true);
this.setRawValue(this.value);
},
_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
};
},
onSpinnerChange: function() {
if(!this.rendered) {
return;
}
//限制时间范围
var args = arguments; //this, newValue, oldValue, eOpts
args[0].setValue( (args[1]>args[0].maxNum) ? args[0].minNum : args[0].value );
args[0].setValue( (args[1]<args[0].minNum) ? args[0].maxNum : args[0].value );
this.fireEvent('change', this, this.getValue(), this.getRawValue());
},
// 依次调用各输入框函数, call each spinner's function
callSpinnersFunction: function(funName, args) {
for(var i = 0; i < this.spinners.length; i++) {
if( this.spinners[i][funName] != null && this.spinners[i][funName] != undefined ){
this.spinners[i][funName](args);
}
}
},
getRawValue: function() {
if(!this.rendered) {
var date = this.value || new Date();
return this._valueSplit(date);
}
else {
return {
h: this.hoursSpinner.getValue(),
m: this.minutesSpinner.getValue(),
s: this.secondsSpinner.getValue()
};
}
},
setRawValue: function(value) {
var v = this._valueSplit(value);
if(this.hoursSpinner) {
this.hoursSpinner.setValue(v.h);
this.minutesSpinner.setValue(v.m);
this.secondsSpinner.setValue(v.s);
}
},
getValue: function() {
var v = this.getRawValue();
return Ext.String.leftPad(v.h, 2, '0') + ':' + Ext.String.leftPad(v.m, 2, '0') + ':'
+ Ext.String.leftPad(v.s, 2, '0');
},
setValue: function(value) {
this.value = Ext.isDate(value) ? Ext.Date.format(value, 'H:i:s') : value;
if(!this.rendered) {
return;
}
this.setRawValue(this.value);
this.validate();
},
disable: function() {
this.callParent(arguments);
this.callSpinnersFunction('disable', arguments);
},
enable: function() {
this.callParent(arguments);
this.callSpinnersFunction('enable', arguments);
},
setReadOnly: function() {
this.callParent(arguments);
this.callSpinnersFunction('setReadOnly', arguments);
},
clearInvalid: function() {
this.callParent(arguments);
this.callSpinnersFunction('clearInvalid', arguments);
},
isValid: function(preventMark) {
return this.hoursSpinner.isValid(preventMark) && this.minutesSpinner.isValid(preventMark)
&& this.secondsSpinner.isValid(preventMark);
},
validate: function() {
return this.hoursSpinner.validate() && this.minutesSpinner.validate() && this.secondsSpinner.validate();
}
});
DateTimePicker(主要改动就在这边,因为前辈那边的功能只有添加,那我如果不想要这个参数了怎么办,所以就又添加了个重置按钮):
Ext.define('Ext.ux.DateTimePicker', {
extend: 'Ext.picker.Date',
alias: 'widget.datetimepicker',
requires: ['Ext.ux.TimePickerField','Ext.dom.Query'],
todayText: '现在',
timeLabel: '时间',
buttonText: '确定',
buttonText2: '重置',
initComponent: function() {
this.callParent();
this.value = this.value || new Date();
},
onRender: function(container, position) {
this.callParent(arguments);
var me = this;
//确认按键
var btnCfg = Ext.apply({}, {}, {
style: 'center',
listeners: {
click: {
fn: function(){
this.confirmDate();
},
scope: me
}
}
});
//清空按键
var resetBtnCfg = Ext.apply({}, {}, {
style: 'center',
listeners: {
click: {
fn: function(){
this.resetDate();
},
scope: me
}
}
});
me.confirmBtn = Ext.create('Ext.Button', Ext.apply({}, btnCfg, {
text: '确认',
}));
me.resetBtnCfg = Ext.create('Ext.Button', Ext.apply({}, resetBtnCfg, {
text: '重置',
}));
me.confirmBtn.render(this.el.child('div div.x-datepicker-footer'));
me.resetBtnCfg.render(this.el.child('div div.x-datepicker-footer'));
if(!this.timefield) {
this.timefield = Ext.create('Ext.ux.TimePickerField', {
fieldLabel: this.timeLabel,
labelWidth: 40,
value: Ext.Date.format(this.value, 'H:i:s'),
});
}
this.timefield.ownerCt = this;//指定范围
this.timefield.on('change', this.timeChange, this);//
var table = Ext.get(Ext.DomQuery.selectNode('table', this.el.dom));
var tfEl = Ext.DomHelper.insertAfter(table, {
tag: 'div',
style: 'border:0px;',
children: [{
tag: 'div',
cls: 'x-datepicker-footer ux-timefield'
}]
}, true);
this.timefield.render(this.el.child('div div.ux-timefield'));
var p = this.getEl().parent('div.x-layer');
if(p) {
p.setStyle("height", p.getHeight() + 31);
}
},
// listener 时间域修改, timefield change
timeChange: function(tf, time, rawtime) {
this.value = this.fillDateTime(this.value);
},
fillDateTime: function(value) {
if(this.timefield) {
var rawtime = this.timefield.getRawValue();
value.setHours(rawtime.h);
value.setMinutes(rawtime.m);
value.setSeconds(rawtime.s);
}
return value;
},
changeTimeFiledValue: function(value) {
this.timefield.un('change', this.timeChange, this);
this.timefield.setValue(this.value);
this.timefield.on('change', this.timeChange, this);
},
setValue: function(value) {
this.value = value;
this.changeTimeFiledValue(value);
return this.update(this.value);
},
getValue: function() {
return this.fillDateTime(this.value);
},
handleDateClick: function(e, t) {
var me = this,
handler = me.handler;
e.stopEvent();
if(!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)) {
me.doCancelFocus = me.focusOnSelect === false;
me.setValue(this.fillDateTime(new Date(t.dateValue)));
delete me.doCancelFocus;
me.fireEvent('select', me, me.value);
if(handler) {
handler.call(me.scope || me, me, me.value);
}
me.onSelect();
}
},
//确认按键
confirmDate: function(){
var that = this;
that.fireEvent('select', that, that.value);//模拟用户选择
that.onSelect();
},
//重置按钮
resetDate: function () {
var me = this;
me.value = null;
me.fireEvent('select', me, me.value);//模拟用户选择
me.onSelect();
},
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;
}
});
DateTimeField:
Ext.define('Ext.ux.DateTimeField', {
extend: 'Ext.form.field.Date',
alias: 'widget.datetimefield',
requires: ['Ext.ux.DateTimePicker'],
initComponent: function() {
this.format = this.format;
this.callParent();
},
format: 'Y-m-d H:i:s',
createPicker: function() {
var me = this,
format = Ext.String.format;
return Ext.create('Ext.ux.DateTimePicker', {
ownerCt: me.ownerCt,
// renderTo: document.body,
floating: true,
// hidden: true,
focusOnShow: 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();
}
}
});
}
});
因为使用的地方比较多,我不喜欢重复定义,所以就搞了个工具类:
emmm...这里需要注意的,如果要设置通用的监听事件,直接在控件listeners里面设置是无效的,所以,有需要的话,直接在下面控件名.addListener()好了,如果想支持多个,可以自行扩展....
/**
* 日期时间控件
* 如果没有选择任何时间,返回的是个object, field.getValue() 返回null
* 如果选择了时间,返回的是个UTO时间中文字符(例如:Mon Jun 04 2018 09:55:27 GMT+0800 (中国标准时间)),建议取值时,getTime()
* @param emptyText
* @param fieldLabel
*/
search_config_dateTimeField : function (emptyText, fieldLabel, eventName, eventFunc) {
var field = Ext.create({
xclass:'Ext.ux.DateTimeField',
fieldLabel:fieldLabel,
labelWidth:65,
emptyText:emptyText,
xtype:'datetimefield',
/*reference:'dateTimeText',*/
format:"Y-m-d H:i:s",
listeners:{
eventName : eventFunc
}
});
if(eventName != undefined && eventName != '' && eventName.length > 0){
field.addListener(eventName,eventFunc);
}
return field;
},
search_dateTimeField : function (emptyText, fieldLabel) {
return this.search_config_dateTimeField(emptyText,fieldLabel);
},
还有几点值得注意的地方,
(1):上面定义的三个文件.需要放在项目目录中的ux目录下
(2):最好设置一个通用的js文件,然后在js文件中引入自定义的js文件就ok了.
最后附一张页面效果图;