Skip to content

Instantly share code, notes, and snippets.

@jedfoster
Created October 8, 2013 20:14
Show Gist options
  • Save jedfoster/6890869 to your computer and use it in GitHub Desktop.
Save jedfoster/6890869 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<script src="/js/prototype.js"></script>
<script src="/js/scriptaculous.js"></script>
<script src="validation.js"></script>
</head>
<body>
<h1>Really Easy Field validation with Prototype</h1>
<form id="test" action="#" method="get">
<fieldset>
<legend>Form</legend>
<p><input type="email" data-validate-required="This field is required" data-validate-email="This field must be an email address" data-validate-blahblah>
<p><label for="field1">Name:</label><br>
<input name="field1" id="field1" data-validate-required="This field is required"></p>
<div><label for="field8">Password:</label></div>
<div><input type="password" name="field8" id="field8" data-validate-required data-validate-password="Enter a password greater than 6 characters"></div>
<div><label for="field9">Confirm Password:</label></div>
<div><input type="password" name="field9" id="field9" data-validate-required data-validate-password-confirm="Enter the same password for confirmation"></div>
</fieldset>
<input type="submit" value="Submit">
<input type="button" value="Reset" onclick="valid.reset(); return false">
</form>
<script>
var valid = new Validation('test', {onBlur : true});
// valid.addAllThese([
// ['required', '&larr; REQUIRED.', function(v) {
// return !valid.get('IsEmpty').test(v);
//
// }],
// valid.add('IsEmpty', '', function(v) {
// return ((v == null) || (v.length == 0)); // || /^\s+$/.test(v));
// });
// valid.add('required','&rarr; Required!!', {notEmpty:1});
// valid.addRules([
// // ['required', '&larr; REQUIRED.', function(v) {
// // return !valid.get('IsEmpty').test(v);
// //
// // }],
// ['required', '&larr; REQUIRED.', {notEmpty:1}],
// ['email', 'Please enter a valid email address. For example [email protected] .', function (v) {
// return /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
// }],
// ['password', 'Your password must be more than 6 characters and not be \'password\' or the same as your name', {
// minLength : 7,
// notOneOf : ['password','PASSWORD','1234567','0123456'],
// notEqualToField : 'field1'
// }],
// ['password-confirm', 'Your confirmation password does not match your first password, please try again.', {
// equalToField : 'field8'
// }]
// ]);
</script>
</body>
</html>
/*
* Really easy field validation with Prototype
* http://tetlaw.id.au/view/javascript/really-easy-field-validation
* Andrew Tetlaw
* Version 1.5.4.1 (2007-01-05)
*
* Copyright (c) 2007 Andrew Tetlaw
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
var Validator = Class.create();
Validator.prototype = {
initialize: function(validation, className, error, test, options) {
this.validation = validation;
if(typeof test == 'function'){
this.options = $H(options);
this._test = test;
} else {
this.options = $H(test);
this._test = function(){return true};
}
this.error = error || 'Validation failed.';
this.className = className;
},
test: function(v, e) {
self = this;
return (this._test(v,e) && this.options.all(function(p){
return self[p.key] ? self[p.key](v,e,p.value) : true;
}));
},
notEmpty: function(v,e,opt) {return !v.empty();},
pattern: function(v,e,opt) {return this.notEmpty(v,e,opt) || opt.test(v)},
minLength: function(v,e,opt) {return v.length >= opt},
maxLength: function(v,e,opt) {return v.length <= opt},
min: function(v,e,opt) {return v >= parseFloat(opt)},
max: function(v,e,opt) {return v <= parseFloat(opt)},
notOneOf: function(v,e,opt) {return $A(opt).all(function(value) {
return v != value;
})},
oneOf: function(v,e,opt) {return $A(opt).any(function(value) {
return v == value;
})},
is: function(v,e,opt) {return v == opt},
isNot: function(v,e,opt) {return v != opt},
equalToField: function(v,e,opt) {return v == $F(opt)},
notEqualToField: function(v,e,opt) {return v != $F(opt)},
include: function(v,e,opt) {return $A(opt).all(function(value) {
return this.validation.get(value).test(v,e);
})}
};
var Validation = Class.create();
Validation.prototype = {
initialize: function(form, options){
this.options = Object.extend({
onSubmit: true,
onBlur: false,
onFormValidate: function(result, form) {},
onElementValidate: function(result, e) {}
}, options || {});
this.form = $(form);
this.validators = {};
if(this.options.onSubmit) {this.form.observe('submit', this.onSubmit.bind(this),false);}
if(this.options.onBlur) {
var callback = this.options.onElementValidate;
var self = this;
this.form.getElements().each(function(input) {
input.observe('blur', function(event) {
self.validateInput(event.element(), {onElementValidate : callback});
});
});
}
},
elementRules: function(e) {
return $A(e.attributes).filter(function(attr){
return /^data-validate(.)*$/.test(attr.name);
});
},
onSubmit: function(event){
if(!this.validateForm()) {
event.stop();
}
},
validateForm: function() {
var result = false;
var callback = this.options.onElementValidate;
var self = this
result = this.form.getElements().collect(function(e) {
return self.validateInput(e, {onElementValidate : callback});
}).all();
this.options.onFormValidate(result, this.form);
return result;
},
validateInput: function(input, options){
var self = this;
var rules = this.elementRules(input);
return result = rules.all(function(rule) {
var test = self.test(rule.name.replace('data-validate-', ''), input);
options.onElementValidate(test, input);
return test;
});
},
reset: function() {
var self = this;
this.form.getElements().each(function(e) {
var rules = self.elementRules(e);
rules.each(function(rule) {
value = rule.name.replace('data-validate-', '');
var prop = '__warning'+value.camelize();
if(e[prop]) {
var warning = self.getWarning(value, e);
warning.hide();
e[prop] = '';
}
e.removeClassName('validation-failed');
e.removeClassName('validation-passed');
});
});
},
test: function(name, e, useTitle) {
var v = this.get(name);
var prop = '__warning'+name.camelize();
try {
if(this.isVisible(e) && !v.test($F(e), e)) {
if(!e[prop]) {
var warning = this.getWarning(name, e);
if(warning == null) {
var message = (e.readAttribute('data-validate-' + name)) ? e.readAttribute('data-validate-' + name) : v.error;
warning = '<span class="validation-warning" id="warning-' + name + '-' + this.geteID(e) +'" style="display:none">' + message + '</span>';
switch (e.type.toLowerCase()) {
case 'checkbox':
case 'radio':
var p = e.parentNode;
if(p) {
p.insert({'bottom': warning});
} else {
e.insert({'after': warning});
}
break;
default:
e.insert({'after': warning});
}
warning = this.getWarning(name, e);
}
new Effect.Appear(warning, {duration : 0.1 });
}
e[prop] = true;
e.removeClassName('validation-passed');
e.addClassName('validation-failed');
return false;
} else {
var warning = this.getWarning(name, e);
if(warning != null) warning.hide();
e[prop] = '';
e.removeClassName('validation-failed');
e.addClassName('validation-passed');
return true;
}
} catch(e) {
throw(e)
}
},
isVisible: function(e) {
while(e.tagName != 'BODY') {
if(!$(e).visible()) return false;
e = e.parentNode;
}
return true;
},
getWarning: function(name, e) {
return $('warning-' + name + '-' + this.geteID(e)) || $('warning-' + this.geteID(e));
},
geteID: function(e) {
return e.identify();
},
addRules: function(rules) {
var nv = {};
$A(rules).each(function(value) {
nv[value[0]] = new Validator(this, value[0], value[1], value[2], (value.length > 3 ? value[3] : {}));
});
Object.extend(this.validators, nv);
},
get: function(name) {
return this.validators[name] ? this.validators[name] : new Validator(this, '','',{});
}
};
// Object.extend(Validation,
// {
// initialize: function(form, options) {
// function() {
// this.initialize(form, options);
new Validation().addRules([
['required', '&larr; REQUIRED.', {notEmpty:1}],
['email', 'Please enter a valid email address. For example [email protected] .', function (v) {
return /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
}],
['password', 'Your password must be more than 6 characters and not be \'password\' or the same as your name', {
minLength : 7,
notOneOf : ['password','PASSWORD','1234567','0123456'],
notEqualToField : 'field1'
}],
['password-confirm', 'Your confirmation password does not match your first password, please try again.', {
equalToField : 'field8'
}]
]);
// }
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment