patternjavascriptMinor
Time Input Mask Plugin in jQuery
Viewed 0 times
masktimeinputpluginjquery
Problem
I've been searching for a suitable plugin for an input mask for a time field. There are some inherent difficulties with masking a time input, while giving the user the most flexibility.
I have tried to recreate what Google Calendar uses for their time inputs, minus the drop down select. What I've made seems to work, but it's definitely missing a bit of elegance.
I want you to help me write this code better.
What I have is basically a lot of logic statements. I wrote down, on a piece of paper, all the possible ways I could enter a time, and how I would want to plugin to translate that into a standard "00:00 xm" format.
Here is that list:
With that out of the way... here's the plugin code:
```
/*!
* jQuery lightweight plugin boilerplate
* Original author: @ajpiano
* Further changes, comments: @addyosmani
* Licensed under the MIT license
*/
;(function ( $, window, document, undefined ) {
// Create the defaults once
var pluginName = 'timeMask',
defaults = {
propertyName: "value"
};
// The actual plugin constructor
function Plugin( element, options ) {
this.$el = $(element);
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
this._val = this.$el.val();
this.init();
}
// retruns array of numbers in a string
Plugin.prototype = {
_getValueInts: function() {
var ints=[],
j =0;
// Get array of number values
for(i=0; i= 0) {
ints[j] = parseInt(this._val[i]);
j++;
}
}
return ints;
I have tried to recreate what Google Calendar uses for their time inputs, minus the drop down select. What I've made seems to work, but it's definitely missing a bit of elegance.
I want you to help me write this code better.
What I have is basically a lot of logic statements. I wrote down, on a piece of paper, all the possible ways I could enter a time, and how I would want to plugin to translate that into a standard "00:00 xm" format.
Here is that list:
- abc => invalid
- abc1:23 => "1:23am"
- 123p => "1:23pm"
- 1 => "1:00am"
- 12 => "12:00am"
- 91 => "9:10am"
- 05 => "5:00pm"
- 123 => "1:23am"
- 170 => invalid
- 013 => invalid
- 1234 => "12:34am"
- 1934 => "7:34pm"
- 9123 => invalid
- 00:12 => "12:12am"
- 1294 => invalid
With that out of the way... here's the plugin code:
```
/*!
* jQuery lightweight plugin boilerplate
* Original author: @ajpiano
* Further changes, comments: @addyosmani
* Licensed under the MIT license
*/
;(function ( $, window, document, undefined ) {
// Create the defaults once
var pluginName = 'timeMask',
defaults = {
propertyName: "value"
};
// The actual plugin constructor
function Plugin( element, options ) {
this.$el = $(element);
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
this._val = this.$el.val();
this.init();
}
// retruns array of numbers in a string
Plugin.prototype = {
_getValueInts: function() {
var ints=[],
j =0;
// Get array of number values
for(i=0; i= 0) {
ints[j] = parseInt(this._val[i]);
j++;
}
}
return ints;
Solution
Spelling
Remove commented out code
Once you feel the code is ready to be used, delete commented out code such as
JSHint
You have a fiddle, try clicking the JsHint button, you will find a number of things to clean up.
_getValueInts
You could use
becomes
or even, if you are okay with dropping curlies and not using
getTimeStr
There be bugs in this function:
Will turn
In general you should in this function move as quickly as possible into the variables hours and minutes and no longer mess around with that integer array, and then only move in 1 place from
Your requirements are so intense that I did not even try to rewrite this code, are you sure you're not overdoing it?
- pluing -> plugin
Remove commented out code
Once you feel the code is ready to be used, delete commented out code such as
/* // This would be nice, but this plugin pattern isn't set up for public methods...
destroy: function() {
console.log('destroying');
this.$el.unbind('.timeMask');
}*/JSHint
You have a fiddle, try clicking the JsHint button, you will find a number of things to clean up.
- Semicolon in front of
(function ($, window, document, undefined) {
- If you are using parseInt, you should provide the
radix (10)
- You have missing semicolons
- You have an extra comma on
}, // end init, this can break on older versions of IE
_getValueInts
You could use
[].push here to make your code simpler, also you did not declare i._getValueInts: function () {
var ints = [],
j = 0;
// Get array of number values
for (i = 0; i = 0) {
ints[j] = parseInt(this._val[i]);
j++;
}
}
return ints;
},becomes
_getValueInts: function () {
// Get array of number values
for (var i = 0, ints = []; i = 0) {
ints.push( parseInt(this._val[i],10);
}
}
return ints;
}or even, if you are okay with dropping curlies and not using
parseInt:_getValueInts: function () {
// Get array of number values
for (var i = 0, ints = []; i = 0 )
ints.push( +this._val[i] );
return ints;
}getTimeStr
There be bugs in this function:
} else if (n[1] >= 6) { // "17" => 05:00 pmWill turn
13, 14 and 15 to 13AM, 14AM and 15AM, which obviously is impossible..In general you should in this function move as quickly as possible into the variables hours and minutes and no longer mess around with that integer array, and then only move in 1 place from
17 -> 5PM. Your requirements are so intense that I did not even try to rewrite this code, are you sure you're not overdoing it?
Code Snippets
/* // This would be nice, but this plugin pattern isn't set up for public methods...
destroy: function() {
console.log('destroying');
this.$el.unbind('.timeMask');
}*/_getValueInts: function () {
var ints = [],
j = 0;
// Get array of number values
for (i = 0; i < this._val.length; i++) {
if (parseInt(this._val[i]) >= 0) {
ints[j] = parseInt(this._val[i]);
j++;
}
}
return ints;
},_getValueInts: function () {
// Get array of number values
for (var i = 0, ints = []; i < this._val.length; i++) {
if (parseInt(this._val[i],10) >= 0) {
ints.push( parseInt(this._val[i],10);
}
}
return ints;
}_getValueInts: function () {
// Get array of number values
for (var i = 0, ints = []; i < this._val.length; i++)
if ( +this._val[i] >= 0 )
ints.push( +this._val[i] );
return ints;
}} else if (n[1] >= 6) { // "17" => 05:00 pmContext
StackExchange Code Review Q#9517, answer score: 2
Revisions (0)
No revisions yet.