/*
 *--------------- 客户端表单通用验证CheckForm(oForm) -----------------
 * 功能:通用验证所有的表单元素.
 * 使用:
 *	<script language=javascript src=check.js></script>
 *	<form name="form1" onsubmit="return CheckForm(this)">
 *	<INPUT TYPE="text" NAME="user" check="commonChar|required" param0="5,20" warning="用户名为字母数字和下划线 请在 5-20个字符之间" style="ime-mode: disabled " > 
 *	<input type="text" name="id" check="required" warning="id不能为空,且不能含有空格">
 *	<input type="submit">
 *	</form>
<script >

修改记录 by ggg 改进 email:gggxin@hotmail.com  QQ 632519 
2005-8-15
	增加多重验证 每个验证条件可以用 |来分割比如
	 check="commonChar|required" 
	 修改验证符对大小写不敏感 这样required 与 Required 可以表示同一个效果

2005-7-29
	warning check param0 参数对大小写不敏感
	我发现直接从dreamweare 里复制元素时 check 会自动变成大写
	从而导致验证失败

2005-6-23 
	加上 equalsField  email commonChar required chineseChar date number 的验证类型库
	这样避免了每次都要输入表达式 并提供出错弹出警告框或在指定区域显示错误信息功能

 * author:wanghr100(灰豆宝宝.net)
 * email:wanghr100@126.com
 * update:19:28 2004-8-23
 * 注意:写正则表达式时一定要小心.不要让"有心人"有空子钻.
 * 已实现功能:
 * 对text,password,hidden,file,textarea,select,radio,checkbox进行合法性验证
 * 待实现功能:把正则表式写成个库.
 *--------------- 客户端表单通用验证CheckForm(oForm) -----------------
 */
////////////////////////////////////////////////////////////////////////////////


function ValidateMethodFactory() {}
//验证  是否不能为空
//value2 定议长度参数
ValidateMethodFactory.validateRequired = function(value1)
{
	if(value1=="")	return false;
	return true;
}


//验证  指定长度
//value2 定议长度参数
ValidateMethodFactory.validateStringLenght = function(value1, value2)
{
	if(value1=="")	return false;
	var tmpExp="\\S";

	p1=parseFloat(value2.split(",")[0]);
	p2=parseFloat(value2.split(",")[1]);
//	alert(value1.length+":"+p1+":"+p2);

	if(ValidateMethodFactory.valiNumber(p1,""))	
	{
		if(ValidateMethodFactory.valiNumber(p2,"") )
		{
			if(!(value1.length>=p1 && value1.length<=p2))
			{
//	alert("1");
				return false;
			}
		}
		else
		{
			if(!(value1.length>=p1))
			{
//	alert("2");
				return false;
			}
		}
	}
	return true;

/*
	if(value2==null || value2=="" || !ValidateMethodFactory.valiNumber(p1,"")  || !ValidateMethodFactory.valiNumber(p2,""))
		tmpExp+="{1,}";
	else
		tmpExp+="{"+value2 + "}$";

//alert(tmpExp);
	var exp = new RegExp(tmpExp,"i");
	return exp.test(value1);
*/
}

//验证  必须与某一个域的值相等 param0：同一个表单中域的名称。例如用来校验密码 
ValidateMethodFactory.validateEqualsField = function(value1, value2)
{
//				alert(value1+":"+value2);
	return (value1 == value2);
}

//验证是否为邮件格式
ValidateMethodFactory.validateEmail = function(value)
{
	if(value=="")	return false;
	var pattern = /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/; 
	return pattern.test(value); 
}
//普通英文字符：字母数字和下划线
ValidateMethodFactory.validateCommonChar = function(value1, value2)
{
	if(value1=="")	return false;
	var tmpExp="^[A-Za-z0-9_]";
	if(value2==null || value2=="")
		tmpExp+="*$";
	else
		tmpExp+="{"+value2 + "}$";
	var exp = new RegExp(tmpExp);
	return exp.test(value1);
}
//验证日期 2005-07-05 是这样的格式
//value2 为日期的间隔方式
ValidateMethodFactory.validateDate = function(value1,value2)
{
//	alert(value);
	if(value1=="")	return false;
	if(value2=="")	value2="-";

	var tmpExp="^[0-9]{4,4}"+value2+"[0-9]{1,2}"+value2+"[0-9]{1,2}$";//^\d{4,4}\-\d{1,2}-\d{1,2}$
	var exp = new RegExp(tmpExp);
	return exp.test(value1);
}

//验证纯数字 第二个参数是数字的取值范围 如 5,10 表示 5 到10之间
ValidateMethodFactory.valiNumber = function(value1,value2)
{
	if(value1=="")	return false;
	var tmpExp="^[0-9]*$";
	var exp = new RegExp(tmpExp);
	if(!exp.test(value1))
		return false;
	value1=parseFloat(value1);	//进行类型转换
	if(value2!="undefined" &&  value2!=null && value2!="" )		//指定取值范围
	{
//alert(value1+":"+value2);
		p1=value2.split(",")[0];
		p2=value2.split(",")[1];
		if(exp.test(p2) && exp.test(p1))
		{
			p1=parseFloat(p1);	//进行类型转换
			p2=parseFloat(p2);
			//alert(p1+":"+p2);
			return (value1>=p1 && value1<=p2);	//在指定的数值之间
		}
		else if (exp.test(p1))
		{
			p1=parseFloat(p1);
			return value1>=p1 ;	//要比第一个值大
		}
	}
	return true;

}

//中文字符
ValidateMethodFactory.validateChineseChar = function(value1, value2)
{
	if(value1=="")	return false;
	var tmpExp="^^[\u4E00-\u9FA5\uF900-\uFA2D]";
	if(value2==null || value2=="")
		tmpExp+="*$";
	else
		tmpExp+="{"+value2 + "}$";
	var exp = new RegExp(tmpExp);
	return exp.test(value1);
}
//主函数
//oForm 要验证的表单对像 oText 一个div的id（将会在这个div中显示错误消息）,不写这个参数就表示显示警告框 
var errorObjNumb=null;				//验证失失败无素的序号
function CheckForm(oForm,oTextId)
{
	var ValidationFailCssStyle = "border:2px solid #FFCC88;";		//验证不通过时要加亮对象的样式
	var allFormObj = oForm.elements;
	var isSuccess=false;
	//遍历所有表元素
	if (errorObjNumb!=null)		//取消原来的样式
	{
/*
		//以下实现是否改变验证对像的样式
		var objCssLeng=allFormObj[errorObjNumb].style.cssText.length;	//保存要改变的对像原样式的长度
		var AddCssLeng=ValidationFailCssStyle.length;		//保存要添加样式的长度
	
		if(objCssLeng == AddCssLeng)
			allFormObj[errorObjNumb].style.cssText = "";
		else if (objCssLeng > AddCssLeng)
			allFormObj[errorObjNumb].style.cssText =allFormObj[errorObjNumb].style.cssText.substring(objCssLeng-AddCssLeng,AddCssLeng);
*/
		allFormObj[errorObjNumb].style.cssText = "";
	}

	for(var i=0;i<allFormObj.length;i++)
	{
//	alert(allFormObj.length);
//	return false;
		//是否需要验证
		if(allFormObj[i].check || allFormObj[i].CHECK)
		{

			var sReg = null;
			if(allFormObj[i].check)
				sReg = allFormObj[i].check.toLowerCase();
			if(allFormObj[i].CHECK)
				sReg = allFormObj[i].CHECK.toLowerCase();

			//取得验证的正则字符串
			//取得表单的值,用通用取值函数
			var sVal = GetValue(allFormObj[i]);
			var param0="";
			if(allFormObj[i].param0)
				param0=allFormObj[i].param0.toLowerCase();				//得到第一个参数

			if(allFormObj[i].PARAM0)
				param0=allFormObj[i].PARAM0.toLowerCase();				//得到第一个参数
//			alert(sReg+":"+allFormObj[i].name);

			var checkArray=sReg.split("|")					//required|email|commonChar 这样的字符进行切割
			var isRequired	= false;	//是否必填
			for (var iCheck=0;iCheck<=checkArray.length-1;iCheck++)				//判断当前是否必填
			{
				if(checkArray[iCheck]=="required" )
				{
					isRequired=true;
					break;
				}
			}
			if(!isRequired && allFormObj[i].value=="")	//没指定要必填 如果当前的内容为空,直接跳过,不进行验证
				continue;

			for (var iCheck=0;iCheck<=checkArray.length-1;iCheck++)		
			{
				sReg=checkArray[iCheck];

				if (sReg == "equalsfield")		//两值是否相同
				{
					eval("tmpparam0=oForm."+param0+".value;");
					isSuccess=ValidateMethodFactory.validateEqualsField(tmpparam0,allFormObj[i].value);
				}
				else if (sReg == "email")		//是否为邮件格式
				{
					isSuccess=ValidateMethodFactory.validateEmail(allFormObj[i].value);
				}
				else if (sReg == "required")		//不能为空
				{
					//eval("param0=oForm."+allFormObj[i].param0+".value;");
					isSuccess=ValidateMethodFactory.validateRequired(allFormObj[i].value,param0);
				}
				else if (sReg == "stringlenght")		//验证字符窜长度
				{
					//eval("param0=oForm."+allFormObj[i].param0+".value;");
					isSuccess=ValidateMethodFactory.validateStringLenght(allFormObj[i].value,param0);
				}
				else if (sReg == "commonchar")	//普通英文字符：字母数字和下划线
				{
					isSuccess=ValidateMethodFactory.validateCommonChar(allFormObj[i].value,param0);
				}
				else if (sReg == "chinesechar")	//汉字
				{
					isSuccess=ValidateMethodFactory.validateChineseChar(allFormObj[i].value,param0);
				}
				else if (sReg == "date")	//是否日期类型 第二个参数是日期的分隔方式
				{
					isSuccess=ValidateMethodFactory.validateDate(allFormObj[i].value,param0);
				}
				else if (sReg == "number")	//纯数字 第二个参数是数字的取值范围 如 5,10 表示 5 到10之间
				{
					isSuccess=ValidateMethodFactory.valiNumber(allFormObj[i].value,param0);
				}
				
				else
				{
					//字符串->正则表达式,不区分大小写
					var reg = new RegExp(sReg,"i");
					isSuccess=reg.test(sVal);
				}
//				alert(isSuccess+":"+sReg+":"+allFormObj[i].name);

				if(!isSuccess)					//验证不通过,弹出提示warning
				{
					errorObjNumb=i;
					var warning_str=null;

					if(allFormObj[i].warning)
						warning_str=allFormObj[i].warning;
					if(allFormObj[i].WARNING)
						warning_str=allFormObj[i].WARNING;
					if(oTextId)						//错误信息显示在div内
					{
						oTextId.innerHTML = warning_str;
					}
					else
					{
						alert(warning_str);
					}
/*
					//以下实现是否改变验证对像的样式
					var objCssLeng=allFormObj[i].style.cssText.length;	//保存要改变的对像原样式的长度
					var AddCssLeng=ValidationFailCssStyle.length;		//保存要添加样式的长度
					var objCssStr=allFormObj[i].style.cssText;
					if(objCssLeng < AddCssLeng)	//样式比要加的样式小
					{
						objCssStr	= objCssStr +";"+ValidationFailCssStyle;
						allFormObj[i].style.cssText = objCssStr;	//改变没通过验证对像的样式
					}
					else
					{
						if (objCssStr.substring(objCssLeng-AddCssLeng,AddCssLeng)!=ValidationFailCssStyle)
						{
							objCssStr	= objCssStr +";"+ValidationFailCssStyle;
							allFormObj[i].style.cssText = objCssStr;	//改变没通过验证对像的样式
						}
					}
*/
				//	allFormObj[i].style.cssText = ValidationFailCssStyle;	//改变没通过验证对像的样式
					//该表单元素取得焦点,用通用返回函数
					GoBack(allFormObj[i])  
					return false;
				}
			}
		}
	}
	return true;
}

//通用取值函数分三类进行取值
//文本输入框,直接取值el.value
//单多选,遍历所有选项取得被选中的个数返回结果"00"表示选中两个
//单多下拉菜单,遍历所有选项取得被选中的个数返回结果"0"表示选中一个
function GetValue(el)
{
	//取得表单元素的类型
	var sType = el.type;
	switch(sType)
	{
		case "text":
		case "hidden":
		case "password":
		case "file":
		case "textarea": return el.value;
		case "checkbox":
		case "radio": return GetValueChoose(el);
		case "select-one":
		case "select-multiple": return GetValueSel(el);
	}
	//取得radio,checkbox的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
	function GetValueChoose(el)
	{
		var sValue = "";
		//取得第一个元素的name,搜索这个元素组
		var tmpFormObj = document.getElementsByName(el.name);
		for(var i=0;i<tmpFormObj.length;i++)
		{
			if(tmpFormObj[i].checked)
			{
				sValue += "0";
			}
		}
		return sValue;
	}
	//取得select的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
	function GetValueSel(el)
	{
		var sValue = "";
		for(var i=0;i<el.options.length;i++)
		{
			//单选下拉框提示选项设置为value=""
			if(el.options[i].selected && el.options[i].value!="")
			{
				sValue += "0";
			}
		}
		return sValue;
	}
}

//通用返回函数,验证没通过返回的效果.分三类进行取值
//文本输入框,光标定位在文本输入框的末尾
//单多选,第一选项取得焦点
//单多下拉菜单,取得焦点
function GoBack(el)
{
	//取得表单元素的类型
	var sType = el.type;
	switch(sType)
	{
		case "hidden":break;
		case "text":
		case "password":
		case "file":
		case "textarea": el.focus();var rng = el.createTextRange(); rng.collapse(false); rng.select();
		case "checkbox":
		case "radio": var els = document.getElementsByName(el.name);els[0].focus();
		case "select-one":
		case "select-multiple":el.focus();
	}
}
/*
</script>

通用表单函数测试: <div id="errorDiv" style="color:red;font-weight:bold"></div>
<form name="form1" onsubmit="return CheckForm(this,errorDiv)"> 
用户名:<INPUT TYPE="text" NAME="user" check="commonChar|required" param0="5,20" warning="用户名为字母数字和下划线 请在 5-20个字符之间" style="ime-mode: disabled " > 
<BR>密码1:<input type="password" check="required" param0=6 warning="密码六位以上" name="passwd1">六位以上<br> 
密码2:<INPUT TYPE="password" check="equalsField|required" param0=passwd1 warning="两次输入的密码要相同" NAME="passwd2">六位以上<br> 
姓名:<input type="text" name="test" check="commonChar|required" warning="姓名只能为数字、字母组合">姓名<br> 
账号:<input type="text" check="required" warning="账号不能为空,且不能含有空格" name="id">不能为空<br> 
电话:<input type="text" check="number|required" warning="电话号码含有非法字符" name="number" value=""><br> 
相片上传:<input type="file" check="(.*)(\.jpg|\.bmp)$" warning="相片应该为JPG,BMP格式的" name="pic" ><br> 
出生日期:<input type="text" check="date|required" param0="-" warning="日期格式2004-08-10"  name="dt" value="">日期格式2004-08-10<br> 
邮件:<input type="text" check="email|required"  warning="邮件格式不对"  name="Email" value=""><br> 
省份: <select name="sel" check="^0$" warning="请选择所在省份"> <option value="">请选择 <option value="1">福建省 
<option value="2">湖北省 </select> <br> 选择你喜欢的运动:<br> 游泳<input type="checkbox" name="c" check="^0{2,}$" warning="请选择2项或以上"> 
篮球<input type="checkbox" name="c"> 足球<input type="checkbox" name="c"> 排球<input type="checkbox" name="c"> 
<br> 你的学历: 大学<input type="radio" name="r" check="^0$" warning="请选择一项学历"> 中学<input type="radio" name="r"> 
小学<input type="radio" name="r"> <br> 个人介绍: <textarea name="txts" check="^[\s|\S]{20,}$" warning="个人介绍不能为空,且不少于20字"></textarea>20个字以上 
<input type="submit"> </form>
*/