//修改时间：2006-7-15 20:55		（转载请保留此信息）
//ModifyBy：caiyuzhuan	QQ:3095024	Email:caiyuzhuan@126.com
//根据需要自行进行修改，修改了提示内容，详见下面说明
//凯信138购物网		网址：http://www.kaixin138.com
//源文件来自太平洋电脑网	网址:http://www.pconline.com.cn

//2005-6-7 将判断长度的方法改成判断字节长度，一个中文占2个字节  ivanlin
/*
 * 检查提交的form的每个表单元素是否符合填写要求
 * @fm 需要检查的form元素。
 * @return 如果form的所有表单元素都符合要求，将返回true，
 * 否则将会报告不符合的原因，同时返回false。
 * 示例：
 * <form onsubmit="return checkForm(this)">
 *  	<input type=submit>
 *  	<input name=email title="请填写邮件地址~email!">
 * </form>
 * 说明：
 * 在form表单元素的title属性中指明此表单元素期望的格式。
 * 此格式说明如下
 *          请填写邮件地址~email!
 * 以最后一个"~"为界，前面的是提示信息，后面是格式信息。
 * 格式信息请遵守以下规则：
 * [number[f]:][type][!][`value]（[`value]，此项为新增加）
 * 说明：
 * number[f]:	一个数值后面跟一个":",表示此域的文本长度不可以超过指定的数值，如果在数值后面有个f表示固定长度必须为多少位
 * type可以是如下表达式
 *	 email	邮件地址
 *	 int		整数
 *	 float	浮点数
 *	 date		日期
 *	 time		时间
 *	 hasChinese     含有中文
 *	 allChinese	全部是中文
 *	 noChinese	没有中文
 *	 /.../[gi]	自定义正则式
 * !表示此处文本不可以为空
 * [`value]为提示内容，替代表单名称作为提示内容（新增加）
 * 对于<input type=radio > 格式串为
 * "请选择一个选项~!"表示此radio组必须选择一个选项
 * "请选择一个选项~"表示此radio组的选项可以不选。
 * 对于<input type=checkbox >或者<select multiple></select>格式串的意义为
 * 说明信息~min:0max:3
 * 对于<select ></select>非multiple类型
 * "请选择一个选项~!"表示此select不可以选择第一个选项
 * "请选择一个选项~"表示此select可以选择第一个选项
*/

function checkForm(fm)
{
	for(var i=0;i<fm.length;i++)
	{
		var title=fm[i].title;
		if(title=="")continue;//忽略未定义title的元素
		var p=title.lastIndexOf("~");
		if(p<0)continue;//忽略title中未定义检查格式的元素
		var info=title.substring(0,p);
		var format=title.substring(p+1,title.length);
		var name=fm[i].name;
		if(name=="")continue;//忽略没有名字的元素
		var value=trim(fm[i].value);
		//fm[i].value=value;//自动除去提交项的两端的空格
		
		if(fm[i].type=="radio")
		{
			if(checkRadio(fm,fm[i]))
			{
				continue;
			}
			else
			{
				return false;
			}
		}
		if(fm[i].type=="checkbox")
		{
			if(checkCheckbox(fm,fm[i]))
			{
				continue;
			}
			else
			{
				return false;
			}
		}
		if(fm[i].type=="select-one")
		{
			if(checkSelectOne(fm[i]))
			{
				continue;
			}
			else
			{
				return false;
			}
		}
		if(fm[i].type=="select-multiple")
		{
			if(checkSelectMultiple(fm[i]))
			{
				continue;
			}
			else
			{
				return false;
			}
		}
		var notNull=false;
		t=format.lastIndexOf("`")
		tips="";
		if(t>0)
		{
			tips=format.substring(t+1,format.length);
			format=format.substring(0,t);
		}
		if(!tips.length) tips=name;
		
		if(format.charAt(format.length-1)=="!")
		{
			notNull=true;
			format=format.substring(0,format.length-1);
		}
		if(notNull)
		{
			if(value=="")
			{
				t=info.lastIndexOf("|br|")
				if(t>0)
				{
					info_1=info.substring(0,t);
					info_2=info.substring(t+4,info.length);
				}
				else
				{
					info_1=info;
					info_2="";
				}
				info_2=info_2.replace(/<br>/g,"\n");
				alert(info_1+"\n"+tips+"不可以为空。"+"\n\n"+info_2);
				getfocus(fm[i]);
				return false;
			}
		}
		else
		{
			//内容可以为空时，
			if(value=="")
				continue;
		}
		//内容的长度判断
		var colonP=format.indexOf(":");
		if(colonP>0)
		{
			if(format.charAt(colonP-1)=='f')
			{
				var lengthLimit=format.substring(0,colonP-1);
				if(!isNaN(lengthLimit))
				{
					var len = getRealLength(value);
					if(len!=lengthLimit)
					{
						alert(info+"\n"+tips+"的长度为"+len+"位，必须为"+lengthLimit+"位");
						getfocus(fm[i]);
						return false;
					}
				}
			}
			else
			{
				var lengthLimit=format.substring(0,colonP);
				if(!isNaN(lengthLimit))
				{
					var len = getRealLength(value);
					if(len>lengthLimit)
					{
						alert(info+"\n"+tips+"的长度("+len+")超过限制"+lengthLimit);
						getfocus(fm[i]);
						return false;
					}
				}
			}
			format=format.substring(colonP+1,format.length);
		}
		if(format=="email")
		{
			//电子邮件格式
			var found=value.match(/\w+@.+\..+/);
			if(found==null)
			{
				alert(info+"\n"+tips+"的格式不正确:\n\""+value+"\"不是一个Email地址");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="int")
		{
			//整数
			return true;
			var intVal=parseInt(value);
			if(isNaN(intVal)||intVal!=value)
			{
				alert(info+"\n"+tips+"的格式不正确:\n"+value+"不是一个整数。");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="float")
		{
			//浮点数
			var floatVal=parseFloat(value);
			if(isNaN(floatVal)||floatVal!=value)
			{
				alert(info+"\n"+tips+"的格式不正确:\n"+value+"不是一个浮点数。");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="date")
		{
			//日期
			var found=value.match(/(\d{1,5})-(\d{1,2})-(\d{1,2})/);
			if(found==null||found[0]!=value||found[2]>12||found[3]>31)
			{
				alert(info+"\n"+tips+"的格式不正确:\n\""+value+"\"不是一个日期\n提示：[2000-01-01]");
				getfocus(fm[i]);
				return false;
			}
			var year=trim0(found[1]);
			var month=trim0(found[2])-1;
			var date=trim0(found[3]);
			var d=new Date(year,month,date);
			if(d.getFullYear()!=year||d.getMonth()!=month||d.getDate()!=date)
			{
				alert(info+"\n"+tips+"的内容不正确:\n\""+value+"\"不是一个正确的日期\n提示：[2000-01-01]");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="time")
		{
			//时间
			var found=value.match(/(\d{2}):(\d{2}):(\d{2})/);
			if(found==null||found[0]!=value||found[1]>23||found[2]>59||found[3]>59)
			{
				alert(info+"\n"+tips+"的格式不正确:\n\""+value+"\"不是一个时间\n提示：[05:38:00]");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="hasChinese")
		{
			var _hasChinese=false;
			for(var j=0;j<value.length;j++)
			{
				if(value.charCodeAt(j)>255)
				{
					_hasChinese=true;
					break;
				}
			}
			if(!_hasChinese)
			{
				alert(info+"\n"+tips+"的内容需要中文:\n\""+value+"\"不含有任何中文字符");
				getfocus(fm[i]);
				return false;
			}
		}
		else if(format=="allChinese")
		{
			for(var j=0;j<value.length;j++)
			{
				if(value.charCodeAt(j)<=255)
				{
					alert(info+"\n"+tips+"的内容要求全中文:\n\""+value+"\"含有非中文字符");
					getfocus(fm[i]);
					return false;
				}
			}
		}
		else if(format=="noChinese")
		{
			for(var j=0;j<value.length;j++)
			{
				if(value.charCodeAt(j)>255)
				{
					alert(info+"\n"+tips+"的内容要求非中文:\n\""+value+"\"含有中文字符");
					getfocus(fm[i]);
					return false;
				}
			}
		}
		else if(format!="")
		{
			//自定义
			try
			{
				var found=value.match(eval(format));
				if(found==null||found[0]!=value)
				{
					alert(info+"\n"+tips+"的内容不符合要求:\""+value+"\"");
					getfocus(fm[i]);
					return false;
				}
			}
			catch(e)
			{
				alert(e.name+":\n["+fm[i].name+"]正则式\""+format+"\"");
				return false;
			}
		}
	}
	return true;
}

function getfocus(f)
{
	if(f.type!="hidden")
		f.focus()
}

function checkRadio(fm,opt)
{
	var title=opt.title;
	if(title=="")return true;//忽略未定义title的元素
	var p=title.lastIndexOf("~");
	if(p<0)return true;//忽略title中未定义检查格式的元素
	var info=title.substring(0,p);
	var format=title.substring(p+1,title.length);
	var name=opt.name;
	if(name=="")return true;//忽略没有名字的元素
	if(format=="!")
	{
		//必须选择一个选项
		if(typeof(fm.all[name].length)=="undefined")
		{
			//同名radio只有一个
			if(opt.checked)
			{
				return true;
			}
			else
			{
				alert(info+"\n必须选择"+tips);
				opt.focus();
				return false;
			}
		}
		else
		{
			//是一个radio组
			var radios=fm[name];
			for(var j=0;j<radios.length;j++)
			{
				if(radios[j].checked==true)return true;
			}
			alert(info+"\n必须选择"+tips+"的一个选项");
			opt.focus();
			return false;
		}
	}
	else
	{
		//可以一个选项也不选
		return true;
	}
}

function checkCheckbox(fm,opt)
{
	var title=opt.title;
	if(title=="")return true;//忽略未定义title的元素
	var p=title.lastIndexOf("~");
	if(p<0)return true;//忽略title中未定义检查格式的元素
	var info=title.substring(0,p);
	var format=title.substring(p+1,title.length);
	var name=opt.name;
	if(name=="")return true;//忽略没有名字的元素

	var min=format.match(/min:(\d+)\w*/);
	var max=format.match(/\w*max:(\d+)/);

	if(typeof(fm.all[name].length)=="undefined")
	{
		//只有一个同名checkbox
		if(min!=null)
		{
			if(min[1]==1&&!opt.checked)
			{
				alert(info+"\n必须选上"+tips+"选项");
				opt.focus();
				return false;
			}
		}
	}
	else
	{
		//一个checkbox组
		var checkboxes=fm.all[name];
		var check_count=0;
		for(var j=0;j<checkboxes.length;j++)
		{
			if(checkboxes[j].checked)check_count++;
		}
		if(min!=null)
		{
			if(min[1]>check_count)
			{
				alert(info+"\n"+tips+"至少需要选择"+min[1]+"个选项");
				opt.focus();
				return false;
			}
		}
		if(max!=null)
		{
			if(max[1]<check_count)
			{
				alert(info+"\n"+tips+"至多可以选择"+max[1]+"个选项");
				opt.focus();
				return false;
			}
		}
	}
	return true;
}

function checkSelectOne(sel)
{
	var title=sel.title;
	if(title=="")return true;//忽略未定义title的元素
	var p=title.lastIndexOf("~");
	if(p<0)return true;//忽略title中未定义检查格式的元素
	var info=title.substring(0,p);
	var format=title.substring(p+1,title.length);
	var name=sel.name;
	if(name=="")return true;//忽略没有名字的元素
	
	if(format=="!"&&sel.selectedIndex==0)
	{
		alert(info+"\n"+tips+"不可以选择第一个选项");
		sel.focus();
		return false;
	}
	return true;
}

function checkSelectMultiple(sel)
{
	var title=sel.title;
	if(title=="")return true;//忽略未定义title的元素
	var p=title.lastIndexOf("~");
	if(p<0)return true;//忽略title中未定义检查格式的元素
	var info=title.substring(0,p);
	var format=title.substring(p+1,title.length);
	var name=sel.name;
	if(name=="")return true;//忽略没有名字的元素

	var min=format.match(/min:(\d+)\w*/);
	var max=format.match(/\w*max:(\d+)/);
	
	var select_count=0;
	for(var j=0;j<sel.length;j++)
	{
		if(sel[j].selected)select_count++;
	}
	if(min!=null)
	{
		if(min[1]>select_count)
		{
			alert(info+"\n"+tips+"至少需要选择"+min[1]+"个选项");
			sel.focus();
			return false;
		}
	}
	if(max!=null)
	{
		if(max[1]<select_count)
		{
			alert(info+"\n"+tips+"至多可以选择"+max[1]+"个选项");
			sel.focus();
			return false;
		}
	}
	return true;
}

function trim(s)
{
	/*** 除去字符串变量s两端的空格。*/
	s=s.replace(/^ */,"");
	s=s.replace(/ *$/,"");
	return s;
}

function trim0(s)
{
	/**
	* 除去字符串表示的数值变量开头的所有的"0"。
	* 比如
	* 	trim0("01")将返回"1"
	* 	trim0("1")将返回"1"
	* 	trim0("10")将返回"10"
	* 	trim0("000")将返回"0"
	*/
	if(s.length==0)return s;
	s=s.replace(/^0*/,"");
	if(s.length==0)s="0";
	return s;
}

function getRealLength(val){
	var len=0;
	for (i=0;i<val.length;i++){
		if (val.charCodeAt(i)>255) len+=2; else len++;
	}
	return len;
}