开发者博客:www.developsearch.com
一。一些废话
近日来,有几个项目用到了EXTJS作为Web前端。也看到了一些童鞋苦苦在网上寻觅可以选择时间的控件,由于EXTJS版本差异较大,利用官方3.2的Demo制作了一个可以选择到秒的时间控件,该控件只能够用于ExtJs2.2以上的版本。经过测试ExtJs2.02版本不适用该控件,如果你还在使用2.02这个版本或者更老,请绕道。废话不说了,看代码:
二。文件明细:
Spinner.js
SpinnerField.js
DateTimeField.js
三。各文件详解
1.Spinner.js
EXTJS个版本略有不同,最后的文件解压后请覆盖源文件。这里不做详细介绍。
2.SpinnerField.js
EXTJS个版本略有不同,最后的文件解压后请覆盖源文件。这里不做详细介绍。
3.DateTimeField.js
// 命名空间归属 Ext.ns('Ext.ux.form'); // 在该命名空间内,开辟一个名为TimePickerField的区域,我们可以当他是一个时间选择器 Ext.ux.form.TimePickerField = function(config){ // 调用构造方法,也就是说定义了他的所属--this // this指的是什么呢?这里需要注意,首先这个东东属于这个类(对象),其次这个类(对象)在没有被调用之前或者实例之前是不会被构造的 // 那么这个this实际上是指我们实例化后的datetimefield Ext.ux.form.TimePickerField.superclass.constructor.call(this, config); } // 给刚刚定义的TimePickerField加点菜吧。 // 首先它继承与Ext.form.Field,是一个扩展 Ext.extend(Ext.ux.form.TimePickerField, Ext.form.Field, { defaultAutoCreate: { tag: 'div'// 定义了一个DIV标签 }, cls: 'x-form-timepickerfield',// 它的样式 hoursSpinner: null,// 属性:小时选择器 minutesSpinner: null,// 属性:分钟选择器 secondsSpinner: null,// 属性:秒选择器 spinnerCfg: { width: 40// 选择器的宽度定位40px }, // 约束:选择数值约束,如果小于最小值该如何,如果大于最大值该如何,这里的处理方式我详细说明一下(这个约束是触发的,我们输入的值或者我们点击上下箭头选择的值后都会进入该约束检查。) spinnerFixBoundries: function(value){ // 这里有可能会造成不解,我解释一下。 // 如果我们选择秒的时候,有一个向上的箭头和向下的箭头,如果我点击向上的箭头则秒数加1,点击向下的箭头则秒数减1。 // 如果我选择了59秒后,点击向上的箭头,由于时间秒数约束,不可能出现60,那我们要怎么办?会如何?当然是,58,59,0,1这样的序列 // 所以最大值定义为59,如果超过59那么秒数归零,就是这个逻辑。 if (value < this.field.minValue) { value = this.field.maxValue; } if (value > this.field.maxValue) { value = this.field.minValue; } // 这里返回了一个带有精度的值 return this.fixPrecision(value); }, // 渲染,这个没什么可说的了所有的渲染都差不多是位置和范围之类的 onRender: function(ct, position){ Ext.ux.form.TimePickerField.superclass.onRender.call(this, ct, position); this.rendered = false; this.date = new Date(); // 定义一个对象,他即将有三个属性,时分秒数值,往下看。 var values = {}; // 如果实例时已经被设定了初始值,那么将这些值赋予values这个对象中。 // 再将这些值表示在时分秒选择器中 if (this.value) { values = this._valueSplit(this.value); this.date.setHours(values.h); this.date.setMinutes(values.m); this.date.setSeconds(values.s); delete this.value; } // 如果实例时没被设定了初始值,简单了,时分秒选择器的初始值就不用改变了,只要values得到这些值备用即可 else { values = { h: this.date.getHours(), m: this.date.getMinutes(), s: this.date.getSeconds() }; } // 定义一个外围包裹,就是想把时分秒这三个选择器给包起来成为一组,下面会实例这三个选择器的,往下看。 var spinnerWrap = Ext.DomHelper.append(this.el, { tag: 'div' }); var cfg = Ext.apply({}, this.spinnerCfg, { renderTo: spinnerWrap, readOnly: this.readOnly, disabled: this.disabled, listeners: { spin: { fn: this.onSpinnerChange, scope: this }, valid: { fn: this.onSpinnerChange, scope: this }, afterrender: { fn: function(spinner){ spinner.wrap.applyStyles('float: left'); }, single: true } } }); // 接下来实例(Ext.ux.form.SpinnerField)了几个选择器,时分秒。 this.hoursSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, { minValue: 0, maxValue: 23, cls: 'first', value: values.h })); this.minutesSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, { minValue: 0, maxValue: 59, value: values.m })); this.secondsSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, { minValue: 0, maxValue: 59, value: values.s })); Ext.DomHelper.append(spinnerWrap, { tag: 'div', cls: 'x-form-clear-left' }); // 渲染完毕释放出去 this.rendered = true; }, // 如果实例时已经被设定了初始值,那么调用这个方法,将这些值赋予values这个对象中。 _valueSplit: function(v){ 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; } // 这里注册了这个监听类别,指明了监听的对象 this.fireEvent('change', this, this.getRawValue()); }, // 禁用 disable: function(){ Ext.ux.form.TimePickerField.superclass.disable.call(this); this.hoursSpinner.disable(); this.minutesSpinner.disable(); this.secondsSpinner.disable(); }, // 解用 enable: function(){ Ext.ux.form.TimePickerField.superclass.enable.call(this); this.hoursSpinner.enable(); this.minutesSpinner.enable(); this.secondsSpinner.enable(); }, // 只读 setReadOnly: function(r){ Ext.ux.form.TimePickerField.superclass.setReadOnly.call(this, r); this.hoursSpinner.setReadOnly(r); this.minutesSpinner.setReadOnly(r); this.secondsSpinner.setReadOnly(r); }, // 清除所有的无效验证 clearInvalid: function(){ Ext.ux.form.TimePickerField.superclass.clearInvalid.call(this); this.hoursSpinner.clearInvalid(); this.minutesSpinner.clearInvalid(); this.secondsSpinner.clearInvalid(); }, // 拿到那个值,可以认为是vlaues对象 getRawValue: function(){ if (!this.hoursSpinner) { this.date = new Date(); return { h: this.date.getHours(), m: this.date.getMinutes(), s: this.date.getSeconds() }; } else { return { h: this.hoursSpinner.getValue(), m: this.minutesSpinner.getValue(), s: this.secondsSpinner.getValue() }; } }, // 赋值 setRawValue: function(v){ this.hoursSpinner.setValue(v.h); this.minutesSpinner.setValue(v.m); this.secondsSpinner.setValue(v.s); }, // 有效验证 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(); }, // 这里可以自己修改想要的格式,这个值将作为返回值到调用该类的元控件中也就是DateTimeField的实例 getValue: function(){ var v = this.getRawValue(); return String.leftPad(v.h, 2, '0') + ':' + String.leftPad(v.m, 2, '0') + ':' + String.leftPad(v.s, 2, '0'); }, setValue: function(value){ if (!this.rendered) { this.value = value; return; } value = this._valueSplit(value); this.setRawValue(value); this.validate(); } }); // 下面就没什么好说的了,就是将上面自定义的类(对象),成为一个总选择器一部分。 Ext.form.TimePickerField = Ext.ux.form.TimePickerField; Ext.reg('timepickerfield', Ext.form.TimePickerField); Ext.ns('Ext.ux.form'); Ext.DateTimePicker = Ext.extend(Ext.DatePicker, { timeFormat: 'g:i:s A', timeLabel: '时间', timeWidth: 100, initComponent: function(){ Ext.DateTimePicker.superclass.initComponent.call(this); this.id = Ext.id(); }, onRender: function(container, position){ Ext.DateTimePicker.superclass.onRender.apply(this, arguments); var table = Ext.get(Ext.DomQuery.selectNode('table tbody', container.dom)); var tfEl = Ext.DomHelper.insertBefore(table.last(), { tag: 'tr', children: [{ tag: 'td', cls: 'x-date-bottom', html: this.timeLabel, style: 'width:30;' }, { tag: 'td', cls: 'x-date-bottom ux-timefield', colspan: '2' }] }, true); this.tf.render(table.child('td.ux-timefield')); var p = this.getEl().parent('div.x-layer'); if (p) { p.setStyle("height", p.getHeight() + 31); } }, setValue: function(value){ var old = this.value; if (!this.tf) { this.tf = new Ext.ux.form.TimePickerField(); this.tf.ownerCt = this; } this.value = this.getDateTime(value); }, getDateTime: function(value){ if (this.tf) { var dt = new Date(); var timeval = this.tf.getValue(); value = Date.parseDate(value.format(this.dateFormat) + ' ' + this.tf.getValue(), this.format); } return value; }, selectToday: function(){ if (this.todayBtn && !this.todayBtn.disabled) { this.value = this.getDateTime(new Date()); this.fireEvent("select", this, this.value); } } }); Ext.reg('datetimepickerfield', Ext.DateTimePicker); if (parseInt(Ext.version.substr(0, 1), 10) > 2) { Ext.menu.DateTimeItem = Ext.DateTimePicker; Ext.override(Ext.menu.DateMenu, { initComponent: function(){ this.on('beforeshow', this.onBeforeShow, this); if (this.strict = (Ext.isIE7 && Ext.isStrict)) { this.on('show', this.onShow, this, { single: true, delay: 20 }); } Ext.apply(this, { plain: true, showSeparator: false, items: this.picker = new Ext.DatePicker(Ext.apply({ internalRender: this.strict || !Ext.isIE, ctCls: 'x-menu-date-item' }, this.initialConfig)) }); Ext.menu.DateMenu.superclass.initComponent.call(this); this.relayEvents(this.picker, ["select"]); this.on('select', this.menuHide, this); if (this.handler) { this.on('select', this.handler, this.scope || this); } } }); } else { Ext.menu.DateTimeItem = function(config){ Ext.menu.DateTimeItem.superclass.constructor.call(this, new Ext.DateTimePicker(config), config); this.picker = this.component; this.addEvents('select'); this.picker.on("render", function(picker){ picker.getEl().swallowEvent("click"); picker.container.addClass("x-menu-date-item"); }); this.picker.on("select", this.onSelect, this); }; Ext.extend(Ext.menu.DateTimeItem, Ext.menu.DateMenu, { onSelect: function(picker, date){ this.fireEvent("select", this, date, picker); Ext.menu.DateTimeItem.superclass.handleClick.call(this); } }); } Ext.menu.DateTimeMenu = function(config){ Ext.menu.DateTimeMenu.superclass.constructor.call(this, config); this.plain = true; var di = new Ext.menu.DateTimeItem(config); this.add(di); this.picker = di; this.relayEvents(di, ["select"]); this.on('beforeshow', function(){ if (this.picker) { this.picker.hideMonthPicker(true); } }, this); }; Ext.extend(Ext.menu.DateTimeMenu, Ext.menu.Menu, { cls: 'x-date-menu', beforeDestroy: function(){ this.picker.destroy(); }, hide: function(deep){ if (this.picker.tf.innerList) { if ((Ext.EventObject.within(this.picker.tf.innerList)) || (Ext.get(Ext.EventObject.getTarget()) == this.picker.tf.innerList)) return false; } if (this.el && this.isVisible()) { this.fireEvent("beforehide", this); if (this.activeItem) { this.activeItem.deactivate(); this.activeItem = null; } this.el.hide(); this.hidden = true; this.fireEvent("hide", this); } if (deep === true && this.parentMenu) { this.parentMenu.hide(true); } } }); Ext.ux.form.DateTimeField = Ext.extend(Ext.form.DateField, { dateFormat: 'Y-m-d', timeFormat: 'H:i:s', defaultAutoCreate: { tag: "input", type: "text", size: "20", autocomplete: "off" }, initComponent: function(){ Ext.ux.form.DateTimeField.superclass.initComponent.call(this); this.format = this.dateFormat + ' ' + this.timeFormat; this.afterMethod('afterRender', function(){ this.getEl().applyStyles('top:0'); }); }, getValue: function(){ return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || ''; }, onTriggerClick: function(){ if (this.disabled) { return; } if (this.menu == null) { this.menu = new Ext.menu.DateTimeMenu(); } Ext.apply(this.menu.picker, { minDate: this.minValue, maxDate: this.maxValue, disabledDatesRE: this.ddMatch, disabledDatesText: this.disabledDatesText, disabledDays: this.disabledDays, disabledDaysText: this.disabledDaysText, format: this.format, timeFormat: this.timeFormat, dateFormat: this.dateFormat, showToday: this.showToday, minText: String.format(this.minText, this.formatDate(this.minValue)), maxText: String.format(this.maxText, this.formatDate(this.maxValue)) }); if (this.menuEvents) { this.menuEvents('on'); } else { this.menu.on(Ext.apply({}, this.menuListeners, { scope: this })); } this.menu.picker.setValue(this.getValue() || new Date()); this.menu.show(this.el, "tl-bl?"); } }); Ext.reg('datetimefield', Ext.ux.form.DateTimeField);
四。示例截图:
相关推荐
标题“Ext时间日期选择控件,精确到秒”指出了该控件允许用户选择时间到秒级别,这对于需要精确时间记录的应用场景(如日程安排、定时任务等)非常关键。EXTJS提供了多种时间日期选择控件,如`MyTimeField.js`、`...
针对这种情况,EXT社区提供了丰富的用户扩展(Ux,User Extensions)来增强其功能,如“Ext用户扩展控件---------日期时间选择器,可以精确到某天的某分钟”所描述,这是一个专门为了提供更精确时间选择的控件。...
在本案例中,我们关注的是"Ext-datatimefield日期与时间选择器",这是一个用于选择日期和时间的控件,适用于需要精确到分钟甚至秒的操作场景。 "Ext-datatimefield"是Ext JS库中的一个组件,它结合了日期选择器...
1.此控件支持Ext3.2及以上版本 2.用法与Ext.form.DateField一样,xtype:'datetimefield' 3.不需要导入css或其他js 4.解决某些插件导入会显示对象未定义问题
在“EXTJS时间控件精确秒”这个主题中,我们将深入探讨EXTJS如何实现时间控件的秒级精确选择,以及如何自定义和优化这一功能。 EXTJS的时间控件主要通过`Ext.form.field.Time`类来实现。这个类提供了一个标准的时间...
在EXTJS4中,时间控件是用于用户交互并输入日期和时间的界面元素,它提供了多种选择方式,包括年月选择、年月日选择以及年月日时分秒选择。这些控件在Web应用程序中非常常见,尤其适用于需要用户输入特定日期或时间...
"EXT日期时间控件"是一个专门用于显示和编辑日期及时间的控件,它可以精确到时、分、秒,满足了对时间精确度有较高要求的应用场景。EXT的时间控件不仅提供了基本的日期和时间选择功能,还支持自定义格式化、日期范围...
该控件的独特之处在于它可以将日期和时间精确到秒,这意味着用户可以选择一个特定的日期,然后在时间部分精确到分钟和秒,这对于需要记录详细时间信息的系统来说非常实用。例如,在日程安排、会议预订或任务管理应用...
这个"EXT 4.0 日期选择控件 时分秒 中文版"显然是一个经过本地化处理的版本,支持中文显示,并且在选择日期的同时还能选择具体的时间,精确到时、分、秒。 日期选择控件在Web应用中非常常见,用于用户输入或选择...
在这个特定的资源中,我们关注的是一个集成时间选择的日期控件,这在需要精确到时、分、秒的场景下非常有用。 EXT JS 4 的日期控件(`Ext.form.field.Date`)通常用于让用户选择一个日期。默认情况下,它只显示日期...
EXT的时间控件2是对原生EXT日期时间控件的扩展和增强,它不仅支持日期的选择,还允许用户精确到小时和分钟,以满足更精细化的时间设定需求。 EXT框架中的DateTimeField2组件是EXT.form.DateTimeField的一个变体,...
`Ext.picker.Date`是EXT中基础的日期选择器,而`Ext.picker.DateTimePicker`则增加了对时间选择的支持,让用户能够精确到小时、分钟甚至秒。这种控件对于需要用户输入特定时间的Web应用非常有用,比如事件调度、会议...
ExtJs是一款强大的JavaScript框架,主要用于构建富...优化后的时间选择控件精确到秒,使得在需要精确时间信息的场景下表现得尤为出色。开发者可以根据项目的具体需求,灵活运用这些特性来提升应用的质量和用户体验。
为了解决这个问题,开发者可以创建一个自定义的EXT JS组件,通过组合EXT JS的基础控件,如TimeField和DateField,或者直接修改EXT JS源码,增加对时分秒选择的支持。 这个自定义组件可能会包含以下关键特性: 1. **...
这个"extjs4能用的带时分秒的日期控件"可能就是一个定制的组件,它允许用户不仅选择日期,还能选择具体的时间,精确到小时、分钟和秒。 首先,ExtJS 4的日期时间控件一般会基于`Ext.form.field.Date`进行扩展,增加...
该代码仅适用于ExtJs5.x, 使用方法: 在Extjs5.x.js文件后引入以下两文件,注意顺序...<script type="text/javascript" src="ext/5.1/ext-all-debug.js"> ${src}/DateTimePicker.js"> ${src}/DateTime.js"></script>
"ext4.2 日历日期控件,可以选择时分秒"是一个专门针对这个需求的组件,它允许用户在网页应用中方便地选择日期、时间和秒数。这个控件是EXTJS库的一个组成部分,EXTJS是一个基于JavaScript的富客户端应用框架,广泛...
在描述中提到的"支持时分秒的时间控件",意味着这个控件不仅限于选择日期,还能精确到小时、分钟和秒,这对于需要精确时间输入的场景非常有用。此外,这个时间控件还宣称支持多种浏览器,包括IE(至少兼容到IE8)、...
描述中提到的控件可能就是这样的一个扩展,它不仅允许用户选择日期,还能精确到小时、分钟和秒。 在创建这样的时间选择控件时,开发者需要考虑以下关键点: 1. **自定义组件**:开发者可能需要自定义`Ext.picker....
这种控件允许用户选择一个特定的日期和时间,通常用于表单中,以获取用户输入的精确时间戳。 3. **显示问题与解决**:在上述论坛帖子中提到的日期时间控件显示问题,可能涉及到样式、格式配置、时区处理或者与其他...