Wrote a little jQuery plugin which converts a regular HTML textbox into a time-entry field with all the necessary key bindings and masks.
Features:
· supports time entry in 12 or 24 format
· API user can pass custom handler in case user types invalid time.
· Tested in IE8,Chrome(Desktop and Android),Safari(Desktop and iPhone),Firefox and Opera.
The source JS file, examples and documentation are located at: http://sajjansarkar.zxq.net/jquery/timefield/
Hope it is useful and please let me know if u find any bugs/have any suggestions!
Downloads,Demos and Documentation: http://sajjansarkar.zxq.net/jquery/timefield/
Usage:
$("#tbPlain").timefield();$("#tb12Hour").timefield({ 'hourFormat': '12'});$("#tb24Hour").timefield({ 'hourFormat': '24'});$("#tbWithInvalidHandler").timefield({'hourFormat': '24','onError' : function(){alert(this.value+' is not a valid time!');this.style.backgroundColor='red';}});$("#tbOnOff").timefield();$("#btnTurnOff").click(function(){$("#tbOnOff").timefield('turnOffTimeField');});
Code:
/**
* @author Sajjan Sarkar*/(function($)
{$.fn.timefield = function(options)
{//Public Methods
var methods = {
/** Initializes the timefield */
init : function(options)
{return this.each(function(){/** Txt entry is from RIGHT TO LEFT */
this.style.direction = "rtl";/** Cache for performance*/
var $this = $(this);/** bind listeners */
$this.bind('keydown.timefield', helpers.eventHandlers.keyDownHandler);
$this.bind('keyup.timefield', helpers.eventHandlers.keyUpHandler);
$this.bind('blur.timefield', helpers.eventHandlers.blurHandler);});},/** removes all timefield effects**/
turnOffTimeField : function(content)
{return this.each(function(){this.style.direction = "ltr";var $this = $(this);$this.unbind('.timefield');
});}};/** Private methods */
var helpers = {
eventHandlers : {/** On key down, check if the pressed key is valid else dont show it.
* acts as mask* */keyDownHandler : function(event)
{if (!helpers.utils.isValidKeyStroke(event))
{event.preventDefault();event.stopPropagation();}},/**
* When this is called the keydown event would have already rendered the* key stroke, so apply the padding with zeros.* */keyUpHandler : function(event)
{var keyCode = event.keyCode;
/** check if a special key was pressed */
if ($.inArray(keyCode, constants.KEYS.SPECIAL_KEYS_TO_IGNORE) != -1)
return;
/** did this on key up instead of keydown as its easier coz the text has rendered */
helpers.utils.applyPadding(helpers.utils.getEventSource(event));},/**
* On blur, check the validity of the enterred value based on selected settings.* Could not do this on change as most browsers dont fire the change event* if the value has changed programatically.** If the time is invalid, call the specified(or default) onError handler* */blurHandler : function(event)
{helpers.utils.getEventSource(event).value = jQuery.trim( helpers.utils.getEventSource(event).value );if (!helpers.utils.isValidTime(helpers.utils.getEventSource(event).value))
{settings.onError.call(helpers.utils.getEventSource(event));}}},utils : {/**
* This function returns true if the enterred key is a number, a colon or one of the allowed special keys.* */isValidKeyStroke : function(event)
{var keyCode = event.keyCode;
/** check if a special key was pressed */
if ($.inArray(keyCode, constants.KEYS.SPECIAL_KEYS_TO_IGNORE) != -1)
return true;/** Only allow numbers and the colon key */
if ((!event.shiftKey && (constants.KEYS.CHARACTER_ZERO <= keyCode
&& keyCode <= constants.KEYS.CHARACTER_NINE || constants.KEYS.KEYPAD_ZERO <= keyCode&& keyCode <= constants.KEYS.KEYPAD_NINE))|| (event.shiftKey && keyCode == constants.KEYS.COLON)){return true;}return false;},/**
* This function pads the values with zeroes and colons.* */applyPadding : function(textBox)
{var val = textBox.value;
if (val != "")
val = parseInt(textBox.value.replace(":", ""), 10) + "";if (val.length > constants.NO_OF_CHARACTERS_WITHOUT_COLON){val = val.substring(val.length - constants.NO_OF_CHARACTERS_WITHOUT_COLON);
}switch (val.length){case 0:
val = val;break;
case 1:
val = "00:0" + val;
break;
case 2:
val = "00:" + val;
break;
case 3:
val = "0" + val.substring(0, 1) + ":" + val.substring(1);break;
case 4:
val = val.substring(0, 2) + ":" + val.substring(2);
break;
}//$(textbox).blur();
//$(textbox).focus();
/**
* mobile browsers seem to not place the caret in the correct place* after the padding of zeroes, and IE8 doesnt support* setselection range but works fine without it.** The basic idea is to add an extra space after the last digit* and "select" it,ensuring that the caret is in the correct position** */if(textBox.setSelectionRange)
{textBox.value = val+" ";
textBox.setSelectionRange(5, 6);}else
{textBox.value = val;}return;
},/**
* This function returns true if the enterred time is* a valid time based on the specified(or default) settings,* else returns false.* */isValidTime : function(strTime)
{if (strTime == "")
return true;var regex = constants.REGEX.TWENTY_FOUR;
switch (settings.hourFormat)
{case constants.HOUR_FORMATS.TWELVE:
regex = constants.REGEX.TWELVE;break;
case constants.HOUR_FORMATS.TWENTY_FOUR:
regex = constants.REGEX.TWENTY_FOUR;break;
}return regex.test(strTime);
},getEventSource:function(event)
{return event.target || event.srcElement;
}}};/**Constants*/
var constants = {
/** Only 2 formats supported now.*/
HOUR_FORMATS : {TWELVE : "12",
TWENTY_FOUR : "24"
},KEYS : {CHARACTER_ZERO : 48,CHARACTER_NINE : 57,KEYPAD_ZERO : 96,KEYPAD_NINE : 105,BACKSPACE : 8,TAB : 9,ENTER : 13,COLON : 186,SPECIAL_KEYS_TO_IGNORE : [8, /**BACKSPACE*/
9, /**DELETE*/
46, /**TAB*/
40, /**DOWN ARROW*/
39, /**LEFT ARROW*/
38, /**UP ARROW*/
37 ,/**LEFT ARROW*/
16 /** SHIFT*/
]},NO_OF_CHARACTERS_WITHOUT_COLON : 4,REGEX : {TWELVE : /^([0-1]?[0-2])([:][0-5]?[0-9])?$/,TWENTY_FOUR : /^([2][0-3]|[0-1]?[0-9])([:][0-5]?[0-9])?$/}};// Create some defaults, extending them with any options that were provided
var settings = $.extend( {
'hourFormat' : '24','onError' : function()
{this.value="";
}}, options);// Method calling logic
if (methods[options])
{return methods[options].apply(this, Array.prototype.slice.call(arguments, 1));} else if (typeof options === 'object' || !options){return methods.init.apply(this, arguments);} else
{$.error('Method ' + options + ' does not exist on jQuery.timefield');}};})(jQuery);
No comments:
Post a Comment