Created
March 24, 2014 11:12
-
-
Save ryanand26/9738371 to your computer and use it in GitHub Desktop.
jQuery Validation integration
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
/*jslint bitwise: true, eqeqeq: true, passfail: false, nomen: false, plusplus: false, undef: true, evil: true */ | |
/*global window, document, $, jQuery, LBI, self, Modernizr, setTimeout, define, require */ | |
define(['validate', 'createFormError' ], function (validateInclude, createFormError) { | |
var validationInitialized = false, | |
isSelectValid = 'is-select-valid', | |
isSelectValidMobile = 'is-select-valid-mobile', | |
validationDefaults = { | |
errorClass: "has-error", | |
validClass: "is-valid-marker", | |
validFieldClass: "is-valid-field", | |
formErrorSelect : ".form-error", | |
showErrors: showErrorsHandler, | |
markValidItems: true | |
}, | |
validationSettings; | |
/** | |
* Object definition | |
*/ | |
function ABGValidator(rootElement, validationOptions) { | |
// ensure a UI element has been specified | |
if (!rootElement) { | |
throw 'Invalid argument exception: you must specify an element to create the map in.'; | |
} | |
// ensure constructor is called with new keyword | |
if (!(this instanceof ABGValidator)) { | |
return new ABGValidator(rootElement, specifiedOptions); | |
} | |
this.form = rootElement; | |
//init validation, only valid on a form tag | |
if (rootElement[0].nodeName.toLowerCase() === 'form') { | |
validationSettings = $.extend(true, {}, validationDefaults, validationOptions); | |
rootElement.validate(validationSettings); | |
} | |
return this; | |
} | |
ABGValidator.prototype = { | |
valid : function () { | |
return this.form.valid(); | |
}, | |
createError : function (message, supporting, direction) { | |
return createFormError.getError(message, supporting, direction); | |
}, | |
removeErrors : function (formParam) { | |
var form = formParam || this.form; | |
return removeErrors(form); | |
} | |
}; | |
/** | |
* Show errors function | |
*/ | |
function showErrorsHandler (errorMap, errorList) { | |
var form = $(this.currentForm), | |
i, elements; | |
//remove old errors | |
removeErrors(form); | |
if(errorList.length) { | |
for (i = 0; this.errorList[i]; i += 1) { | |
//show only the first error message | |
showError(errorList[i].element, errorList[i].message, i === 0); | |
if (validationSettings.markValidItems === true) { | |
removeValid(errorList[i].element); | |
} | |
} | |
} | |
//mark all valid fields as valid | |
if (validationSettings.markValidItems === true) { | |
for (i = 0; this.successList[i]; i += 1) { | |
showValid(this.successList[i]); | |
} | |
} | |
} | |
/** | |
* Show error | |
*/ | |
function showError (fieldParam, message, addMessageParam) { | |
var direction = 'north', | |
field = $(fieldParam), | |
addMessageToPage = (addMessageParam !== false), | |
errorHTML, newError, errorInsertPoint; | |
if (field[0].nodeName.toLowerCase() === 'select') { | |
field.parent().addClass(validationSettings.errorClass); | |
errorInsertPoint = field.parents('.form-row'); | |
} | |
else if (field.attr('type') === 'checkbox') { | |
field.parent() | |
.addClass(validationSettings.errorClass); | |
errorInsertPoint = field.parent().parent(); | |
} | |
else { | |
field.addClass(validationSettings.errorClass); | |
errorInsertPoint = field.parent(); | |
} | |
//create message Html | |
if (addMessageToPage === true) { | |
errorHTML = createFormError.getError(message, '', direction); | |
errorInsertPoint.append(errorHTML); | |
setScroll(field.parent(), true); | |
} | |
} | |
/** | |
* Remove error | |
*/ | |
function removeErrors (form) { | |
form.find('.' + validationSettings.errorClass).removeClass(validationSettings.errorClass); | |
form.find(validationSettings.formErrorSelect).remove(); | |
} | |
/** | |
* Show valid marker | |
*/ | |
function showValid (element) { | |
var validClass = validationSettings.validClass, | |
htmlTemplate = '<span data-icon="" class="' + validClass + '"></span>', | |
validElem = $(element); | |
//only add to text inputs | |
if (validElem[0].nodeName.toLowerCase() === 'input') { | |
if (validElem.hasClass(validationSettings.lookAheadFieldSelect.replace('.', '')) === false && validElem.attr('type') !== 'checkbox' && validElem.attr('type') !== 'radio') { | |
if (validElem.siblings('.' + validClass).length === 0) { | |
validElem | |
.addClass(validationSettings.validFieldClass) | |
.after(htmlTemplate); | |
} | |
} | |
} | |
else if (validElem[0].nodeName.toLowerCase() === 'select') { | |
if (ABG.isMobile) { | |
$(element).parent().addClass(isSelectValidMobile); | |
} | |
else { | |
$(element).parent().addClass(isSelectValid); | |
if (validElem.siblings('.' + validClass).length === 0) { | |
validElem.after(htmlTemplate); | |
} | |
} | |
} | |
} | |
/** | |
* Remove valid marker | |
*/ | |
function removeValid (element) { | |
var $element = $(element); | |
if (element.nodeName.toLowerCase() === 'select') { | |
if (ABG.isMobile) { | |
$element.parent().removeClass(isSelectValidMobile); | |
return; | |
} | |
else { | |
$element.parent().removeClass(isSelectValid); | |
} | |
} | |
$element | |
.removeClass(validationSettings.validFieldClass) | |
.siblings('.' + validationSettings.validClass).remove(); | |
} | |
/** | |
* Set the scroll position on the page to ensure items are in view | |
*/ | |
function setScroll(targetElem, force) { | |
var elementTop = targetElem.offset().top, | |
currentTop = document.documentElement.scrollTop || document.body.scrollTop; | |
$('window, body').animate({ | |
scrollTop: elementTop - 15 | |
}, 'fast'); | |
return elementTop; | |
} | |
/***** | |
* Custom validation | |
*****/ | |
/** | |
* Validate that the first line of the address exists | |
*/ | |
function validateAddressEntry (value, element, params) { | |
//if the addr1 box is hidden then fail validation | |
if ($(params[0]).is(':hidden')) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Validate that the first line of the address exists | |
*/ | |
function validateSelect (value, element, params) { | |
var indexValue = params[0] * 1; | |
//if the first option is selected then fail | |
if (element.selectedIndex === indexValue) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Validate that the field contains only numbers | |
*/ | |
function strictlyNumberic (value, element, params) { | |
var isNumberRegex = new RegExp('^[0-9]+$'); | |
if (isNumberRegex.test(value) === false) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Validate card number length against the selected type | |
*/ | |
function validateCardNumber (value, element, params) { | |
var cardType = $(params[0]).val(); | |
if (cardType === 'Visa' || cardType === 'MasterCard') { | |
if (value.length !== 16) { | |
return false; | |
} | |
} | |
else if (cardType === 'American Express') { | |
if (value.length !== 15) { | |
return false; | |
} | |
} | |
else if (cardType === 'Diners') { | |
if (value.length < 14 && value.length > 16 ) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Validate card number using the Luhn test | |
* http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#JavaScript | |
*/ | |
var validateCardNumberLunh = (function() { | |
var luhnArr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]; | |
return function(str) { | |
var counter = 0, | |
incNum, | |
odd = false, | |
temp = String(str).replace(/[^\d]/g, ""); | |
if ( temp.length === 0) { | |
return false; | |
} | |
for (var i = temp.length-1; i >= 0; i -= 1) { | |
incNum = parseInt(temp.charAt(i), 10); | |
counter += (odd = !odd)? incNum : luhnArr[incNum]; | |
} | |
return (counter%10 === 0); | |
}; | |
})(); | |
/** | |
* Validate | |
*/ | |
function validateCardName (value, element, params) { | |
if (value.length > 30) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Validate | |
*/ | |
function validateCardMonth (value, element, params) { | |
//get the current date | |
var yearSelect, inputMonth, inputYear, | |
rightNow = new Date(), | |
thisMonth = rightNow.getMonth() + 1, | |
thisYear = rightNow.getFullYear(); | |
//get the month | |
yearSelect = $(params[0]); | |
if (yearSelect[0].selectedIndex !== 0) { | |
inputMonth = $(element).val() * 1; | |
inputYear = yearSelect.val() * 1; | |
//if the year selected is the same | |
if (inputYear === thisYear && inputMonth < thisMonth) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Validate | |
*/ | |
function validateCardCVV (value, element, params) { | |
var cardType = $(params[0]).val(), | |
cvvLength = 3; | |
//if it's amex change the valid number | |
if (cardType === params[1]) { | |
cvvLength = 4; | |
} | |
if (value.length !== cvvLength) { | |
return false; | |
} | |
return true; | |
} | |
function initValidation (rootElement, validationOptions) { | |
var validatorInstance = new ABGValidator(rootElement, validationOptions); | |
return validatorInstance; | |
} | |
(function autoInit (options) { | |
if (validationInitialized === false) { | |
//define default message values | |
$.extend($.validator.messages, { | |
"required" : ABG.errorMessages.genericEmpty | |
}); | |
jQuery.validator.addMethod("addressEntered", validateAddressEntry, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateSelect", validateSelect, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("strictlyNumberic", strictlyNumberic, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateCardNumber", validateCardNumber, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateCardNumberLunh", validateCardNumberLunh, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateCardName", validateCardName, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateCardMonth", validateCardMonth, ABG.errorMessages.genericEmpty); | |
jQuery.validator.addMethod("validateCardCVV", validateCardCVV, ABG.errorMessages.genericEmpty); | |
} | |
return this; | |
})(); | |
return { | |
init: initValidation | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment