/**
* @author Virtuosi Media
* @link http://www.virtuosimedia.com
* @version 1.0
* @copyright Copyright (c) 2008, Virtuosi Media
* @License: MIT License
* Description: A form validator class
* Documentation: http://www.virtuosimedia.com
* Requirements: MooTools 1.2 Core - See http://mootools.net
*/
var vmValidator=new Class({Implements:[Events,Options],options:{disableSubmit:true,errorDisplay:'belowInput',errorListClass:'errorList',errorListItemClass:'errorListItem',errorElement:'errorElement',errorLabel:'errorLabel',labelDisplay:'before',successElementClass:'successElement',successLabelClass:'successLabel',validateOnBlur:true,validateOnSubmit:true},initialize:function(formId,options){this.setOptions(options);this.form=formId;this.formElements=new Hash;if(this.options.validateOnSubmit==true){$(this.form).addEvent('submit',function(e){this.executeAllValidators(e);if(this.options.errorDisplay=='aboveForm'){var numberErrors=$(this.form+'ErrorList').getElements('li[class='+this.options.errorListItemClass+']');}else{var numberErrors=$(this.form).getElements('li[class='+this.options.errorListItemClass+']');}if(numberErrors.length!=0){return false;}}.bind(this));}this.buildFormElementArray($(this.form),this.formElements,this);},buildFormElementArray:function(form,formElements,validator){var formTextArray=form.getElements('input[type=text]');var formPasswordArray=form.getElements('input[type=password]');var formRadioArray=form.getElements('input[type=radio]');var formCheckboxArray=form.getElements('input[type=checkbox]');var formFileArray=form.getElements('input[type=file]');var formTextareaArray=form.getElements('textarea');var formSelectArray=form.getElements('select');var formElementsArray=[formTextArray,formPasswordArray,formCheckboxArray,formFileArray,formTextareaArray,formSelectArray,formRadioArray].clean();formElementsArray.each(function(item){item.each(function(item){var elementName=item.getProperty('name');element=new Hash({elName:elementName,validators:new Hash()});if(validator.options.validateOnBlur==true){item.addEvent('blur',function(event){validator.executeValidators(elementName,event,this);});}formElements[elementName]=element;});});},setValidator:function(elementName,validatorName,vFunction,error){this.formElements[elementName]['validators'][validatorName]=new Hash({validatorFunction:vFunction,validatorError:error});},executeValidators:function(elementName,event,eventType){this.formElements[elementName]['validators'].each(function(index){eval(index.validatorFunction);},this);},executeAllValidators:function(e){this.formElements.each(function(item){this.executeValidators(item.elName,e,'submit');}.bind(this));},createErrorId:function(name,error){var errorString=error.capitalize();errorString=errorString.replace(/[^a-zA-Z0-9]+/g,'');var errorId=name+errorString;return errorId;},createErrorList:function(name){var errorList=new Element('ul',{'id':name+'ErrorList','class':this.options.errorListClass});return errorList;},checkErrorList:function(errorList,errorId,name,element,label,error){if(errorList!=null){var errorListId=errorList.get('id');var errorListElements=errorList.getElements('li[class='+this.options.errorListItemClass+']');if(errorListElements.length!=0){errorListElements.each(function(el){if(el.getProperty('id')==errorId){el.destroy();}});this.destroyErrorList(errorList,name,element,label);}else{this.destroyErrorList(errorList,name,element,label);}}else{this.inputSuccess(element,label);this.enableSubmit();}},destroyErrorList:function(errorList,name,element,label){var errorCheck=errorList.getElements('li[class='+this.options.errorListItemClass+']');if(this.options.errorDisplay=='aboveForm'){if(errorCheck.length==0){errorList.destroy();this.inputSuccess(element,label);this.enableSubmit();}else{errorCheck=errorList.getElements('li[id^='+name+']');if(errorCheck.length==0){this.inputSuccess(element,label);}}}else{if(errorCheck.length==0){errorList.destroy();this.inputSuccess(element,label);this.enableSubmit();}}},inputSuccess:function(element,label){if(element.hasClass(this.options.errorElement)){element.removeClass(this.options.errorElement);}if(label.hasClass(this.options.errorLabel)){label.removeClass(this.options.errorLabel);}label.addClass(this.options.successLabelClass);element.addClass(this.options.successElementClass);},enableSubmit:function(){if(this.options.disableSubmit==true){var numberErrors=$(this.form).getElements('li[class='+this.options.errorListItemClass+']');if(numberErrors.length==0){var submitButton=$(this.form).getElements('[type=submit]');submitButton.removeProperty('disabled');}}},success:function(name,element,label,error){var errorId=this.createErrorId(name,error);var errorList=$(name+'ErrorList');if(this.options.errorDisplay=='aboveForm'){errorList=$(this.form+'ErrorList');}this.checkErrorList(errorList,errorId,name,element,label,error);},error:function(name,element,label,error){var errorId=this.createErrorId(name,error);var errorMessage=new Element('li',{'id':errorId,'class':this.options.errorListItemClass,'html':error});if(element.hasClass(this.options.successElementClass)){element.removeClass(this.options.successElementClass);}if(label.hasClass(this.options.successLabelClass)){label.removeClass(this.options.successLabelClass);}label.addClass(this.options.errorLabel);element.addClass(this.options.errorElement);if(this.options.errorDisplay=='aboveForm'){var formId=this.form;var errorListId=formId+'ErrorList';if($(errorListId)){var errorList=$(errorListId);}else{var errorList=this.createErrorList(formId);errorList.inject(formId,'before');}}else if(this.options.errorDisplay=='aboveInput'){if($(name+'ErrorList')!=null){var errorList=$(name+'ErrorList');}else{var errorList=this.createErrorList(name);if(this.options.labelDisplay=='before'){errorList.inject(label,'before');}else if(this.options.labelDisplay=='after'){errorList.inject(element,'before');}}}else if(this.options.errorDisplay=='belowInput'){if($(name+'ErrorList')!=null){var errorList=$(name+'ErrorList');}else{var errorList=this.createErrorList(name);if(this.options.labelDisplay=='before'){errorList.inject(element,'after');}else if(this.options.labelDisplay=='after'){errorList.inject(label,'after');}}}if(!$(errorId)){errorMessage.inject(errorList);}if(this.options.disableSubmit==true){var submitButton=$(this.form).getElements('[type=submit]');submitButton.setProperty('disabled','true');}},checkValid:function(valid,name,element,label,error){if(valid==true){this.success(name,element,label,error);}else if(valid==false){this.error(name,element,label,error);}},internalRegEx:function(regex,name,error){var element=$(this.form).getElement('[name='+name+']');var label=$(this.form).getElement('label[for='+name+']');var value=element.get('value').trim();var regexTest=new RegExp(regex);var valid=false;if(regexTest.test(value)){valid=true;}this.checkValid(valid,name,element,label,error);},internalChecked:function(name,error,e,eventType){var element=$(this.form).getElement('[name='+name+']');var label=$(this.form).getElement('label[for='+name+']');if(element.get('type')=='checkbox'){var checked=false;if(element.get('checked')==true){checked=true;};}else{var currentElement;if(!e)var e=window.event;if(e.target){currentElement=e.target;}else if(e.srcElement){currentElement=e.srcElement;}if(currentElement.nodeType==3){currentElement=currentElement.parentNode;};var element=$(this.form).getElements('[name='+name+']');var lastElement=(element.length-1);var checked;element.each(function(item,index){if(item.checked){checked=true;};if((eventType!='submit')&&((Browser.Engine.gecko)||(Browser.Engine.presto))){if(currentElement==element[lastElement]){element.each(function(item){if(item.checked){checked=true;};});if(checked!=true){checked=false;};}}else{if(checked!=true){checked=false;};}});element=element[lastElement];}this.checkValid(checked,name,element,label,error);},internalLength:function(name,error,type,length1,length2){var element=$(this.form).getElement('[name='+name+']');var label=$(this.form).getElement('label[for='+name+']');var value=element.get('value').trim().length;var valid=true;if(type=='minLength'){if(value<length1){valid=false;}}else if(type=='maxLength'){if(value>length1){valid=false;}}else if(type=='range'){if((value<length1)||(value>length2)){valid=false;}}this.checkValid(valid,name,element,label,error);},internalCompare:function(name,compareName,error,type){var element=$(this.form).getElement('[name='+name+']');var element2=$(this.form).getElement('[name='+compareName+']');var label=$(this.form).getElement('label[for='+name+']');var value=element.get('value').trim();var value2=element2.get('value').trim();var valid=true;if(type=='matches'){if(value!=value2){valid=false;}}else if(type=='noMatches'){if(value==value2){valid=false;}}this.checkValid(valid,name,element,label,error);},internalArray:function(name,error,type,arrayCheck){var element=$(this.form).getElement('[name='+name+']');var label=$(this.form).getElement('label[for='+name+']');var value=element.get('value').trim();if(type=='includes'){var valid=false;arrayCheck.each(function(item){var regexTest=new RegExp(item);if(regexTest.test(value)){valid=true;}});}else if(type=='excludes'){var valid=true;arrayCheck.each(function(item){var regexTest=new RegExp(item);if(regexTest.test(value)){valid=false;}});}this.checkValid(valid,name,element,label,error);},validateRegEx:function(regex,name,error){var vFunction='this.internalRegEx(\''+regex+'\', \''+name+'\', \''+error+'\');';this.setValidator(name,regex,vFunction,error);},required:function(name,error){if(!error){error="This field is required.";}var element=$(this.form).getElements('[name='+name+']');var type=element.getProperty('type');regexTest=new RegExp('radio');if((regexTest.test(type))||(type=='checkbox')){var vFunction='this.internalChecked(\''+name+'\', \''+error+'\', event, eventType);';this.setValidator(name,'required',vFunction,error);}else{this.validateRegEx('[^\S]',name,error);}},minLength:function(name,minLength,error){if(!error){error='This field must contain at least '+minLength+' characters.';}var vFunction="this.internalLength('"+name+"', '"+error+"', 'minLength', "+minLength+");";this.setValidator(name,'minLength',vFunction,error);},maxLength:function(name,maxLength,error){if(!error){error='This field may contain no more than '+maxLength+' characters.';}var vFunction="this.internalLength('"+name+"', '"+error+"', 'maxLength', "+maxLength+");";this.setValidator(name,'maxLength',vFunction,error);},range:function(name,minLength,maxLength,error){if(!error){error='This field must contain at least '+minLength+' and no more than '+maxLength+' characters.';}var vFunction="this.internalLength('"+name+"', '"+error+"', 'range', "+minLength+", "+maxLength+");";this.setValidator(name,'range',vFunction,error);},matches:function(name,compareName,error){if(!error){error='This field does not match the '+compareName+' field.';}var vFunction="this.internalCompare('"+name+"', '"+compareName+"', '"+error+"', 'matches');";this.setValidator(name,'matches',vFunction,error);},noMatches:function(name,compareName,error){if(!error){error='This field cannot match the '+compareName+' field.';}var vFunction="this.internalCompare('"+name+"', '"+compareName+"', '"+error+"', 'noMatches');";this.setValidator(name,'noMatches',vFunction,error);},includes:function(name,arrayCheck,error){if(!error){error="This field did not contain any of the following values: "+arrayCheck.join(', ')+".";}var vFunction="this.internalArray('"+name+"', '"+error+"', 'includes', ['"+arrayCheck.join("', '")+"']);";this.setValidator(name,'includes',vFunction,error);},excludes:function(name,arrayCheck,error){if(!error){error="This field cannot contain any of the following values: "+arrayCheck.join(', ')+".";}var vFunction="this.internalArray('"+name+"', '"+error+"', 'excludes', ['"+arrayCheck.join("', '")+"']);";this.setValidator(name,'excludes',vFunction,error);},addFunction:function(name,customFunction){this.setValidator(name,customFunction,customFunction);},alpha:function(name,error){if(!error){error="This field may contain only letters.";}this.validateRegEx('^[a-zA-Z]+$',name,error);},numeric:function(name,error){if(!error){error="This field may contain only numbers.";}this.validateRegEx('^[0-9]+$',name,error);},alphanumeric:function(name,error){if(!error){error="This field may contain only letters or numbers.";}this.validateRegEx('^[a-zA-Z0-9]+$',name,error);},email:function(name,error){if(!error){error="Please enter a valid email address.";}this.validateRegEx('^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$',name,error);},url:function(name,error){if(!error){error="Please enter a valid URL.";}this.validateRegEx('^((http|https|ftp)://)?([[:alnum:]\-\.])+(\.)([[:alnum:]]){2,4}([[:alnum:]/+=%&_\.~?\-]*)$',name,error);},password:function(name,error){if(!error){error="Your password must contain one lowercase letter, one uppercase letter, one number, and be at least 6 characters long.";}this.validateRegEx("(?=^.{6,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*",name,error);},usZip:function(name,error){if(!error){error="Please enter a valid US ZIP Code.";}this.validateRegEx('^[0-9]{5}(?:-[0-9]{4})?$',name,error);},canadaPostal:function(name,error){if(!error){error="Please enter a valid Canadian Postal Code.";}this.validateRegEx('^[ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9]$',name,error);},credit:function(name,error){if(!error){error="Please enter a valid credit card number.";}this.validateRegEx('^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$',name,error);},dateMDY:function(name,error){if(!error){error="Please enter a valid date in M/D/Y format.";}this.validateRegEx('^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$',name,error);},dateYMD:function(name,error){if(!error){error="Please enter a valid date in Y/M/D format.";}this.validateRegEx('^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$',name,error);},swearFilter:function(name,error){if(!error){error="Please refrain from using profanity.";}this.excludes(name,[' fuck ',' fuk ',' fuc ',' shit ',' bitch ',' cunt ',' damn ',' damm '],error);},imageFile:function(name,error){if(!error){error="Please upload a valid image file. Valid files end with one of the following extensions: .jpg, .jpeg, .bmp, .gif, .png.";}this.validateRegEx('\.jpg|jpeg|bmp|gif|png$',name,error);},phone:function(name,error){if(!error){error="Please enter a valid phone number including area code.";}this.validateRegEx('^(([0-9]{1})*[- .(]*([0-9]{3})[- .)]*[0-9]{3}[- .]*[0-9]{4})+$',name,error);}});