ExtJs - Date-Time field plugins for efficient data entry

DateField & TimeField from ExtJs/Ext.net arsenal are two really useful controls for entering date/time into forms. However, one of my clients complained that these fields can sometime take too much time in filling out, e.g. when the Date to be entered was months/years behind or ahead of the current date. Moreover, if you fill a partial value in these fields (e.g. 2 for timefield), the fields do not validate, and clear out the content.

I was asked to ensure that the user should be able to use the Datefield calendar and the TimeField drop-down items in case he/she wanted to, but simultaneously, I should do something to speed up data entry, and allow these fields to accept partial values and automatically complete them with logical values.

So, I came up with a plugin each for DateField and TimeField which you can see in action below:


The plugins allow you to choose date/time for the corresponding fields normally. Plus they enable you to enter partial values like 1, 1 Apr etc. for DateField, and 2, 2p etc. for TimeField which are automatically converted into correct values for the corresponding field.

The DateField plugin uses current date for the filling out the date portions not specified directly (e.g. year in 1Apr).
However, Timefield fills the minutes with zeros  in case they are not specified (e.g. 2 gets converted to 2:00 am, but 2:5p gets converted to 2:05 pm).

I chose the above rules as dictated by the project requirements, for which these plugins were created. It should not be too difficult to tweak the rules according to your needs in case you want them to be different.

The complete source for the plugins is available in the attached file. I am also reproducing the plugin code below:


{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }Ext.ns('Ext.ux'); // Date Field Corrector Ext.ux.DateFieldCorrector = function(config) { Ext.apply(this, config); }; Ext.extend(Ext.ux.DateFieldCorrector, Object, { init: function(el) { el.on('blur', this.correctDate); el.on('specialkey', function(el, e) { if (e.keyCode == e.TAB) this.correctDate(el); }, this); }, // end of function init correctDate: function(el) { if (el.isValid()) return; var val = el.getRawValue(); var corrected; if (typeof (val) == 'date') { return; } val = !Ext.isEmpty(val) ? val.toString() : null; if (val == null) { corrected = ''; } var nums = val.match(/[0-9]+/g); var alpha = val.match(/[a-zA-Z]+/); var cur = new Date(); var d = nums && nums[0] ? nums[0] : cur.getDate(); var y = nums && nums[1] ? nums[1] : cur.getFullYear(); var m = alpha && alpha[0] ? alpha[0] : cur.format('M'); var milli = Date.parse(d + ' ' + m + ' ' + y); if (!isNaN(milli)) { corrected = new Date(milli); } else { corrected = new Date(); } el.setValue(corrected); } }); // Time Field Corrector Ext.ux.TimeFieldCorrector = function(config) { Ext.apply(this, config); }; Ext.extend(Ext.ux.TimeFieldCorrector, Object, { init: function(el) { var plugin = this; plugin.lastText = ''; el.on('render', function(el) { el.el.on('keypress', function(e, t, o) { if (!e.isSpecialKey()) { var key = String.fromCharCode(e.keyCode); plugin.lastText = t.value + key; } }); }); el.on('blur', this.correctTime, this); el.on('specialkey', function(el, e) { if (e.keyCode == e.TAB) this.correctTime(el); }, this); }, // end of function init correctTime: function(el) { var val = this.lastText; if (Ext.isEmpty(val)) { return; } else { val = val.toString(); } var nums = val.match(/[0-9]+/g); var alpha = val.match(/[a-zA-Z]+/); var h = nums && nums[0] ? nums[0] : '12'; if (h.length > 2) h = h.substring(0, 2); var m = nums && nums[1] ? nums[1] : '00'; if (m.length > 2) { m = m.substring(0, 2) } else { if (m.length == 1) m = '0' + m }; var a = alpha && alpha[0] ? alpha[0].toLowerCase() : 'am'; if (a == 'a' || a == 'p') a = a + 'm'; if (a != 'am' && a != 'pm') a = 'am'; if (h > 12) { h = h % 12; a = 'pm'; } if (m > 59) m = m % 60; var time = h + ':' + m + ' ' + a; if (time.charAt(0) == '0') { time = time.substring(1); } el.setValue(time); } });{/syntaxhighlighter}



HTML icon DateTimePlugins.htm4.2 KB


Nice job! The timefield is what I've been looking for. Thanks for sharing.

rahul's picture

Hi andrew, thanks for the feedback. I have improved versions of this plugin, will try to update code as soon as I get time.

Hello, thank you very much for sharing this, very well

can we use this for extjs 4.0 ?

rahul's picture

Yes, if you are using the Ext 3 compatibility layer, then it sould work as is most probably. Otherwise you will need to update the code to accommodate the fact that add-on instance methods on native Date object are now static methods in Ext.Date class. Please read the Ext4 migration notes for details.

Thanks a lot for sharing this brilliant work. Yet to test it with 3.4. I hope it works well.

rahul's picture

Should work, I am using it with 3.4 :)


nice work

does it work with ExtJS 4? would u show me the code that how can i apply the time plugin to a textfield?


rahul's picture

Hi there, the plugin was written for ExtJs 3 and I don't think the plugin would work with Ext 4 without some changes. As for applying plugin to a textfield in Ext 3, check the attached html document with the blog post. That has real working examples of using the plugin.