var FormValidator={_attrs:["format","maxlength","minlength"],_alert:null,_inited:false,onValidate:[],DataType:{format:"",maxlength:10000,minlength:0,_errorMsgs:{maxvalue:"",minvalue:"",pattern:"Введенные данные не соответствуют формату",date:"Введенные данные не являются датой",formatDate:"Введенная дата не соответствуют формату",nan:'Введенные данные не являются числом',email:"Введенные данные не является E-mail адресом."},applyArgs:function(args){Object.extend(this,args)},checkEmpty:function(){if((this.value+"").replace(/^\s*|\s*$/gim,"").length<1)throw new Error('Введите данные');},checkFormat:function(){if(this.value.length>this.maxlength)throw new Error('Не более '+this.maxlength+" символов");if(this.value.length<this.minlength)throw new Error('Не менее '+this.minlength+" символов");if(this.format.length>0)this.checkPattern()},checkPattern:function(){var reg=new RegExp(this.format);if(!reg.test(this.value))throw new Error(this._errorMsgs.format);}},DataTypes:{_enum:["num","email","phone","string","date"],num:function(objArgs){this.applyArgs(objArgs);this.validate=function(){this.checkEmpty();this.checkNum();this.checkFormat()};this.checkNum=function(){if(isNaN(this.value)){throw new Error(this._errorMsgs.nan);}}},email:function(objArgs){this.applyArgs(objArgs);this.validate=function(){this.checkEmpty();this.format="^([\\w\\d_\\.\\-\\+])+\\@(([\\w\\d\\-])+\\.)+([\\w\\d]{2,4})+$";this._errorMsgs.pattern=this._errorMsgs.email;this.checkFormat()}},date:function(objArgs){this.patterns={"hh":"([0-1]\\d)|(2[0-3])","mm":"([0-5]\\d)","ss":"([0-5]\\d)","dd":"([0-2]\\d)|(3[0-1])","m":"(0[1-9])|(1[0-2])","yyyy":"\\d{4}"},this.applyArgs(objArgs);this.validate=function(){this.checkEmpty();this.checkFormat()};this.checkFormat=function(){if(this.format.length<1){if(isNaN(Date.parse(this.value))){throw new Error(this._errorMsgs.date);}return}var ptrn=this.format.replace("{","\\{").replace("}","\\}").replace("+","\\+").replace(".","\\.").replace("(","\\(").replace(")","\\)").replace("-","\\-").replace("[","\\[").replace("]","\\]").replace(",","\\,");for(var type in this.patterns)ptrn=ptrn.replace(type,"("+this.patterns[type]+")");var reg=new RegExp("^"+ptrn+"$");if(!reg.test(this.value))throw new Error(this._errorMsgs.formatDate);}},phone:function(objArgs){this.applyArgs(objArgs);this.validate=function(){this.checkEmpty()}},string:function(objArgs){this.applyArgs(objArgs);this.validate=function(){this.checkEmpty();this.checkFormat()}}},init:function(){if(this._inited)return;for(var type=0,l=this.DataTypes._enum.length;type<l;type++){this.DataTypes[this.DataTypes._enum[type]].prototype=FormValidator.DataType}var aBody=document.body;this._alert=$(aBody.insertBefore(document.createElement("div"),aBody.firstChild));this._alert.hide();Event.observe(aBody,"keydown",this.cancelAlert.bind(this));this._inited=true},check:function(objForm){this.init();var fields=$(objForm).getElements();for(var i=0,l=fields.length;i<l;i++){try{fields[i].style.borderColor="";fields[i].style.borderStyle="";this.validateField(fields[i])}catch(e){this.alert(e.message||e.Message,fields[i]);return false}}var additonal=null;if(this.onValidate.length>0){for(var i=0;i<this.onValidate.length;i++){try{this.onValidate[i].validator()}catch(e){this.alert(e.message||e.Message,this.onValidate[i].field);return false}}}return true},validateField:function(objField){if(!objField.readAttribute("required")||!this.checkFieldVisible(objField))return true;var val=objField.getValue();var type=objField.readAttribute("datatype")||"string";if(!type)return true;var args={value:val};for(var i=0,l=this._attrs.length;i<l;i++){var attr=objField.readAttribute(this._attrs[i]);if(attr)args[this._attrs[i]]=attr}if(!this.DataTypes[type])return false;type=new this.DataTypes[type](args);return type.validate()},checkFieldVisible:function(elt){var node=elt;while(node!=document.body.parentNode){if(!$(node).visible())return false;node=node.parentNode}return true},alert:function(text,field){field=$(field);field.focus();field.style.borderColor="red";field.style.borderStyle="solid";this._alert.show();this._alert.style.zIndex='50';this._alert.absolutize();this._alert.clonePosition(field,{setLeft:true,setTop:true,setWidth:false,setHeight:false,offsetLeft:(field.clientWidth||field.offsetWidth),offsetTop:((field.clientHeight||field.offsetHeight)/2)-30});this._alert.update((['<div class="alert_left"><div class="alert_right"><div class="alert_center">',text,'&nbsp;</div></div></div>']).join(""));this._alert.setStyle({width:"auto",height:60})},cancelAlert:function(){this._alert.hide()}};