Skip to content

Instantly share code, notes, and snippets.

@ryanand26
Created March 24, 2014 11:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanand26/9738371 to your computer and use it in GitHub Desktop.
Save ryanand26/9738371 to your computer and use it in GitHub Desktop.
jQuery Validation integration
/*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