Created
December 11, 2008 14:05
-
-
Save lokamaya/34716 to your computer and use it in GitHub Desktop.
inspectForm: unobtrusive form validation
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
/**================================================ | |
* InspectForm version 1.0 (for Prototype version 1.6 and above) | |
* Created: 11 December 2008 | |
* Created by: Zaenal - http://www.lokamaya.net | |
* ================================================ | |
* Copyright (c) 2008 Zaenal - http://www.lokamaya.net | |
* Some rights reserved. This work is licensed under a Creative Commons Attribution-Noncommercial 3.0 Unported License. | |
* ================================================ | |
* Demo: http://code.lokamaya.net/inpectform/ | |
* Blog: http://blog.lokamaya.net | |
* ================================================ | |
**/ | |
var inspectForm = Class.create({ | |
forms:null, | |
successElem: null, | |
formsButton: $A(), | |
error:false, | |
errorText:{}, | |
hashElement: new Hash(), | |
inspectMethod: {}, | |
initialize: function(forms, successElem) { | |
var that = this; | |
this.forms = $(forms); | |
if (successElem) | |
this.successElem = $(successElem); | |
if (this.successElem) | |
(this.successElem).hide(); | |
this.forms.observe('submit', function(evt) { | |
that.inspect(evt); | |
}); | |
this.resetObj = that.resetElement.bindAsEventListener(that); | |
this.inspectMethod = inspectMethod; | |
this.inspectMethod.field = {}; | |
this.inspectMethod.fieldAlternate = []; | |
this.inspectMethod.trim = this.trim; | |
this.inspectMethod.empty = this.empty; | |
}, | |
register: function(elem, param) { | |
var that = this; | |
var found = true; | |
if (!($(elem))) { | |
if (this.forms[elem]) { | |
if ($(this.forms[elem]).id) { | |
elem = $(this.forms[elem]).id; | |
} else if (this.forms[elem].name) { | |
$(this.forms[elem]).id = elem; | |
} else { | |
found = false; | |
} | |
} | |
if (!found) { | |
return alert('Element "'+elem+'" not found'); | |
} | |
} | |
this.hashElement.set(elem,param); | |
$(elem).observe('change', that.resetObj); | |
}, | |
registerMethod: function(method, callback) { | |
this.inspectMethod[method] = callback; | |
}, | |
registerResetButton: function(elem) { | |
var that = this; | |
$(elem).observe('click', function(evt) { | |
that.error = false; | |
if (that.successElem) { | |
(that.successElem).update(''); | |
(that.successElem).hide(); | |
} | |
that.forms.reset(); | |
that.errorCallbackResetAll(); | |
Event.stop(evt); | |
}); | |
}, | |
inspect: function(evt) { | |
var that = this; | |
this.error = false; | |
this.errorCallbackResetAll(); | |
this.hashElement.each(function(elem){ | |
that.inspectElement(elem); | |
}); | |
if (this.error) { | |
this.forms.submit = false; | |
Event.stop(evt); | |
return false; | |
} else { | |
this.submit(); | |
Event.stop(evt); | |
return true; | |
} | |
}, | |
inspectElement: function(elem) { | |
if (!($(elem.key).visible()) || $(elem.key).type=='hidden') return; | |
var that = this; | |
var valid = true; | |
var param = false; | |
var field = {}; field.id = elem.key; field.value = this.getValue(elem.key); | |
this.inspectMethod.field = field; | |
this.inspectMethod.errorText = null; | |
$H(elem.value).each(function(item){ | |
this.inspectMethod.fieldAlternate = []; | |
if (valid) { | |
if (that.is_array(item.value)) param = item.value[0]; | |
else param = item.value; | |
try {that.inspectMethod[item.key](param);}catch(e){alert(elem.key+': method "'+item.key+'" does not exist'); return;} | |
if (that.inspectMethod.errorText!==null) { | |
valid = false; | |
if (that.is_array(item.value) && item.value[1]) | |
that.inspectMethod.errorText = item.value[1]; | |
if (that.is_array(that.inspectMethod.fieldAlternate) && (that.inspectMethod.fieldAlternate).length > 0) { | |
$(elem.key).addClassName('dependElementTo'+this.inspectMethod.field.id); | |
$(elem.key).addClassName('dependElement'); | |
that.errorCallback(elem.key, that.inspectMethod.errorText, (that.error == false)); | |
$A(that.inspectMethod.fieldAlternate).each(function(alternate) { | |
$(alternate).stopObserving('change', that.resetObj); | |
$(alternate).observe('change', that.resetObj); | |
$(alternate).addClassName('dependElementTo'+that.inspectMethod.field.id); | |
$(alternate).addClassName('dependElement'); | |
that.errorCallback(alternate, false); | |
}); | |
} else { | |
that.errorCallback(elem.key, that.inspectMethod.errorText, false); | |
} | |
that.error = true; | |
throw $break; | |
} | |
} | |
}); | |
}, | |
successCallback: function(msg, error) { | |
if (this.successElem) { | |
(this.successElem).update(msg); | |
var that = this; | |
$A((this.successElem).select('[href="#back"]')).each(function(item) { | |
that.registerResetButton(item); | |
}); | |
(this.successElem).show(); | |
} else { | |
alert(msg); | |
} | |
if (!error) (this.forms).addClassName("successForm"); | |
}, | |
resetElement: function(event) { | |
var cleanup = Event.element(event); | |
if ($(cleanup).hasClassName('dependElement')) { | |
var that = this; | |
$(cleanup).readAttribute('class').scan("[a-zA-Z0-9\\-_]+", function(cls) { | |
if ((cls+'').startsWith('dependElementTo')) { | |
$A((that.forms).select('*.'+cls)).each(function(cleanup) { | |
if (cleanup.hasClassName(cls+'')) { | |
cleanup.removeClassName('dependElement'); | |
cleanup.removeClassName(cls+''); | |
that.errorCallbackReset(cleanup); | |
} | |
}); | |
return; | |
} | |
}); | |
} else { | |
this.errorCallbackReset(cleanup); | |
} | |
}, | |
errorCallback: function(elem, msg, focused) { | |
var that = this; | |
$(elem).addClassName('errorElement'); | |
if (msg) $(elem).up().appendChild(new Element('label', {'for':'error-'+elem, 'class':'errorLabel'}).update(msg)); | |
if (focused===true) $(elem).focus(); | |
}, | |
errorCallbackReset: function(elem) { | |
//alert($(elem).id); | |
$(elem).removeClassName('errorElement'); | |
if ($(elem).up().down('label.errorLabel')) { | |
$(elem).up().down('label.errorLabel').remove(); | |
} | |
}, | |
errorCallbackResetAll: function() { | |
var that = this; | |
this.forms.getElements().each(function(elem) { | |
that.errorCallbackReset(elem); | |
}); | |
(this.forms).removeClassName("successForm"); | |
if (this.successElem) { | |
(this.successElem).update(''); | |
(this.successElem).hide(); | |
} | |
}, | |
submit: function() { | |
var that = this; | |
(this.forms).request({ | |
onSuccess: function(transport) { | |
var docRoot = null; | |
var fields = []; | |
var error = false; | |
try {docRoot = transport.responseXML.documentElement;} catch(e){alert(e); return;}; | |
try {fields = (docRoot.getElementsByTagName('messageError')[0]).getElementsByTagName('fields');} catch(e){fields=[]} | |
$A(fields).each(function(field, i) { | |
that.errorCallback(field.getAttribute('id'), that.getNodeValue(field), (i==0)); | |
error = true; | |
}); | |
if (docRoot.getElementsByTagName('message')) { | |
that.successCallback(that.getNodeValue(docRoot.getElementsByTagName('message')[0]), error); | |
} | |
}, | |
onFailure: function() { | |
alert('Server down, please try to submit this form later!'); | |
} | |
}); | |
}, | |
getNodeValue: function (oNode) { | |
if (oNode.nodeValue) | |
return oNode.nodeValue; | |
else if (oNode.firstChild) | |
return this.getNodeValue(oNode.firstChild); | |
else | |
return ''; | |
}, | |
is_array: function(mixed_var) { | |
if (!mixed_var || mixed_var === null || mixed_var === false || mixed_var === true) return false; | |
return (mixed_var.constructor.toString().indexOf("Array") != -1 || mixed_var instanceof Array || mixed_var instanceof Object); | |
}, | |
getValue: function(elem) { | |
return $(elem).getValue(); | |
}, | |
trim: function(str) { | |
return str.strip(); | |
}, | |
empty: function() { | |
return ((this.trim(this.field.value)).length == 0); | |
} | |
}); | |
var inspectMethod = { | |
field: {id:null,value:''}, | |
fieldAlternate: [], | |
errorText: null, | |
required: function(param){ | |
if (this.empty()) { | |
this.errorText = 'Required field'; | |
} | |
return (this.errorText == null); | |
}, | |
confirm: function(param) { | |
if(this.field.value != Form.Element.getValue(param)) { | |
this.errorText = 'Confirm value not macth'; | |
this.fieldAlternate = [param]; | |
} | |
return (this.errorText == null); | |
}, | |
alternate: function(param) { | |
if((this.field.value).length==0) { | |
var found = false; | |
$A(param.split('|')).each(function(item) { | |
if (($(item).getValue()).length > 0) { | |
if (!found) found = true; | |
} | |
}); | |
if (!found) { | |
this.errorText = 'One of these fields must not empty'; | |
this.fieldAlternate = param.split('|'); | |
} | |
}; | |
return (this.errorText == null); | |
}, | |
radio: function(param) { | |
if($(this.field.id).checked==false) { | |
var found = false; | |
$A(param.split('|')).each(function(item) { | |
if ($(item).checked==true) { | |
if (!found) found = true; | |
} | |
}); | |
if (!found) { | |
this.errorText = 'One of these fields must be checked'; | |
this.fieldAlternate = param.split('|'); | |
} | |
}; | |
return (this.errorText == null); | |
}, | |
checkbox: function(param) { | |
if ($(this.field.id).checked==false) { | |
this.errorText = 'Must be checked'; | |
} | |
return (this.errorText == null); | |
}, | |
not: function(param) { | |
if (this.field.value==param) { | |
this.errorText = 'Value "'+param+'" is not allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
maxlength: function(param) { | |
if (this.empty()) return; | |
if (parseInt(param) > 0 && this.field.value.length > parseInt(param)) { | |
this.errorText = 'Maximum ' + parseInt(param) + ' characters'; | |
} | |
return (this.errorText == null); | |
}, | |
minlength: function(param) { | |
if (this.empty() || (parseInt(param) > 0 && this.field.value.length < parseInt(param))){ | |
this.errorText = 'Minimum ' + parseInt(param) + ' characters'; | |
} | |
return (this.errorText == null); | |
}, | |
decimal: function(param) { | |
if (this.empty()) return; | |
if((this.field.value).search("[^0-9\.,]") > 0 || (this.field.value).search("^(\.|,)")) { | |
this.errorText = 'Only decimal allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
numeric: function(param) { | |
if (this.empty()) return; | |
if(!this.strsrc("[^0-9]")) { | |
this.errorText = 'Only integer number allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
alphabet: function(param) { | |
if (this.empty()) return; | |
if(!this.strsrc("[^A-Za-z]")) { | |
this.errorText = 'Only alphabet characters are allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
alphanumeric: function(param) { | |
if (this.empty()) return; | |
if(!this.strsrc("[^A-Za-z0-9]")) { | |
this.errorText = 'Only alphabet and number characters are allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
lessthan: function(param) { | |
if (this.empty()) return; | |
if (isNaN(this.field.value)){ | |
this.errorText = 'Only number allowed'; | |
} else if (parseFloat(this.field.value) > parseFloat(param)){ | |
this.errorText = 'Value greater than ' + parseFloat(param); | |
} | |
return (this.errorText == null); | |
}, | |
greaterthan: function(param) { | |
if (this.empty()) return; | |
if (isNaN(this.field.value)){ | |
this.errorText = 'Only number allowed'; | |
} else if (parseFloat(this.field.value) < parseFloat(param)) { | |
this.errorText = 'Value less than ' + parseFloat(param); | |
} | |
return (this.errorText == null); | |
}, | |
email: function(param) { | |
if (this.empty()) return; | |
if(!(new RegExp("^([\\w-]+(?:\\.[\\w-]+)*)@((?:[\\w-]+\\.)*\\w[\\w-]{0,66})\\.([a-z]{2,6}(?:\\.[a-z]{2})?)$", "i")).test(this.trim(this.field.value))) { | |
this.errorText = 'Not valid email address'; | |
} | |
return (this.errorText == null); | |
}, | |
website: function(param) { | |
if (this.empty()) return; | |
if(!(new RegExp("^(?:https?):\\/\\/(?:(?:[\\w]+:)?\\w+@)?(?:(?:(?:[\\w-]+\\.)*\\w[\\w-]{0,66}\\.(?:[a-z]{2,6})(?:\\.[a-z]{2})?)|(?:(?:25[0-5]\\.|2[0-4][0-9]\\.|1[0-9]{2}\\.|[0-9]{1,2}\\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})))(?:\\:\\d{1,5})?(?:\\/(~[\\w-_.])?)?(?:(?:\\/[\\w-_]*)*)?$", "i")).test(this.trim(this.field.value))) { | |
this.errorText = 'Not valid website'; | |
} | |
return (this.errorText == null); | |
}, | |
url: function(param) { | |
if (this.empty()) return; | |
if(!(new RegExp("^(?:https?):\\/\\/(?:(?:[\\w]+:)?\\w+@)?(?:(?:(?:[\\w-]+\\.)*\\w[\\w-]{0,66}\\.(?:[a-z]{2,6})(?:\\.[a-z]{2})?)|(?:(?:25[0-5]\\.|2[0-4][0-9]\\.|1[0-9]{2}\\.|[0-9]{1,2}\\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})))(?:\\:\\d{1,5})?(?:\\/(~[\\w-_.])?)?(?:(?:\\/[\\w-_.#]*)*)?(\\?)?(?:(?:[\\w-_.#]+\\=[\\w-_.#]+&?)*)?$", "i")).test(this.trim(this.field.value))) { | |
this.errorText = 'Not valid url address'; | |
} | |
return (this.errorText == null); | |
}, | |
file: function(param) { | |
if (this.empty() || !param) return; | |
if (!(new RegExp("\.("+param+")$", "i")).test(this.field.value)) { | |
this.errorText = 'File extension not allowed'; | |
} | |
return (this.errorText == null); | |
}, | |
date: function(param) { | |
if (this.empty()) return; | |
param = param.toLowerCase(); | |
var oRegex = ((((((param.replace(new RegExp('\\W+', "gi"), "##")).replace('dd', "(0[1-9]|1[0-9]|2[0-9]|3[0-1])")).replace('d', "([1-9]|1[0-9]|2[0-9]|3[0-1])")).replace('mm', "(0[1-9]|1[0-2])")).replace('m', "([1-9]|1[0-2])")).replace('yyyy', "([0-9]{4})")).replace('yy', "([0-9]{2})"); | |
var oValue = (this.field.value).replace(new RegExp('\\W+', "gi"), "##"); | |
if (!(new RegExp("^"+oRegex+"$")).match(oValue)) { | |
this.errorText = 'Invalid date format'; | |
} | |
return (this.errorText == null); | |
}, | |
regexp: function(param) { | |
if (this.empty()) return; | |
if(!(param).test(this.field.value)) { | |
this.errorText = 'Error regex'; | |
} | |
return (this.errorText == null); | |
}, | |
strsrc: function(param) { | |
if (this.empty()) return; | |
if((this.field.value).search(param) > 0) { | |
this.errorText = 'Error: characters found'; | |
} | |
return (this.errorText == null); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment