Created
October 8, 2013 20:11
-
-
Save jedfoster/6890830 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/** | |
* ValidatedFields | |
* ------------------- | |
* | |
* | |
*/ | |
function ValidatedFields(errorCallback, successCallback) { | |
// var ValidatedFields = function(errorCallback, successCallback) { | |
this.errorCallback = errorCallback || function() {}; | |
this.successCallback = successCallback || function() {}; | |
/** | |
* Event handler called when a form field loses focus (onblur). | |
*/ | |
this.validate = function(event) { | |
var input = event.element(); // form field | |
return this.validateInput(input, this.successCallback); | |
}; | |
this.validateInput = function(input, callback) { | |
var errors = this.getErrorMessages(input); // error messages in data-error attrs | |
var valid = true; | |
var validators = new Array; | |
validators = $w($(input).readAttribute('data-validates')); | |
if (!validators) { | |
valid = false; | |
} | |
if($(input).hasAttribute('required')) { | |
validators.push('required'); | |
} | |
if($(input).readAttribute('type') === 'email') { | |
validators.push('email'); | |
} | |
if($(input).hasAttribute('pattern')) { | |
validators.push('format'); | |
} | |
for (var i = 0; i < validators.length; i++) { | |
var v = validators[i]; | |
if(v.match(/\:/)) { | |
v = v.split(':'); | |
var arg = v[1]; | |
// generate validator method name | |
var validator = 'validate' + v[0].capitalize(); | |
valid = valid && this[validator]($(input), errors, arg); | |
} | |
else { | |
// generate validator method name | |
var validator = 'validate' + v.capitalize(); | |
valid = valid && this[validator]($(input), errors); | |
} | |
} | |
// alert(valid); | |
if (valid) { | |
if(callback) | |
this.successCallback($(input)); | |
return true; | |
} | |
else { | |
return false; | |
} | |
}; | |
this.validateFormSubmission = function(event) { | |
var form = event.element(); | |
var self = this; | |
var inputs = form.getElements(); | |
var validForm = true; | |
for (var i = 0; i < inputs.length; i++) { | |
if(!this.validateInput(inputs[i])) | |
validForm = false; | |
} | |
if(!validForm) | |
event.stop(); | |
return; | |
}; | |
/** | |
* Finds all attributes of element that begin with 'data-error-' | |
* and extracts them to an array. | |
*/ | |
this.getErrorMessages = function(element) { | |
var errors = []; | |
for (var i = 0; i < element.attributes.length; i++) { | |
var attr = element.attributes[i]; | |
var match = attr.nodeName.match(/^data-error-(.*)$/); | |
if (match) { | |
errors[match[1]] = attr.nodeValue; | |
} | |
} | |
return errors; | |
}; | |
this.validateRequired = function(element, errors) { | |
var value = $F(element).strip(); | |
if (value === "") { | |
this.errorCallback(element, errors['required']); | |
return false; | |
} | |
return true; | |
}; | |
this.validateFormat = function(element, errors) { | |
var value = $F(element).strip(); | |
var allowBlank = element.hasAttribute('data-allow-blank'); | |
if (value === "" && allowBlank) { | |
return true; | |
} | |
var p = element.readAttribute('pattern'); | |
// it's also possible to do "re = eval(p)", but might be dangerous | |
var re = new RegExp(p.slice(p.indexOf('/')+1, p.lastIndexOf('/')), p.slice(p.lastIndexOf('/')+1)); | |
var res = re.test(value); | |
if (!res) { | |
this.errorCallback(element, errors['format']); | |
} | |
return res; | |
}; | |
this.validateLength = function(element, errors) { | |
var value = $F(element).strip(); | |
var min = parseInt(element.readAttribute('min')); // the browser will take care of maxlength | |
var allowBlank = element.hasAttribute('data-allow-blank'); | |
if (value === "" && allowBlank) { | |
return true; | |
} | |
if (value.length < min) { | |
var msgKey = 'too-short' in errors ? 'too-short' : 'invalid-length'; | |
this.errorCallback(element, errors[msgKey]); | |
return false; | |
} | |
return true; | |
}; | |
this.validateEmail = function(element, errors) { | |
var value = $F(element).strip(); | |
var allowBlank = element.hasAttribute('data-allow-blank'); | |
if (value === "" && allowBlank) { | |
return true; | |
} | |
var res = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.test(value); | |
if (!res) { | |
this.errorCallback(element, errors['email']); | |
} | |
return res; | |
}; | |
this.validateMatches = function(element, errors, matchField) { | |
var value = $F(element).strip(); | |
// var matchField = element.readAttribute('data-validate-matches'); | |
if ($F(element) !== $F(matchField)) { | |
this.errorCallback(element, errors["matches"]); | |
return false; | |
} | |
return true; | |
}; | |
// -------------------------------------------------------- | |
// set up events for all elements with the 'validated' class | |
$$('*[required],input[type="email"],*[pattern],*[data-validates]').invoke('observe', 'blur', this.validate.bind(this)); | |
$$('form').invoke('observe', 'submit', this.validateFormSubmission.bind(this)); | |
}; | |
document.observe('dom:loaded', function() { | |
// var valid = new ValidatedFields( | |
new ValidatedFields( | |
// function called when validation fails | |
function(element, errorMsg) { | |
element.setStyle({'border': '1px red solid'}); | |
element.next('span.error').update(errorMsg); // show error message | |
}, | |
// function called when validation succeeds | |
function(element) { | |
element.setStyle({'border': '1px green solid'}); | |
element.next('span.error').update(''); // clear error message | |
} | |
); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment