HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Time Input Mask Plugin in jQuery

Submitted by: @import:stackexchange-codereview··
0
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:

  • 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

  • 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 pm


Will 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 pm

Context

StackExchange Code Review Q#9517, answer score: 2

Revisions (0)

No revisions yet.