Last active
September 6, 2015 19:57
-
-
Save bhalash/4126f24a5cdd32d99f47 to your computer and use it in GitHub Desktop.
Datechecker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Time and Date Checker | |
* ----------------------------------------------------------------------------- | |
* Does: | |
* | |
* 1. Append either time (hour:minute) or date (day/month/year) selects to | |
* target element. | |
* 2. Selects are prefixed with a given string, and suffixed with the input | |
* type foo_year, foo_month, etc. | |
* 3. A given time and date can be provided by a Unix timestamp, and the inputs | |
* will be set to this value. | |
*/ | |
;(function($) { | |
$.fn.checker = function(prefix, target) { | |
var add = { | |
/* Inputs are added without a value or options. These are set via | |
* update.foo() | |
*/ | |
fieldset: function(prefix) { | |
var $fieldset = $('<fieldset>').append('Until: '); | |
$.each(['hour', 'minute'], function(index, name) { | |
add.input.call($fieldset, name, prefix); | |
if (index === 0) { | |
$fieldset.append(' : '); | |
} | |
}); | |
$fieldset.append('<br />').append('on: '); | |
$.each(['day', 'month', 'year'], function(index, name) { | |
add.input.call($fieldset, name, prefix); | |
if (index === 0 || index === 1) { | |
// Insert dividing forward slash. | |
$fieldset.append(' / '); | |
} | |
}); | |
$fieldset.on('change', 'input', validate); | |
inputSetup.call($fieldset); | |
this.append($fieldset); | |
}, | |
input: function(name, prefix) { | |
// Generate hour and minute input HTML. | |
var attr = (prefix) ? prefix + '-' + name : name; | |
var max = (name === 'hour') ? 23 : 59; | |
var size = (name === 'year') ? 4 : 2; | |
var input = $('<input>', { | |
type: 'text', | |
'class': attr, | |
id: attr, | |
name: attr, | |
minlength: size, | |
maxlength: size | |
}); | |
// Size attr is ignored in Chrome if set above. | |
input.attr('size', size).data('name', name); | |
this.append(input); | |
} | |
}; | |
var inputSetup = function() { | |
// Reset all input values to whatever target says. | |
$(this).find('input').empty().each(function() { | |
padInputValue.call(this, target[$(this).data('name')]); | |
}); | |
} | |
var padInputValue = function(value) { | |
// Pad input values with zeroes for neatness. | |
var zeroes = ''; | |
value = value.toString() || $(this).val().toString(); | |
for (var i = 0; i < $(this).attr('size') - value.length; i ++) { | |
zeroes += '0'; | |
} | |
$(this).val(zeroes + value); | |
} | |
var validate = function(event) { | |
// 0. Get element type/name from added data. | |
var name = $(this).data('name'); | |
// 1. Strip leading zeroes. | |
var value = parseInt($(this).val(), 10); | |
// 2. Validate regex. Regex acounts for leading zeros anyhow. | |
var valid = regex[name].test(value); | |
$(this).toggleClass('input-error', !valid); | |
if (!valid) { | |
// 3. If regex is invalid, focus back on input. | |
$(this).focus().select(); | |
return; | |
} | |
// 5. Update target date object. | |
target[name] = value; | |
if (name.match(/^(day|month|year)$/)) { | |
/* 6. If date change, ensure day of month isn't greater than | |
* days in month. | |
*/ | |
var dim = date.daysInMonth(target.year, target.month); | |
if (target.day > dim) { | |
target.day = dim; | |
value = dim; | |
if (name !== 'day') { | |
$(this).siblings('[id*=day]').val(dim); | |
} | |
} | |
} | |
if (date.timeLessThanNow(target, name)) { | |
// 7. If target date < current datetime, reset it. | |
target = date.split($.now()); | |
inputSetup.call($(this).parent()); | |
} | |
// 8. Pad value. | |
padInputValue.call(this, value); | |
return this; | |
} | |
var regex = { | |
// Regex for input evaluation. | |
minute: /^([0-5])?\d$/, | |
hour: /^((\d)|[0-1]\d|2[0-3])$/, | |
day: /^(([1-9])?|[1-2]\d|3[0-2])$/, | |
month: /^(0?|[1-9]|1[0-2])$/, | |
year: /^[1-2](9|0)\d{2}$/ | |
}; | |
var date = { | |
daysInMonth: function(year, month) { | |
// Return days in given month. | |
return new Date(year, month, 0).getDate(); | |
}, | |
split: function(date) { | |
// Split datetime object into comparison date. | |
var valid = (new Date(date)) > 0; | |
date = (valid) ? new Date(date) : new Date(); | |
return { | |
minute: date.getMinutes(), | |
hour: date.getHours(), | |
day: date.getDate(), | |
month: date.getMonth() + 1, | |
year: date.getFullYear() | |
}; | |
}, | |
join: function(timestamp) { | |
// Rejoin split datetime object for evaluation. | |
return Math.floor(new Date( | |
timestamp.year, | |
timestamp.month - 1, | |
timestamp.day, | |
timestamp.hour, | |
timestamp.minute, | |
0, 0 | |
).getTime() / 1000); | |
}, | |
timeLessThanNow: function(time, name) { | |
// Is updated target time less than the current time? | |
return (date.join(time) < Math.floor($.now() / 1000)); | |
}, | |
}; | |
target = date.split(target || null); | |
add.fieldset.call(this, prefix); | |
return this; | |
} | |
})(jQuery); | |
/** | |
* Date and Time Setup | |
* ----------------------------------------------------------------------------- | |
* Add change to checkboxes and set state. | |
*/ | |
jQuery('#kaitain-sticky-expiry').checker('stickyexpires', pmFeatured.expiry); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment