﻿/*JavaScript一表单检测类支持Ie和ff(不明白到http://hi.baidu.com/yanjinbin/blog留言)
*构造函数:
*Form是表单名,为兼容请把id属性也设置
*Mode是错误提示方法:1-直接alert提示2-只innerHTML写入
*
*--在表单元素中要设置属性
*DataType:要检测的类型 如DomUserName,DomEmail(可用逗号隔开检测多个)
*Max:是最大值，只有DataType=中时有用
*Mim:最小值，只有DataType=时有用
*AjaxUrl:是需要检测的连接地址，他会自动的把如..asp?Formname=Formvalue这样发送过去
*ErrMes:是错误提示
*RightMes:是正确提示
*AjaxErrMes:是DomAjax检测失败后的提示
*
*一写类属性(关联方法)说明
*this.Email 是邮箱正则 检测字符串this.CheckEmail 根据表单名检测:this.DomEmail
*this.UserName 是用户名正则  检测字符串this.CheckUserName 根据表单名检测:this.DomUserName
*this.UserPsd 是密码正则  检测字符this.CheckUserPsd 根据表单名检测:this.DomUserPsd
*              --重复密码检测是用this.DomAmount函数来检测上下来年个值是否相等
*              --但是有命名规则：如密码名:UserPsd重复密码就是命名为UserPsd+随意，但只准多加一位
*this.UserTrueName 是真实姓名正则 --this.CheckUserTrueName --this.DomUserTrueName
*this.Integer 整数  --this.IsInteger  --this.CheckIntBound(数字并检测范围Min~Max)
									  --this.CheckStrBound(str,Min,Max)检测字符范围
*this.Double 浮点数 --this.IsDouble 
*this.QQ  QQ        --this.CheckQQ    --this.DomQQ
*this.EngLish      --this.CheckEnglisth --this.DomEngListh
*this.Chinese      --this.CheckChinese    --this.DomChinese
*this.Url  检测Url         --this.CheckUrl      --this.DomUrl
*this.DateStr  检测时间    --this.CheckDateStr       --this.DomDateStr
*this.strIs    检测新正则接口  --this.CheckstrId      --this.DomstrId
*this.ErrStr   --如你未设置ErrMes则显示该默认错误信息
*this.RigthStr  --如你未设置RightMes则显示该正确信息
*this.AaxErrStr  --默认ajax错误信息
*this.ErrColor   --错误提示信息颜色默认为:red
*this.RightColor  --正确提示信息颜色默认为:blue
*this.Event   --批量注册的检测事件
*this.ClassName  --设置类名要和当前创建的类名一致
*this.SetEvent  --根据Event和ClassName属性来设置注册验证事件，该事件会覆盖原有的
*
*--类方法
*this.CheckForm()  --检测整个表单，如是正确返回true 否则返回false
*this.CheckEvent(event)  --是对表单元素进行实时验证
*this.Chek         --为没个表单元素加个事件
*
*以上属性可在创建类后更改，方法也可直接从类中使用
*例如:
*var ck=new CheckFormClass('myform',2)
*ck.Errstr='出错了';--更改默认错误信息
*alert(ck.CheckUserName('xxxx'));或alert(ck.DomUserName('xxx'));
*/
function CheckFormClass(Form,Mode)
{
	this.Email=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;//邮箱正则
	this.UserName=/^[\w_]{4,20}$/;//用户名
	this.UserPsd=/^[\w_]{6,16}$/;
	this.UserTrueName=/^[\u4E00-\u9FAFA-Za-z]+$/;//检测真实姓名
	this.Integer=/^[-\+]?\d+$/;//单精度数
	this.Double=/^[-\+]?\d+(\.\d+)?$///双精度数
	this.QQ=/^[1-9]\d{4,8}$///验证QQ
	this.English=/^[A-Za-z]+$/
	this.Chinese=/^[\u0391-\uFFE5]+$///验证中文
	//验证Url连接
	this.Url=/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/
	//检测时间,粗略的检测了下年月日
	this.DateStr=/^((\d{4})|(\d{2}))[\-\.\/](\d{1,2})[\-\.\/](\d{1,2})/;
	this.strIs;//此处提供一个扩展测试新正则接口,必须先设置该值后在调用DomstrIs即可
	this.ErrStr='数据输入出错，请仔细填写!';//默认出错信息提示
	this.RightStr='√';//默认正确信息提示(Mode=1该语句不显示)
	this.AjaxErrStr="数据库已存在该对象请更改输入后在检测";
	this.ErrColor="red";//默认错误显示颜色
	this.RightColor="blue";//默认正确时显示颜色
	this.Event="onblur";//实时验证默认触发事件
	this.ClassName="Ck";//取创建的类名
	this.obj=function(str)
	{
		return document.getElementById(str)
	}
	//返回同一名所有对象
	this.objar=function(Str)
	{
		return document.getElementsByName(str)
	}
	 //去空格函数
	this.trim=function(str){  
	  return   str.replace(/^\s*|\s*$/gi,""); 
	}  
	//计算字符长度
	this.getIntLeng = function(str) 
	{
        var sTmpChar;
        var nOriginLen = 0;
        var nStrLength = 0;
        nOriginLen = str.length; 
        for ( var i=0 ; i < nOriginLen ; i++ ) {
                sTmpChar = str.charAt(i); 
				//从第一个字符开始算起
                if (escape(sTmpChar).length >=3) {
				//如实ASCII大与255的值编码后字符长度变长
                        nStrLength += 2;     
                } else if (sTmpChar!='\r') {    
                        nStrLength ++;   
                }
        }
        return nStrLength;       
	}
	//ajax功能,操纵返回格式是Xml
	this.CreateXmlHttp=function()
	{
		try
		{
			return new XMLHttpRequest();//非Ie
		}catch(e)
		{
			try
			{
				return new ActiveXObject('Msxml2.XMLHTTP');
			}catch(e)
			{
				try
				{
					return new ActiveXObject('Microsoft.XMLHTTP');
				}catch(e)
				{
					return false;
				}
			}
		}
	}
	this.AjaxBackTxt=function(url)
	{
		var ObjHtp=this.CreateXmlHttp();
		ObjHtp.open("Get",url,false);
		ObjHtp.send(null); 
		return ObjHtp.responseText;
	}
	this.CreateXmlDom=function()
	{
	 try
        {
			//未非Ie的XmDom直接没有这个loadXML属性，但DOmParser可以解决		
			if(!document.all){
				XMLDocument.prototype.loadXML = function(xmlString){
					var childNodes = this.childNodes;
					for (var i = childNodes.length - 1; i >= 0; i--)
					this.removeChild(childNodes[i]);//删除原对象的所有节点
					var dp = new DOMParser();
					var newDOM = dp.parseFromString(xmlString, "text/xml");
					var newElt = this.importNode(newDOM.documentElement, true);
					//importNode把节点对象复制当前文档
					this.appendChild(newElt);//把对象添加到文档中
				}
			}
            return document.implementation.createDocument("","",null);//非Ie
        }catch(e)
        {
                try
                {
                        return new ActiveXObject('MSXML2.DOMDocument');
                }catch(e)
                {
                        try
                        {
                                return new ActiveXObject("microsoft.XmlDom");
                        }catch(e)
                        {
                                return false;
                        }
                }
        }
	}
	this.GetDomXml=function(url)
	{
		var objXml=this.CreateXmlDom();
		objXml.loadXML(this.AjaxBackTxt(url));
		var root
		try{
			root=objXml.documentElement.childNodes;
		}catch(e)
		{
				return "";
		}
		return root[0].childNodes[0].nodeValue
		//还可返回属性值:root[0].attributes[0].nodeValue
	}
	//正则验证
	this.jsvalidation=function(pattern,str)
	{
	  var regstr=pattern;
	  var reg=new RegExp(regstr);
	  if(reg.test(str)){
	  return true;
	  }
	  else{
	  return false;
	  }
	}
	//判断是否数字
	this.IsInteger=function(str)
	{
		return this.jsvalidation(this.Integer,this.trim(str))
	}
	this.IsDouble=function(str)
	{
		return this.jsvalidation(this.Double,this.trim(str))
	}
	
	//检测邮件
	this.CheckEmail=function(str)
	{
		return this.jsvalidation(this.Email,this.trim(str))
	}
	//检测用户名
	this.CheckUserName=function(str)
	{
		return this.jsvalidation(this.UserName,this.trim(str))
	}
	//检测密码
	this.CheckUserPsd=function(str)
	{
		return this.jsvalidation(this.UserPsd,this.trim(str))
	}
	//检测真实姓名
	this.CheckUserTrueName=function(str)
	{
		return this.jsvalidation(this.UserTrueName,this.trim(str))
	}
	//检测QQ
	this.CheckQQ=function(str)
	{
		return this.jsvalidation(this.QQ,this.trim(str))
	}
	//检测Englisth
	this.CheckEnglish=function(str)
	{
		return this.jsvalidation(this.English,this.trim(str))
	}
	//检测中文
	this.CheckChinese=function(str)
	{
		return this.jsvalidation(this.Chinese,this.trim(str))
	}
	//检测Url
	this.CheckUrl=function(str)
	{
		return this.jsvalidation(this.Url,this.trim(str))
	}
	//检测时间
	this.CheckDateStr=function(str)
	{
		return this.jsvalidation(this.DateStr,this.trim(str))
	}
	
	//扩展属性
	this.CheckstrIs=function(str)
	{
		return this.jsvalidation(this.strIs,this.trim(str))
	}
	//检测字符长度是否在某一范围内(字符计算)
	this.CheckStrBound=function(str,StrMinLen,StrMaxLen)
	{
		if(this.getIntLeng(this.trim(str))<StrMinLen || this.getIntLeng(this.trim(str))>StrMaxLen)
		{
			return false;
		}else{
			return true;
		}
	}
	//检测是否为整数，数字长度是否范围内
	this.CheckIntBound=function(str,StrMinLen,StrMaxLen)
	{
		if(this.IsInteger(this.trim(str)))
		{
			if(this.CheckStrBound(str,StrMinLen,StrMaxLen))
			{
				return true
			}else
			{
				return false;
			}
		}else
		{
		return false;
		}
	}
	//判断值是否为空(false)
	this.CheckEmpty=function(str)
	{
		if(this.trim(str)=='')
		{
			return false
		}else{
			return true;
		}
	}	
	//取错误信息
	this.ErrMes=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var ErrStr;
		//ErrStr=DomTxt.attributes("ErrMes").nodeValue;
		ErrStr=DomTxt.getAttribute("ErrMes");
		if(ErrStr==null)	
		{
			ErrStr=this.ErrStr;//设置出错默认语句
		}
		return ErrStr;
	}
	//取的ajax错误信息
	this.AjaxErrMes=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var AjaxErrStr;
		AjaxErrStr=DomTxt.getAttribute("AjaxErrMes");
		if(AjaxErrStr==null)
		{
			AjaxErrStr=this.AjaxErrStr;//设置出错默认语句
		}
		return AjaxErrStr;
	}
	//取正确信息
	this.RightMes=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var RightStr;
		RightStr=DomTxt.getAttribute("RightMes");
		if(RightStr==null)
		{
			RightStr=this.RightStr;
		}
		return RightStr;
	}
	//取最小值
	this.Min=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var MinStr;
			MinStr=DomTxt.getAttribute("Min");
		if(MinStr==null)
		{
			alert('出错:'+DomTxt.name+'最小范围未设置');
			MinStr=0;
		}
		return MinStr;
	}
	//取最大值
	this.Max=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var MaxStr;
		MaxStr=DomTxt.getAttribute("Max");
		if(MaxStr==null)
		{
			alert('出错:'+DomTxt.name+'最大范围未设置');
			MaxStr=0;
		}
		return MaxStr;
	}
	//取AjaxUrl连接页
	this.AjaxUrl=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		var Url;
		Url=DomTxt.getAttribute("AjaxUrl");
		if(Url==null)	
		{
			Url="";//设置出错默认语句
		}
		return Url;
	}
	//取表单元素验证类型
	this.DataType=function(DomName)
	{

		var DomTxt=this.obj(DomName);
		var DataStr="";
		DataStr=DomTxt.getAttribute("DataType");
		if(DataStr==null)
		{
			DataStr="";
		}
		return DataStr;
	}
	//把错误信息写入页面函数
	this.SetPageMes=function(DomName,Type,Mes)
	{
		switch(Type)
		{
			case 1://错误信息
			{
				var DomTxt=this.obj(DomName);
				var span = document.createElement("SPAN");
				span.id = "Errspan"+DomTxt.name;
				span.style.color = this.ErrColor;
				DomTxt.parentNode.appendChild(span);
				span.innerHTML=Mes;
				break;
			}
			case 2:
			{	
				var DomTxt=this.obj(DomName);
				var span = document.createElement("SPAN");
				span.id = "Rightspan"+DomTxt.name;
				span.style.color =this.RightColor;
				DomTxt.parentNode.appendChild(span);
				span.innerHTML=Mes;
				break;	
			}
		}
	}
	//创建提示信息节点
	this.CreaSpanMes=function(DomName,type)
	{
		switch(type)
		{
			case 1:   //显示错误信息(无显示空)
				var DomTxt=this.obj(DomName);
				//删除正确信息节点
				if(!(this.obj("Rightspan"+DomTxt.name)==null))
				{
					DomTxt.parentNode.removeChild(this.obj("Rightspan"+DomTxt.name));
				}
				if(this.obj("Errspan"+DomTxt.name)==null)
				{
					this.SetPageMes(DomName,1,this.ErrMes(DomName));
				}
				break;
			case 2: 
				var DomTxt=this.obj(DomName);
				if(!(this.obj("Errspan"+DomTxt.name)==null))
				{
					DomTxt.parentNode.removeChild(this.obj("Errspan"+DomTxt.name));
				}
				if(this.obj("Rightspan"+DomTxt.name)==null)
				{
					this.SetPageMes(DomName,2,this.RightMes(DomName));
				}
				break;
		}
	}
	this.AlertMes=function(DomName,type)
	{
		switch(type)
		{
			case 1: //显示错误提示
				var DomTxt=this.obj(DomName);
				alert(this.ErrMes(DomName));
				break;
			case 2:
				//正确不显示
				break;
		}
	}
	//根据Mode如何显示出错信息
	this.Message=function(DomName,type)
	{
		switch(Mode)
		{
			case 1:
				this.AlertMes(DomName,type);
				break;
			case 2:
				this.CreaSpanMes(DomName,type);
				break;
		}
	}
	//ajax出错信息，注意这里忽略了ajax正确时候提示，考虑这个字段非常重要的话因该前面还会别的判断
	//所以DomAjax一般放在DataType的最后面，你要实在不知道放什么就放个检测非空的DomEmpty
	this.AjaxMessage=function(DomName)
	{
		var DomTxt=this.obj(DomName);
		switch(Mode)
		{
			case 1:
				alert(this.ErrMes(DomName));
				break;
			case 2:
				if(!(this.obj("Rightspan"+DomTxt.name)==null))
				{
					DomTxt.parentNode.removeChild(this.obj("Rightspan"+DomTxt.name));
				}
				if(this.obj("Errspan"+DomTxt.name)==null)
				{
					this.SetPageMes(DomName,1,this.AjaxErrMes(DomName));
					
				}else
				{
					this.obj("Errspan"+DomTxt.name).innerHTML=this.AjaxErrMes(DomName);		
				}
				break;
		}
	}
	//下面是用节点取值来判断
	this.DomstrIs=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckstrIs(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	
	this.DomEmail=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckEmail(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	
	this.DomUserName=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckUserName(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomUserPsd=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckUserPsd(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomUserTrueName=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckUserTrueName(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomQQ=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckQQ(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomEnglisth=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckEnglish(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomChinese=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckChinese(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomDateStr=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckDateStr(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomStrBound=function(DomName)
	{
		var str=this.obj(DomName).value;
		var Min=this.Min(DomName);
		var Max=this.Max(DomName);
		var bl=true;
		bl=this.CheckStrBound(str,Min,Max);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomIntBound=function(DomName)
	{
		var str=this.obj(DomName).value;
		var Min=this.Min(DomName);
		var Max=this.Max(DomName);
		var bl=true;
		bl=this.CheckIntBound(str,Min,Max);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomAmount=function(DomName)
	{//比较两个数相等，一般用来设置重复密码，这里有命名规则在最后加个R
		var str=this.trim(this.obj(DomName).value);
		var str_2=this.trim(this.obj(DomName.substr(0,(DomName.length-1))).value);
		//去掉后面R就表示前面的值了
		var bl=true;
		if(str==str_2)
		{
			this.Message(DomName,2);
		}else
		{
			bl=false;
			this.Message(DomName,1);
		}
		return bl;
	}
	this.DomEmpty=function(DomName)
	{
		var str=this.obj(DomName).value;
		var bl=true;
		bl=this.CheckEmpty(str);
		if(bl)
		{
			this.Message(DomName,2);
		}else
		{
			this.Message(DomName,1);
		}
		return bl;
	}
	//增加ajax检测
	this.DomAjax=function(DomName)
	{
		var Url=this.AjaxUrl(DomName);
		if(Url==""){alert("开通ajax检测请先设置好AjaxUrl属性");return false;}
		//把属性值加到Url后面
		if(Url.indexOf('?')==-1)
		{
			Url=Url+'?'+DomName+'='+this.trim(this.obj(DomName).value);
		}else
		{
			Url=Url+'&'+DomName+'='+this.trim(this.obj(DomName).value);
		}
		var IsValue=this.GetDomXml(Url);//获取数据库值
		var bl=true;
		if(IsValue==''){alert('ajax获取内容页出错');this.AjaxMessage(DomName);return false;}
		//防止ajax出错设置
		if(parseInt(IsValue))
		{
			this.AjaxMessage(DomName);
			bl=false;
		}
		return bl;
	}
	//检测函数是否存在
	this.CheckDom=function(strName)
	{
			var bl=true;
			//新增加判断函数请放到这里一份
			switch(this.trim(strName)){
			case "DomstrIs" :
			case "DomEmail" :
			case "DomUserName" :
			case "DomUserPsd":
			case "DomUserTrueName" :
			case "DomQQ" :
			case "DomEnglisth" :
			case "DomChinese" : 
			case "DomDateStr" :
			case "DomStrBound" :
			case "DomIntBound" :
			case "DomAmount" :
			case "DomEmpty" :
			case "DomAjax" :
				break;
			default :
				alert('没有此函数对象:'+strName+'请仔细填写');
				bl=false
				break;
		}
		return bl;
	}
	//检测整个表单
	this.CheckForm=function()
	{
		var ObjForm=this.obj(Form);  //表单对象,这里一定要设置表单Id属性
		var ObjEm=ObjForm.elements;
		var ObjLen=ObjEm.length;
		var bl=true;
		for(var i=0;i<ObjLen;i++)
		{
			var Dom=ObjEm[i].name;
			if(Dom!="")
			{
				var CheckStr=this.DataType(Dom);
				if(CheckStr!="")
				{
					var CheckStrAr=CheckStr.split(",");//支持对同一数据进行多个验证用","隔开
					var CheckStrArLen=CheckStrAr.length;
					for(var Ari=0;Ari<CheckStrArLen;Ari++)
					{
						if(!(this.CheckDom(CheckStrAr[Ari]))){break;}
						if(!(eval('this.'+CheckStrAr[Ari]+'(\''+Dom+'\')')))
						{
							bl=false;
							break;
						}
						
					}
					if(!bl)
					{
						ObjEm[i].focus();//得到焦点
						if(Mode==1)//如是弹出模式 则停止程序
						{
							break;
						}
					}
					
				}
			}
		}
		return bl;
	}
	//针对个表单事件做实时验证
	this.CheckEvent=function(event)
	{
		var event = window.event || event;
		var srcElement = event.srcElement || event.target;
		var obj=srcElement;
		if(obj.name!="")
		{
			var CheckStr=this.DataType(obj.name);
			if(CheckStr!="")
			{
				var CheckStrAr=CheckStr.split(",");//支持对同一数据进行多个验证用","隔开
				var CheckStrArLen=CheckStrAr.length;
				var bl=true;
				for(var Ari=0;Ari<CheckStrArLen;Ari++)
				{
					if(!(this.CheckDom(CheckStrAr[Ari]))){break;}
					if(!(eval('this.'+CheckStrAr[Ari]+'(\''+obj.name+'\')')))
					{
						bl=false;
						break;
					}
				}
			}
		}
		return bl;
	}
	var re=true;//让下面的函数只执行一次
	//该函数用注册事件
	this.SetEvent=function()
	{
		if(re)
		{
			var ObjForm=this.obj(Form);  //表单对象,这里一定要设置表单Id属性
			var ObjEm=ObjForm.elements;
			var ObjLen=ObjEm.length;
			var bl=true;
			for(var i=0;i<ObjLen;i++)
			{
				eval('ObjEm[i].'+this.Event+'=function(event){'+this.ClassName+'.CheckEvent(event);}')
				//这里是覆盖原来的参数，要想不覆盖可用attachEvent
			}
		}else
		{
			re=false;
		}
	}
}