Skip to content

Instantly share code, notes, and snippets.

@IndyIndyIndy
Created February 6, 2019 11:03
Show Gist options
  • Save IndyIndyIndy/99ddf6421b677efadf6eadd4271f1bc0 to your computer and use it in GitHub Desktop.
Save IndyIndyIndy/99ddf6421b677efadf6eadd4271f1bc0 to your computer and use it in GitHub Desktop.
// Automatically convert date inputs to a required format
// Works, but needs a lot of refactoring
var dateInputHelper = new DateInputHelper();
function DateInputHelper() {
var self = this;
self.cursorPosition = null;
self.buildDateInput = function($input, separator, minYear, maxYearLimit) {
var maxYear = self.buildMaxYear(maxYearLimit);
var altSeparator = '/';
if (separator == '/') {
altSeparator = '.';
}
$input.on("keypress", function (e) {
return self.isKeyAllowed($input.val(), e.key);
}).on('keydown', function (e) {
if(e.key === altSeparator) {
setTimeout(function() {
e.target.value += separator;
}, 4);
e.preventDefault();
}
}).on('change', function (e) {
var value = $input.val();
value = value.replace(/\//g, '.');
$input.val(value);
}).on('keyup', function (e) {
var val = $input.val();
if (isNaN(e.key)) {
// not a number
return false;
}
// auto add slash
if (
(
(this.selectionEnd === 3 && val.length === 3) ||
(this.selectionEnd === 6 && val.length === 6)
) && val.substring(0, val.length - 1).slice(-1) != separator && val.split(separator).length < 3
) {
$input.val(val.substring(0, val.length - 1)+separator+e.key);
}
self.saveCursorPosition(this);
var clearedValue = self.autoCorrectDate($input.val(), separator, minYear, maxYear, 'date', false);
$input.val(clearedValue);
self.revertCursorPosition(this);
}).on("focusout", function () {
if ($input.val().length > 0) {
var clearedValue = self.autoCorrectDate($input.val(), separator, minYear, maxYear, 'date', true);
$input.val(clearedValue);
}
});
};
self.buildMonthInput = function($input, separator, minYear, maxYearLimit) {
var maxYear = self.buildMaxYear(maxYearLimit);
var altSeparator = '/';
if (separator == '/') {
altSeparator = '.';
}
$input.on("keypress", function (e) {
return self.isKeyAllowed($input.val(), e.key);
}).on('keydown', function (e) {
if(e.key === altSeparator) {
setTimeout(function() {
e.target.value += separator;
}, 4);
e.preventDefault();
}
}).on('change', function (e) {
var value = $input.val();
value = value.replace(/\//g, '.');
$input.val(value);
}).on('keyup', function (e) {
var val = $input.val();
if (isNaN(e.key)) {
// not a number
return false;
}
// auto add slash
if ((this.selectionEnd === 3 && val.length === 3) && val.substring(0, val.length - 1).slice(-1) != separator) {
$input.val(val.substring(0, val.length - 1)+separator+e.key);
}
self.saveCursorPosition(this);
var clearedValue = self.autoCorrectDate($input.val(), separator, minYear, maxYear, 'month', false);
$input.val(clearedValue);
self.revertCursorPosition(this);
}).on("focusout", function () {
if ($input.val().length > 0) {
var clearedValue = self.autoCorrectDate($input.val(), separator, minYear, maxYear, 'month', true);
$input.val(clearedValue);
}
});
};
self.autoCorrectDate = function (value, separator, minYear, maxYear, mode, padZero) {
if (separator == '/') {
value = value.replace(/\./g, '/');
} else {
value = value.replace(/\//g, '.');
}
var dateParts = value.split(separator);
var clearedValue = '';
switch(mode) {
case 'date':
var maxLength = 3;
var dayIndex = 0;
var monthIndex = 1;
var yearIndex = 2;
break;
case 'month':
var maxLength = 2;
var dayIndex = null;
var monthIndex = 0;
var yearIndex = 1;
break;
default:
throw new Error('Invalid autocorrect mode');
}
if (dateParts.length > maxLength) {
dateParts.length = maxLength;
}
for (var i in dateParts) {
var numberString = dateParts[i];
var originalNumber = parseInt(numberString);
var number = parseInt(numberString);
// day
if (i == dayIndex) {
if (isNaN(number)) {
number = 1;
}
number = self.padBetween(number, 0, self.getMaxDays(dateParts));
if (number == 0 && dateParts.length > 1) {
number = '01';
}
if (padZero && (number < 10 && number > 0)) {
number = '0' + number.toString();
}
}
// month
if (i == monthIndex) {
if (isNaN(number)) {
number = 1;
}
number = self.padBetween(number, 0, 12);
if (number == 0 && ((mode == 'month' && dateParts.length > 1) || dateParts.length > 2)) {
number = '01';
}
if (padZero && (number < 10 && dateParts.length > 2)) {
number = '0' + number.toString();
}
}
// year
if (i == yearIndex && numberString.length > 3) {
if (isNaN(number)) {
number = 2000;
}
number = self.padBetween(number, minYear, maxYear);
}
if (number === originalNumber) {
number = numberString;
}
if (i > 0) {
clearedValue += separator;
}
if (!isNaN(number)) {
clearedValue += number;
}
}
return clearedValue;
};
self.buildMaxYear = function (maxYearLimit) {
var currentYear = new Date().getFullYear();
return currentYear+maxYearLimit;
};
self.isKeyAllowed = function (value, key) {
if (parseInt(key) !== parseInt(key) && key !== '/' && key !== '.') {
// not a number and not a slash
return false;
}
if (value === '' && (key === '/' || key === '.')) {
// slash not allowed as first char
return false;
}
return true;
};
self.saveCursorPosition = function (element) {
self.cursorPosition = element.selectionEnd;
};
self.revertCursorPosition = function (element) {
element.selectionEnd = self.cursorPosition;
};
self.padBetween = function(number, min, max) {
if (number < min) {
number = min;
}
if (number > max) {
number = max;
}
return number;
};
self.getMaxDays = function (dateParts) {
var maxDays = 31;
if (dateParts.length > 1) {
var month = parseInt(dateParts[1]);
if (month > 0) {
if ([1, 3, 5, 7, 8, 10, 12].indexOf(month) !== -1) {
maxDays = 31;
} else if ([4, 6, 9, 11].indexOf(month) !== -1) {
maxDays = 30;
} else if (month == 2) {
maxDays = 29;
}
}
}
return maxDays;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment