Sencha Touch TimePicker form field and Picker sheet
Currently we are using Sencha Touch as the basis for our new splog.me app.The Sencha Touch 1.1 framework includes a very large number of readily available form fields including the DatePicker form field and DatePicker popup sheet itself. Strangely enough, a TimePicker is missing so we decided to build one ourselves. The TimePicker below is heavily based on the DatePicker classes and includes a form field and a picker.
Ext.ux.form.TimePicker
To quickly demonstrate, the screenshots below show a TimePicker without any custom configuration and one that only shows a certain timespan and shows every fifth minute.
Usage
The TimePicker can be inserted into a form using it’s xtype ‘timepickerfield’ or by creating an instance yourselve.
var startTime = new Ext.ux.form.TimePicker({
name : 'starttime',
label: 'Start time'
});
Or it can be customized with the starting hour, ending hour and minute interval:
var startTime = new Ext.ux.form.TimePicker({
name : 'starttime',
label: 'Start time',
minuteScale: 5,
hourFrom: 8,
hourTo: 18,
value: {
hour: (new Date().getHours()+1)%24, /* start with the next hour */
minute: 0
}
});
Feel free to use the timepicker in your Sencha Touch app and let me know when you do. Always nice to see other great mobile apps. If you think of any improvements (EG. making it configurable for 24h/ AM PM format), let me know also. The code is displayed below and attached to this post as a tgz archive.
Cheers,
Rob
Code
Ext.ux.Form.TimePicker
Ext.ns('Ext.ux.form');
/**
* @class Ext.ux.form.TimePicker
* @extends Ext.form.Field
*
Specialized field which has a button which when pressed, shows a {@link Ext.ux.TimePicker}.
* @xtype timepickerfield
*/
Ext.ux.form.TimePicker = Ext.extend(Ext.form.Field, {
ui: 'select',
/**
* @cfg {Number} minuteScale
* List every how many minutes, eg. 5 lists 0, 5, 10, 15, etc. Defaults to 1
*/
minuteScale: 1,
/**
* @cfg {Number} hourFrom
* The start hour for the time picker. Defaults to 0
*/
hourFrom: 0,
/**
* @cfg {Number} hourTo
* The last hour for the time picker. Defaults to 23
*/
hourTo: 23,
/**
* @cfg {Object/Ext.ux.TimePicker} picker
* An object that is used when creating the internal {@link Ext.ux.TimePicker} component or a direct instance of {@link Ext.ux.TimePicker}
* Defaults to null
*/
picker: null,
/**
* @cfg {Object/Time} value
* Default value for the field and the internal {@link Ext.ux.TimePicker} component. Accepts an object of 'hour',
* and 'minute' values, all of which should be numbers, or a Time string.
*
* Example: {hour: 18, minute: 15} = 18:15
*/
/**
* @cfg {Boolean} destroyPickerOnHide
* Whether or not to destroy the picker widget on hide. This save memory if it's not used frequently,
* but increase delay time on the next show due to re-instantiation. Defaults to false
*/
destroyPickerOnHide: false,
// @cfg {Number} tabIndex @hide
// @cfg {Boolean} useMask @hide
// @private
initComponent: function() {
this.addEvents(
/**
* @event change
* Fires when a Time is selected
* @param {Ext.ux.form.TimePicker} this
* @param {Time} Time The new Time
*/
'change'
);
this.tabIndex = -1;
this.useMask = true;
Ext.form.Text.superclass.initComponent.apply(this, arguments);
},
/**
* Get an instance of the internal Time picker; will create a new instance if not exist.
* @return {Ext.ux.TimePicker} TimePicker
*/
getTimePicker: function() {
if (!this.timePicker) {
if (this.picker instanceof Ext.ux.TimePicker) {
this.timePicker = this.picker;
} else {
this.timePicker = new Ext.ux.TimePicker(Ext.apply(this.picker || {
minuteScale: this.minuteScale,
hourFrom: this.hourFrom,
hourTo: this.hourTo
}));
}
this.timePicker.setValue(this.value || null);
this.timePicker.on({
scope : this,
change: this.onPickerChange,
hide : this.onPickerHide
});
}
return this.timePicker;
},
/**
* @private
* Listener to the tap event of the mask element. Shows the internal {@link #timePicker} component when the button has been tapped.
*/
onMaskTap: function() {
if (Ext.ux.form.TimePicker.superclass.onMaskTap.apply(this, arguments) !== true) {
return false;
}
this.getTimePicker().show();
},
/**
* Called when the picker changes its value
* @param {Ext.ux.TimePicker} picker The time picker
* @param {Object} value The new value from the time picker
* @private
*/
onPickerChange : function(picker, value) {
this.setValue(value);
this.fireEvent('change', this, this.getValue());
},
/**
* Destroys the picker when it is hidden, if
* {@link Ext.ux.form.icker#destroyPickerOnHide destroyPickerOnHide} is set to true
* @private
*/
onPickerHide: function() {
if (this.destroyPickerOnHide && this.timePicker) {
this.timePicker.destroy();
}
},
// inherit docs
setValue: function(value, animated) {
if (this.timePicker) {
this.timePicker.setValue(value, animated);
this.value = (value != null) ? this.timePicker.getValue() : null;
} else {
if (Ext.isObject(value)) {
var hour = value.hour+"";
hour = hour.length == 1 ? 0 + hour : hour;
var minute = value.minute+"";
minute = minute.length == 1 ? 0 + minute : minute;
this.value = hour+":"+minute;
} else {
this.value = value;
}
}
if (this.rendered) {
this.fieldEl.dom.value = this.getValue(true);
}
return this;
},
/**
* Returns the value of the field, which will be a {@link Time} unless the format parameter is true.
* @param {Boolean} format True to format the value with Ext.util.Format.defaultTimeFormat
*/
getValue: function(format) {
var value = this.value || null;
if (Ext.isObject(value)) {
var hour = value.hour+"";
hour = hour.length == 1 ? 0 + hour : hour;
var minute = value.minute+"";
minute = minute.length == 1 ? 0 + minute : minute;
return hour+":"+minute;
}
return value;
},
// @private
onDestroy: function() {
if (this.timePicker) {
this.timePicker.destroy();
}
Ext.ux.form.TimePicker.superclass.onDestroy.call(this);
}
});
Ext.reg('timepickerfield', Ext.ux.form.TimePicker);
Ext.ux.Form.TimePicker
Ext.ns('Ext.ux');
/**
* @class Ext.ux.TimePicker
* @extends Ext.Picker
*
*
A time picker component which shows a TimePicker on the screen. This class extends from {@link Ext.Picker} and {@link Ext.Sheet} so it is a popup.
*
This component has no required properties.
*
*
<h2>Useful Properties</h2>
*
<ul class="list">
*
<li>{@link #hourFrom}</li>
*
<li>{@link #hourTo}</li>
*</ul>
*
*
<h2>Example code:</h2>
*
*
<pre><code>
var timePicker = new Ext.ux.TimePicker();
timePicker.show();
* </code></pre>
*
*
you may want to adjust the {@link #hourFrom}, {@link #hourTo} and {@link #minuteScale} properties:
*
<pre><code>
var timePicker = new Ext.ux.TimePicker({
hourFrom: 8,
hourTo : 18,
minuteScale: 5
});
timePicker.show();
* </code></pre>
*
* @constructor
* Create a new Timepicker
* @param {Object} config The config object
* @xtype timepicker
*/
Ext.ux.TimePicker = Ext.extend(Ext.Picker, {
/**
* @cfg {Number} minuteScale
* List every how many minutes, eg. 5 lists 0, 5, 10, 15, etc. Defaults to 1
*/
minuteScale: 1,
/**
* @cfg {Number} hourFrom
* The start hour for the time picker. Defaults to 0
*/
hourFrom: 0,
/**
* @cfg {Number} hourTo
* The last hour for the time picker. Defaults to 23
*/
hourTo: 23,
/**
* @cfg {String} hourText
* The label to show for the hour column. Defaults to 'Hour'.
*/
hourText: 'Hour',
/**
* @cfg {String} minuteText
* The label to show for the minute column. Defaults to 'Minute'.
*/
minuteText: 'Minute',
/**
* @cfg {Array} slotOrder
* An array of strings that specifies the order of the slots. Defaults to <tt>['hour', 'minute']</tt>.
*/
slotOrder: ['hour', 'minute'],
initComponent: function() {
var hoursFrom = this.hourFrom,
hoursTo = this.hourTo,
hours = [],
minutes = [],
ln, tmp, i, j;
// swap values if user mixes them up.
if (hoursFrom > hoursTo) {
tmp = hoursFrom;
hoursFrom = hoursTo;
hoursTo = tmp;
}
for (i = j = hoursFrom; i <= hoursTo; i++, j++) { j = (j+"").length > 1 ? j : "0"+j;
hours.push({
text: j,
value: i
});
}
for (i = j = 0; i <= 59; i = j = i + this.minuteScale) { j = (j+"").length > 1 ? j : "0"+j;
minutes.push({
text: j,
value: i
});
}
this.slots = [];
this.slotOrder.forEach(function(item){
this.slots.push(this.createSlot(item, hours, minutes ));
}, this);
Ext.ux.TimePicker.superclass.initComponent.call(this);
},
afterRender: function() {
Ext.ux.TimePicker.superclass.afterRender.apply(this, arguments);
this.setValue(this.value);
},
createSlot: function(name, hours, minutes ){
switch (name) {
case 'hour':
return {
name: name,
align: 'right',
data: hours,
title: this.useTitles ? this.hourText : false,
flex: 5
};
case 'minute':
return {
name: name,
align: 'left',
data: minutes,
title: this.useTitles ? this.minuteText : false,
flex: 5
};
}
},
// @private
onSlotPick: function(slot, value) {
Ext.ux.TimePicker.superclass.onSlotPick.apply(this, arguments);
},
/**
* Gets the current value as a Time object
* @return {hour: x, minute: y} value
*/
getValue: function() {
var value = Ext.ux.TimePicker.superclass.getValue.call(this);
return value;
},
/**
* Sets the values of the TimePicker's slots
* @param {Date/Object} value The value either in a {hour:'value', minute:'value'} format or a String, eg: '18:00'
* @param {Boolean} animated True for animation while setting the values
* @return {Ext.DatePicker} this This DatePicker
*/
setValue: function(value, animated) {
if (Ext.isObject(value)) {
this.value = value;
} else {
var arr = (value+"").split(':');
this.value = {
hour: parseInt(arr[0],10),
minute: parseInt(arr[1],10)
};
}
return Ext.ux.TimePicker.superclass.setValue.call(this, this.value, animated);
}
});
Ext.reg('timepicker', Ext.ux.TimePicker);
31 Responses to Sencha Touch TimePicker form field and Picker sheet
Leave a Reply Cancel reply
POST CATEGORIES
ExtJS
- Sencha.com Sencha.com – creators of ExtJS and Sencha Touch









Hey Rob, Thanks a lot for this ! saved me plenty of time and works great!
The picker component does not seem to work, so I had to inherit from Ext.Sheet instead. Now I can’t seem to get a default value inserted into the picker. I can set the default values (hour and minute), but for some reason the picker values are set to 00:00 instead of the default values I set.
I would be really happy if you could provide me with a solution to this problem, or point me to where (in the code) the default value is set inside the picker.
Hi Jacob,
I will be happy to look into it, first off, which version of Sencha Touch are you using? This picker is based on 1.1
I’m using Sencha Touch 1.1.0, so that shouldn’t be a problem. Also, what I’ve noticed is that the picker seems to get the correct time after I’ve picked a time once, but it does not get the correct time if I’ve set a default time.
I’m aware that it could be my fault as I’ve done some changes in order to make the picker work at all, but I still need to know where to find the code where the picker gets/sets its default values
If you don’t check the comments very often it would be great if you could email me instead. My email address is jakob.grannas@intelliplan.se. I need to fix this asap, so it would really help you could reply as soon as you read this.
Thank you very much
Rob – what is the best way to integrate these classes into Sencha Touch? I tried dropping into src folder, but figured that sencha-touch.js needs to reference this new components somehow. Or should you just directly include – ?
Hi Chris,
In my production environment I concatenate all Sencha sources and my own custom sources using Sencha build and some custom perl scripts. For my development environment everything is just included into the index.html file in this order:
- sencha-touch.js
- UX classes (including my own, this also includes the time picker)
- app.js
- utils
- models
- stores
- views
- controllers
I built a perl script that scans my sources and automatically creates the index.html file for me (among other things). If you like I can send you an example of this index.html file. Hope this helps.
Hi Robb,
I have still not figured out how to get the make the picker set its values to my default values. I’ve console.log:ged this.value practically everywhere in the code, and it always seems to be correct, but the picker still has 00:00 set upon instantiation. I really need your help, and would really appreciate if you could answer my questions.
Thanks a lot. Saved me a lot of work. Works out of the box.
I have ported this to Sencha 2.0. After I wasn’t able to deploy this to a Sencha 2.0 app, I created a time picker in the same manner by copying and modifying the existing Sencha 2.0 date picker (control and picker).
I’ll post it up at some stage.
Great, let me know when it’s ready
Hi,
Has anyone ported in Sencha touch 2.0. If yes, can you please share the code.
Thanks,
No, not yet, Ryan mentioned he was working on it. Otherwise I will port it over in a few days. Have been incredibly busy but should be easy enough to do
OK, so I put TimePicker.js in my project in the same directory, register it in index.html, then go to a panel and add an item with an xtype of ‘timepickerfield’, and it doesn’t recognise it. What else do I have to do?
Hi Steve, which version of Sencha Touch are you using?
Hi, thanks for sharing this, however I have got a little problem, I put these 2 files into ux folder under /lib/touch folder and reference it in my index.html just under sencha-touch.js.
When i added it into my view as below;
xtype: ‘timepickerfield’,
name: ‘pickuptime’,
label: ‘Pick up Time’,
minuteScale: 5,
hourFrom: 0,
hourTo: 23,
value: {
hour: (new Date().getHours() + 1) % 24, /* start with the next hour */
minute: 0
}
it throws an error saying Uncaught Error: [Ext.createByAlias] Cannot create an instance of unrecognized alias: widget.timepickerfield
I use sencha touch 2
Thanks for help.
Hi Cem,
A couple of other people have reported this as well, the current implementation only works in ST 1.
I will try and free some time to create a similar solution for ST 2 this afternoon.
Thank you so much for your hard work, that would save my life. Many thanks again. Looking forward to it.
Hey,Rob…kindly post the solution for ST2 as soon as possible.Thanks.
Hi there, any progress with ST 2? Im so desperately looking forward to it. Many thanks.
Hehe, working hard on it. I created a new time picker component for ST2 which works like a charm. Now I just have to create a form time picker field. I’ll create a new blog post and link to it when I am ready. Have patience my friend
Hi, any progress with ST 2?
Please let me know when you already posted a new blog post about it.
Thanks a lot.
Any progress on implementing time picker in ST2?
Hi, The timepicker is mostly finished but the one Arbi pointed out looks nice too. Please let me know if you guys still want me to post it
Guys, this is one of working solution:
http://market.sencha.com/addon/datetimepicker
Looks good!
Hi Arbi,
I am in need of timepicker in Sencha touch2.
I am not able to view below url which you have shared.
http://market.sencha.com/addon/datetimepicker
plz help me.
Waiting 4ur +ve reply.
Hey Rob, This is great. Works smooth and very useful. Thank you very much for sharing
can you share the time picker of sencha 1.1 with the improvement of 24h AM/PM format.
Unable to view http://market.sencha.com/addon/datetimepicker.
Pls tell the solution ASAP.Thanks in advance…
That addon is not mine (although it seems to be based in part on my code