Skip to content

Instantly share code, notes, and snippets.

@iamtracy
Created June 10, 2017 14:13
Show Gist options
  • Save iamtracy/468090fefecace04ac468d2c758e5d3f to your computer and use it in GitHub Desktop.
Save iamtracy/468090fefecace04ac468d2c758e5d3f to your computer and use it in GitHub Desktop.
var oPhoneField = document.getElementsByName('Phone')[0]; //get Phone input element
var oErrorMessage = document.createElement('p'); //create paragraph that will contain the error message
var cHasDuplicates = /^\D*(\d)(?:\D*|\1)*$/; //regex for later use
oErrorMessage.classList = 'error-message'; //give error message paragraph class for optional styling via customCSS
//Conditional Error Messages
var cMessages = {
charLength: 'Phone number must contain 3 to 32 characters',
charContent: 'Phone number cannot contain a comma, period, or semicolon',
charRepeated: 'Phone number cannot contain the same digits. ie "1111111111" is not an acceptable number',
charConsecAsc: 'Phone number cannot contain more than 6 consecutive digits. ie "123456" is not an acceptable number',
charConsecDesc: 'Phone number cannot contain more than 6 consecutive digits. ie "654321" is not an acceptable number',
charDigitPerc: 'Phone number contains too many non-digit characters'
};
oPhoneField.addEventListener('blur', validatePhone);
function validatePhone() {
var cPhoneVal = oPhoneField.value; //string value to validate against
var bCharLength = cPhoneVal.length < 3 || cPhoneVal.length > 32; //sets acceptable length between 3 and 32
var bCharContains = cPhoneVal.indexOf(',') > 0 || cPhoneVal.indexOf('.') > 0 || cPhoneVal.indexOf(';') > 0; //no commas, periods, or semi-colons
var bCharDuplicate = cPhoneVal.length >= 9 && cHasDuplicates.test(cPhoneVal); //set length for acceptable repeated characters
var bCharConsecAsc = consecDigits(cPhoneVal, 6, false); //set string, set consecutive number max, true - descending order -> false - ascending order
var bCharConsecDesc = consecDigits(cPhoneVal, 6, true); //set string, set consecutive number max, true - descending order -> false - ascending order
var bNonDigitLimit = calcNonDigits(cPhoneVal, .30); //set string, set acceptable percent of non-digit characters
if (bCharLength) {
printMessage(cMessages.charLength);
return false;
} else if (bCharContains) {
printMessage(cMessages.charContent);
return false;
} else if (bCharDuplicate) {
printMessage(cMessages.charRepeated);
return false;
} else if (bCharConsecAsc) {
printMessage(cMessages.charConsecAsc);
return false;
} else if (bCharConsecDesc) {
printMessage(cMessages.charConsecDesc);
return false;
} else if (bNonDigitLimit) {
printMessage(cMessages.charDigitPerc);
return false;
} else {
printMessage('');
return true;
}
}
//consecDigits() is based on a function created by stackoverflow user 'AGE'
//http://stackoverflow.com/questions/30928293/how-to-find-whether-specific-number-of-continuous-consecutive-numbers-are-contai
function consecDigits(str, consecutive, descending) {
if (descending) {
var cPhoneVal = reverseString(str);
} else {
var cPhoneVal = str;
}
var curr,
prev,
count = 0;
for (var i = 0; i < cPhoneVal.length; ++i) {
curr = parseInt(cPhoneVal.split('')[i]);
if (isNumeric(curr)) {
if (count === 0) {
++count;
} else if (prev + 1 === curr) {
++count;
if (count === consecutive) {
return true;
}
}
prev = curr;
}
}
return false;
}
function reverseString(str) {
var splitString = str.split("");
var reverseArray = splitString.reverse();
var joinArray = reverseArray.join("");
return joinArray;
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function calcNonDigits(phoneVal, percent) {
var cDigits = phoneVal.replace(/[^\d]/g, '');
var iNonDigits = phoneVal.length - cDigits.length;
var bTest = iNonDigits / phoneVal.length >= percent;
if (bTest) return true;
return false;
}
function printMessage(message) {
oErrorMessage.innerHTML = '';
oErrorMessage.innerHTML = message;
oPhoneField.parentNode.appendChild(oErrorMessage);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment