var FormValidator=function(obj,printErrorExternal)
{
this.FORM=null;
this.printErrorExternal=printErrorExternal;
this.LANG="rus";
this.NEEDSUBMIT=true;
this.RESULT=null;
this.TEMPLATE=null;
this.TARGET='alert';
this.ERRORS=[];
this.ERROR_TYPES=
{
EMPTY:0,
MAXLEN:1,
MINLEN:2,
INVALID:3,
ATLEAST:4,
INSET:5,
PWD:6,
BAD_DAY:7,
BAD_MONTH:8,
BAD_YEAR:9,
BETWEEN:10,
LESS:11,
MAXSIZE:12,
MINSIZE:13,
BEETWEENSIZE:14,
SIZE:15,
SIZENUMBER:16,
BETWEENSEL:17
};
this.ERROR_MSG_TEMPLATES={rus:null,eng:null};
this.ERROR_MSG_TEMPLATES.rus=
[
'Поле --fieldDesc-- не может быть пустым\n',
'Значение пол  --fieldDesc-- должно быть меньше --fieldLen--\n',
'Значение пол  --fieldDesc-- должно быть больше --fieldLen--\n',
'Поле --fieldDesc-- заполнено некорректно\n',
'Количество выбранных значений в разделе --fieldDesc-- должно быть больше --fieldLen--\n',
'Количество выбранных значений в разделе --fieldDesc-- должно быть --fieldLen--\n',
'Введенные пароли не совпадают, попробуйте еще раз\n',
'В поле --fieldDesc-- значение дн  установлено не верно\n',
'В поле --fieldDesc-- значение мес ца установлено не верно\n',
'В поле --fieldDesc-- значение года установлено не верно\n',
'Значение пол  --fieldDesc-- должно находитс  в пределах --fieldLen--\n',
'Количество выбранных значений в разделе --fieldDesc-- должно быть меньше --fieldLen--\n',
'Количество символов в поле --fieldDesc-- не может превышать --fieldLen--\n',
'Количество символов в поле --fieldDesc-- должно превышать --fieldLen--\n',
'Количество символов в поле --fieldDesc-- должно находитс  в пределах --fieldLen--\n',
'Количество символов в поле --fieldDesc-- должно быть ровно --fieldLen--\n',
'Значение пол  --fieldDesc-- должно быть --fieldLen--\n',
'Количество выбранных значений в разделе --fieldDesc-- должно находитс  в пределах --fieldLen--\n',
];
this.ERROR_MSG_TEMPLATES.eng=
[
'--fieldDesc-- cannot be empty\n',
'Value of --fieldDesc-- cannot be greater than --fieldLen--\n',
'Value of --fieldDesc-- cannot be greater than --fieldLen--\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- section must have at least --fieldLen-- value selected\n',
'--fieldDesc-- section must have 1 to --fieldLen-- values selected\n',
'The password and its confirmation are not identical\n',
'--fieldDesc-- contains incorrect day value\n',
'--fieldDesc-- contains incorrect month value\n',
'--fieldDesc-- contains incorrect year value\n',
'Value of --fieldDesc-- must be between --fieldLen-- letters\n',
'--fieldDesc-- section must have less than --fieldLen-- value selected\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- is invalid\n',
'--fieldDesc-- is invalid\n'
];
if(obj)
{
if(obj.nodeName&&obj.nodeName.toUpperCase()=='FORM')
{
this.FORM=obj;
}
else if(obj.form)
{
this.FORM=obj.form;
}
else if(typeof(obj)=="string"||typeof(obj)=="number")
{
this.FORM=document.forms[obj];
}
if(!this.FORM)
{
return false;
}
}
try
{
if(window.event)
{
window.event.returnValue=false;
}
else
{
this.FORM.onsubmit=function(e){return false;};
}
}
catch(e){}
this.processSettings('LANG');
this.processSettings('NEEDSUBMIT');
this.processSettings('RESULT');
this.processSettings('TARGET');
this.processSettings('TEMPLATE');
for(var i=0;i<this.FORM.elements.length;i++)
{
var elem=this.FORM.elements[i];
var attr=this.getAttributeByName(elem,'FORMAT');
if(attr)
{
this.validate(elem,new FormItemFormatParser(attr));
}
}
if(this.ERRORS.length>0)
{
if(this.RESULT||this.TARGET=='html')
{
this.clearPreviousErrrors();
this.printErrors();
}
else
{
alert(this.getMessage());
}
}
else if(this.NEEDSUBMIT)
{
this.FORM.submit();
}
}
FormValidator.prototype.clearPreviousErrrors=function()
{
for(var i=0;i<this.FORM.elements.length;i++)
{
var elem=this.FORM.elements[i];
var attr=this.getAttributeByName(elem,'FORMAT');
if(attr)
{
try
{
document.getElementById(elem.name+this.RESULT).innerHTML='';
}
catch(e){continue;}
}
}
};
FormValidator.prototype.getMessage=function()
{
var message='';
for(var i=0;i<this.ERRORS.length;i++)
{
message+=this.ERRORS[i].getMessage();
}
return message;
};
FormValidator.prototype.printErrors=function()
{
if(this.printErrorExternal)
{
this.printErrorExternal.call(this,this.ERRORS);
}
else
{
for(var i=0;i<this.ERRORS.length;i++)
{
var error=this.ERRORS[i];
error.print();
}
}
};
FormValidator.prototype.processSettings=function(name)
{
var attr=this.getAttributeByName(this.FORM,name);
if(attr)
{
this[name]=attr;
}
};
FormValidator.prototype.validate=function(element,format)
{
switch(element.type.toUpperCase())
{
case'RADIO':
if(countChecked.call(this)==0)
{
format.size=1;
setError.call(this,this.ERROR_TYPES.ATLEAST);
}
break;
case'PASSWORD':
var depend=this.getAttributeByName(element,'DEPEND');
if(depend&&!isEmpty())
{
var dependElem=this.FORM.elements[depend];
if(dependElem&&dependElem.value!=element.value)
{
setError.call(this,this.ERROR_TYPES.PWD);
}
}
else if(isEmpty())
{
setError.call(this,this.ERROR_TYPES.EMPTY);
}
else if(format.size)
{
var sizeError=checkSize(element.value);
if(sizeError>0)
{
setStringSizeError.call(this,sizeError);
}
}
break;
default:
if(format.required&&isEmpty())
{
setError.call(this,this.ERROR_TYPES.EMPTY);
break;
}
else if(format.type)
{
var check=checkType();
if(format.type=='date')
{
setDateSizeError.call(this,check);
break;
}
else if(!check)
{
setError.call(this,this.ERROR_TYPES.INVALID);
break;
}
}
var sizeError=checkSize.call(this,element.value);
if(sizeError>0)
{
if(element.nodeName=='SELECT'||element.type.toUpperCase()=='CHECKBOX')
{
setSizeError.call(this,sizeError);
}
else if(format.type=='number')
{
setNumberSizeError.call(this,sizeError);
}
else
{
setStringSizeError.call(this,sizeError);
}
}
break;
}
function setError(errorNumber)
{
var error=new FormError(element,this.ERROR_MSG_TEMPLATES[this.LANG][errorNumber],errorNumber,format,this.RESULT,this.TEMPLATE);
this.ERRORS.push(error);
}
function isEmpty()
{
return(!element.value.match(/.+/));
}
function checkType()
{
var value=element.value.toString();
if(isEmpty())return true;
var re='';
switch(format.type)
{
case'email':
re=/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
return value.match(re);
break;
case'phone':
re=/^(\\+\\d{1,3}\\x20?)?(\\d{3,4}\\x20?|\\(\\d{3,4}\\)\\x20?)?\\d{2,3}\\-?\\d\\d\\-?\\d\\d(\\s[\\d\\s\(\)]*)?$/;
return value.match(re);
break;
case'number':
re=/^[-]?\d*\.?\d*$/;
return value.match(re);
break;
case'int':
re=/^[-]?\d$/;
return value.match(re);
break;
case'date':
return isValidDate(value);
break;
}
return true;
}
function checkSize(value)
{
var compare=(format.type=='number')?parseInt(value):(''+value).length;
if(element.nodeName=='SELECT')
{
compare=countSelected();
}
else if(element.type.toUpperCase()=='CHECKBOX')
{
compare=countChecked.call(this);
if(typeof(format.size)=='undefined'&&compare==0)return 5;
}
if(typeof(format.size)=='undefined')return-1;
var beetwin=format.size.toString().split('-');
if(beetwin.length>1&&beetwin[0]!='')
{
var from=parseInt(beetwin[0]);
var to=parseInt(beetwin[1]);
if((from==to&&compare!=from)||((compare<=from||compare>=to)&&from!=to))
{
return(from==to)?4:3;
}
}
else if(format.size<0&&compare>=format.size*-1)
{
return 1;
}
else if(format.size>0&&compare<=format.size)
{
return 2;
}
return -1;
}
function setSizeError(errorNumber)
{
switch(errorNumber)
{
case 1:
setError.call(this,this.ERROR_TYPES.LESS);
break;
case 2:
setError.call(this,this.ERROR_TYPES.ATLEAST);
break;
case 3:
setError.call(this,this.ERROR_TYPES.BETWEENSEL);
break;
case 4:
setError.call(this,this.ERROR_TYPES.INSET);
break;
case 5:
setError.call(this,this.ERROR_TYPES.EMPTY);
break;
}
}
function setNumberSizeError(errorNumber)
{
switch(errorNumber)
{
case 1:
setError.call(this,this.ERROR_TYPES.MAXLEN);
break;
case 2:
setError.call(this,this.ERROR_TYPES.MINLEN);
break;
case 3:
setError.call(this,this.ERROR_TYPES.BETWEEN);
break;
case 4:
setError.call(this,this.ERROR_TYPES.SIZENUMBER);
break;
}
}
function setStringSizeError(errorNumber)
{
switch(errorNumber)
{
case 1:
setError.call(this,this.ERROR_TYPES.MAXSIZE);
break;
case 2:
setError.call(this,this.ERROR_TYPES.MINSIZE);
break;
case 3:
setError.call(this,this.ERROR_TYPES.BEETWEENSIZE);
break;
case 4:
setError.call(this,this.ERROR_TYPES.SIZE);
break;
}
}
function setDateSizeError(errorNumber)
{
switch(errorNumber)
{
case 1:
setError.call(this,this.ERROR_TYPES.INVALID);
break;
case 2:
setError.call(this,this.ERROR_TYPES.BAD_DAY);
break;
case 3:
setError.call(this,this.ERROR_TYPES.BAD_MONTH);
break;
case 4:
setError.call(this,this.ERROR_TYPES.BAD_YEAR);
break;
}
}
function countSelected()
{
var count=0;
for(var i=0;i<element.options.length;i++)
{
if(element.options[i].selected)count++;
}
return count;
}
function countChecked()
{
var count=0;
for(var i=0;i<this.FORM[element.name].length;i++)
{
if(this.FORM[element.name][i].checked)count++;
}
return count;
}
function comparePasswords()
{
var password='';
var password2='';
for(var i=0;i<this.FORM.elements.length;i++)
{
var elem=this.FORM.elements[i];
if(elem.name.toLowerCase().indexOf('password')!=-1)
{
password2=(password=='')?'':elem.value;
password=(password=='')?elem.value:password;
}
if(password2!=''&&password!='')
{
return(password2==password);
}
}
return true;
}
function isValidDate(str)
{
if(str.search(/[0-9]{2}(\.|\/|\-)[0-9]{2}(\.|\/|\-)[0-9]{4}/g)==-1)return 1;
var delim=str.substr(str.length-5).slice(0,-4);
var strArr=str.split(delim);
if(strArr.length!=3)
{
return 1;
}
var dd=strArr[0];
var mm=strArr[1];
var yy=strArr[2];
if(dd.substr(0,1)=='0')dd=dd.substr(1);
if(mm.substr(0,1)=='0')mm=mm.substr(1);
if(parseInt(dd)>31||parseInt(dd)<1)return 2;
else if(parseInt(mm)>12||parseInt(mm)<1)return 3;
else if(delim!='.'&&delim!='-'&&delim!='/')return 4;
var time=Date.parse(mm+'/'+dd+'/'+yy);
var etalonDate=new Date(time);
if(parseInt(dd)!=etalonDate.getDate())return 2;
else if(parseInt(mm)!=etalonDate.getMonth()+1)return 3;
else if(parseInt(yy)!=etalonDate.getFullYear()||parseInt(yy)>9999)return 4;
return 0;
}
};
FormValidator.prototype.getAttributeByName=function(elem,name)
{
name=name.toUpperCase();
try
{
var value=elem.getAttribute(name);
return((value)?value:null);
}
catch(e)
{
return null;
}
return null;
};
var FormItemFormatParser=function(str)
{
var values=str.split('::');
var format={type:'',name:'',required:false,size:''};
try
{
format.type=values[0];
format.name=values[1];
format.required=(values[2]=='opt')?false:true;
if(values[2]!='opt'&&values[2]!='req')
{
format.size=values[2];
}
else
{
format.size=values[3];
}
}
catch(e)
{
return format;
}
return format;
};
var FormError=function(element,msg,errorNumber,format,prefix,template)
{
this.field=element;
this.message=msg;
this.caption=format.name;
this.size=format.size;
this.type=errorNumber;
this.target=null;
this.prefix=prefix;
this.template=template;
};
FormError.prototype.getMessage=function()
{
var size=this.size;
if(this.type==1||this.type==12||this.type==11)
{
size*=-1;
}
if(this.type==15||this.type==16||this.type==5)
{
size=size.split('-')[0];
}
return this.message.replace('--fieldDesc--',this.caption).replace('--fieldLen--',size);
};
FormError.prototype.print=function()
{
this.target=document.getElementById(this.field.name+((this.prefix)?this.prefix:''));
if(!this.target)return;
if(this.template)
{
this.template=this.template.split('::');
if(this.template.length==3)
{
this.message=this.template[0].replace('text',this.message);
this.caption=this.template[1].replace('name',this.caption);
this.size=this.template[2].replace('size',this.size);
}
}
else
{
this.caption=this.caption.bold();
}
this.target.innerHTML=this.getMessage();
};