﻿// JavaScript Document
/********************************************************************
主题:表单验证类(Dec.2005)
作者:(原作者)我佛山人/(续貂者)Issac
********************************************************************/

function Validator(xmlFile, xmlNode, msgCss) {
	this.Obj=null;
	this.xmlFile = xmlFile || "Javascript/validator.xml";
	this.xmlNode = xmlNode || "initMsg,errMsg,okMsg,msg,id,value";	//前三个为一级节点名,后一个为二级公用节点名
	this.initNode = this.xmlNode.split(",")[0].replace(/\s/gi,"");
	this.errNode = this.xmlNode.split(",")[1].replace(/\s/gi,"");
	this.okNode = this.xmlNode.split(",")[2].replace(/\s/gi,"");
	this.msgNode = this.xmlNode.split(",")[3].replace(/\s/gi,"");
	this.IdAttr = this.xmlNode.split(",")[4].replace(/\s/gi,"");
	this.ValueAttr = this.xmlNode.split(",")[5].replace(/\s/gi,"");
	this.msgCss = msgCss || "valMsgInit,valMsgFocus,valMsgErr,valMsgOk";
	var _initCss = this.msgCss.split(",")[0].replace(/\s/gi,"");
	var _focusCss = this.msgCss.split(",")[1].replace(/\s/gi,"");
	var _errCss = this.msgCss.split(",")[2].replace(/\s/gi,"");
	var _okCss = this.msgCss.split(",")[3].replace(/\s/gi,"");
	if (window.ActiveXObject)	//For IE
		this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
	else if (document.implementation&&document.implementation.createDocument)	//For Mozilla
		this.xmlDoc=document.implementation.createDocument("","doc",null);
	else {
		alert("很抱歉,您的浏览器暂不支持该脚本,建议使用IE6!");
		return;
	}
	this.xmlDoc.async = false;
	this.xmlDoc.preserveWhiteSpace = true;
	this.xmlDoc.load(this.xmlFile);
	this.InitNode = this.xmlDoc.getElementsByTagName(this.initNode)[0].getElementsByTagName(this.msgNode);
	this.ErrNode = this.xmlDoc.getElementsByTagName(this.errNode)[0].getElementsByTagName(this.msgNode);
	this.OkNode = this.xmlDoc.getElementsByTagName(this.okNode)[0].getElementsByTagName(this.msgNode);
	this.InitPage = function(theForm) {
		var obj = theForm || document.forms[0];
		var count = obj.elements.length;
		for (var i=0; i<count; i++)
			with (obj.elements[i]) {
				if (typeof(getAttribute("msg"))=="object"||getAttribute("msg").split(",").length!=4)
					continue;
				var _msgId = getAttribute("msg").split(",")[0].replace(/\s/gi,"");
				var _initMsg = getAttribute("msg").split(",")[1].replace(/\s/gi,"");
				var _errMsg = getAttribute("msg").split(",")[2].replace(/\s/gi,"");
				var _okMsg = getAttribute("msg").split(",")[3].replace(/\s/gi,"");
				if (_msgId=="")
					continue;
				setAttribute("msgId",_msgId);
				if (_initMsg=="")
					setAttribute("initMsg","");
				else
					for (var j=0; j<this.InitNode.length; j++)
						if (this.InitNode[j].getAttribute(this.IdAttr)==_initMsg) {
							setAttribute("initMsg",this.InitNode[j].getAttribute(this.ValueAttr));
							break;
						}
				if (_errMsg=="")
					setAttribute("errMsg","");
				else
					for (j=0; j<this.ErrNode.length; j++)
						if (this.ErrNode[j].getAttribute(this.IdAttr)==_errMsg) {
							setAttribute("errMsg",this.ErrNode[j].getAttribute(this.ValueAttr));
							break;
						}
				if (_okMsg=="")
					setAttribute("okMsg","");
				else
					for (j=0;j<this.OkNode.length; j++)
						if (this.OkNode[j].getAttribute(this.IdAttr)==_okMsg) {
							setAttribute("okMsg",this.OkNode[j].getAttribute(this.ValueAttr));
							break;
						}
				with (document.getElementById(getAttribute("msgId"))) {
					innerHTML = obj.elements[i].getAttribute("initMsg");
					className = _initCss;
					obj.elements[i].onfocus = function() {
						className = (className==_initCss)?_focusCss:className;
					}
					obj.elements[i].onblur = function() {
						className = (className==_focusCss)?_initCss:className;
						//obj.elements[i].value = obj.elements[i].value.replace(/<[^<]+>/gi,"");	//No HTML Tag
					}
					style.display = (innerHTML=="")?"none":"block";
				}
			}
	};
	/***以下主要参见于我佛山人-Validator1.05***/
	/*Validator.Properties(属性)*/ 
	this.Chinese =  /^[\u0391-\uFFE5]+$/;
	this.Currency = /^\d+(\.\d+)?$/;
	this.Double = /^[-\+]?\d+(\.\d+)?$/;
	this.Email = /^[\w-]+@[\w-]+\.(com|cn|net|org|edu|mil|tv|biz|info)$/;
	this.IEmail = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
	this.English = /^[A-Za-z]+$/;
	this.Integer = /^[-\+]?\d+$/;
	this.Mobile = /^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$/;
	this.Number = /^\d+$/;
	this.Password = /^[\w!@#\$%\^&\*\(\)]{4,20}$/;
	this.UnSafe = /^(([A-Z]*|[a-z]*|\d*|[\~!@#\$%\^&\*\(\)-_=+\\\|\[\]\{\};:\'\",\.<>\/\?]*)|.{0,5})$|\s/;
	this.LowSafe = /^([A-Za-z]+|\d+|[_!@#\$%\^&\*\(\)]+)$/;
	this.MidSafe = /^([A-Za-z0-9]+|[A-Za-z_!@#\$%\^&\*\(\)]+|[\d_!@#\$%\^&\*\(\)]+)$/;
	this.HighSafe = /^([\w!@#\$%\^&\*\(\)]+)$/;
	this.Phone = /^(0{0,2}[1-9]\d{0,3}-)?(0?[1-9]\d{1,2}-)?[1-9]\d{6,7}(-\d{1,4})?(,[1-9]\d{6,7}(-\d{1,4})?)*$/;
	this.PhoneCountry = /^0{0,2}[1-9]\d{0,3}$/;
	this.PhoneArea = /^0?[1-9]\d{1,2}$/;
	this.PhoneNum = /^[1-9]\d{6,7}(-\d{1,4})?(,[1-9]\d{6,7}(-\d{1,4})?)*$/;
	this.QQ = /^[1-9]\d{4,8}$/;
	this.Require = /.+/;
	this.Url = /^http:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?$/;
	this.Username = /^\w{4,20}$/;
	this.Zip = /^[1-9]\d{5}$/;
	this.Range = "getAttribute('min') < (value|0) && (value|0) < getAttribute('max')";
	this.Repeat = "value == document.getElementById(getAttribute('to')).value";
	this.Limit = "this.limit(value.length,getAttribute('min'), getAttribute('max'))";
	this.LimitB = "this.limit(this.LenB(value), getAttribute('min'), getAttribute('max'))";
	this.Custom = "this.Exec(value, getAttribute('regexp'))";
	this.Compare = "this.compare(value,getAttribute('operator'),getAttribute('to'))";
	this.SafeString = "this.IsSafe(value)";
	this.IdCard = "this.IsIdCard(value)";
	this.Date = "this.IsDate(value, getAttribute('min'), getAttribute('format'))";
	this.Group = "this.MustChecked(getAttribute('name'), getAttribute('min'), getAttribute('max'))";
	this.Filter = "this.DoFilter(value, getAttribute('accept'))";
	this.Count = "this.DoCount(obj)";
	this.SafeLevel = "this.DoSafeLevel(obj)";
	this.ErrorItem = [document.forms[0]];
	this.ErrorMessage = ["以下原因导致提交失败：\t\t\t\t"];
	/*Validator.Methods(方法)*/
	this.ValSubmit = function(theForm){
		var obj = theForm || event.srcElement;
		var count = obj.elements.length;
		this.ErrorMessage.length = 1;
		this.ErrorItem.length = 1;
		this.ErrorItem[0] = obj;
		for(var i=0;i<count;i++)
			with(obj.elements[i]){
				var _dataType = getAttribute("dataType");
				if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined")
					continue;
				this.ClearState(obj.elements[i]);
				if(getAttribute("require") == "false" && value == "")
					continue;
				this.SwitchType(obj.elements[i],i);
			}
		if(this.ErrorMessage.length > 1){
			var errCount = this.ErrorItem.length;
			this.ErrorItem[1].focus();
			return false;
		}
		return true;
	};
	this.ValChange = function (theField) {
		var obj = theField || event.srcElement;
		with(obj){
			var _dataType = getAttribute("dataType");
			if(typeof(_dataType) == "object" || typeof(this[_dataType]) == "undefined")
				return;
			if(getAttribute("require") == "false" && value == "")
				return;
			this.SwitchType(obj);
		}
	};
	this.SwitchType = function (obj, i) {
		with (obj) {
			if (i==null && typeof(getAttribute("disChanged"))=="string")
				return;
			var _dataType = getAttribute("dataType"); 
			var oMsgDiv = document.getElementById(getAttribute("msgId"));
			switch(_dataType){
				case "IdCard" :
				case "Date" :
				case "Repeat" :
				case "Range" :
				case "Compare" :
				case "Custom" :
				case "Group" :
				case "Limit" :
				case "LimitB" :
				case "SafeString" :
				case "Filter" :
					if(!eval(this[_dataType])) {
						oMsgDiv.innerHTML = getAttribute("errMsg") + getAttribute("initMsg");
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else {
						oMsgDiv.innerHTML = getAttribute("okMsg");
						oMsgDiv.className = _okCss;
					}
					break;
				case "Username":
					if(!this[_dataType].test(value)) {
						oMsgDiv.innerHTML = getAttribute("errMsg") + getAttribute("initMsg");
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else if(IsExistUserName(this.Obj)){
						oMsgDiv.innerHTML = "当前用户名已存在，请重新填写！";
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else {
						oMsgDiv.innerHTML = getAttribute("okMsg");
						oMsgDiv.className = _okCss;
					}
					break;
				case "IEmail":
					if(!this[_dataType].test(value))
					 {
					//alert('ok');
						oMsgDiv.innerHTML = getAttribute("errMsg") + getAttribute("initMsg");
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else if(IsExistEmail(this.Obj)){
						oMsgDiv.innerHTML = "当前Email已注册过，请使用另外Email注册！";
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else {
						oMsgDiv.innerHTML = getAttribute("okMsg");
						oMsgDiv.className = _okCss;
					}
					break;
				default :
					if(!this[_dataType].test(value)) {
						oMsgDiv.innerHTML = getAttribute("errMsg") + getAttribute("initMsg");
						oMsgDiv.className = _errCss;
						if (i!=null)
							this.AddError(i, getAttribute("errMsg")+getAttribute("initMsg"));
					}
					else {
						oMsgDiv.innerHTML = getAttribute("okMsg");
						oMsgDiv.className = _okCss;
					}
					break;
			}
			
			oMsgDiv.style.display = (oMsgDiv.innerHTML=="")?"none":"block";
		}
	};
	this.BindKey = function(theField) {
		var obj = theField || event.srcElement;
		with (obj) {
			var _keyEvent = getAttribute("keyEvent");
			var _keyObj = getAttribute("keyObj");
			if(typeof(_keyEvent) == "object" || typeof(this[_keyEvent]) == "undefined")
				return;
			if(typeof(_keyObj) == "object" || document.getElementById(_keyObj)=="null")
				return;
			eval(this[_keyEvent]);
		}
	};
	this.limit = function(len,min,max){
		min = min || 0;
		max = max || Number.MAX_VALUE;
		return min <= len && len <= max;
	};
	this.LenB = function(str){
		return str.replace(/[^\x00-\xff]/g,"**").length;
	};
	this.ClearState = function(elem){
		/*with(elem){...}*/
	};
	this.AddError = function(index, str){
		this.ErrorItem[this.ErrorItem.length] = this.ErrorItem[0].elements[index];
		this.ErrorMessage[this.ErrorMessage.length] = this.ErrorMessage.length + ":" + str;
	};
	this.Exec = function(op, reg){
		return new RegExp(reg,"g").test(op);
	};
	this.compare = function(op1,operator,op2){
		switch (operator) {
			case "NotEqual":
				return (op1 != op2);
			case "GreaterThan":
				return (op1 > op2);
			case "GreaterThanEqual":
				return (op1 >= op2);
			case "LessThan":
				return (op1 < op2);
			case "LessThanEqual":
				return (op1 <= op2);
			default:
				return (op1 == op2);            
		}
	};
	this.IsSafe = function(str){
		return !this.UnSafe.test(str);
	};
	this.IsIdCard = function(number){
		var date, Ai;
		var verify = "10x98765432";
		var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
		var area = ['','','','','','','','','','','','北京','天津','河北','山西','内蒙古','','','','','','辽宁','吉林','黑龙江','','','','','','','','上海','江苏','浙江','安微','福建','江西','山东','','','','河南','湖北','湖南','广东','广西','海南','','','','重庆','四川','贵州','云南','西藏','','','','','','','陕西','甘肃','青海','宁夏','新疆','','','','','','台湾','','','','','','','','','','香港','澳门','','','','','','','','','国外'];
		var re = number.match(/^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$/i);
		if(re == null)
			return false;
		if(re[1] >= area.length || area[re[1]] == "")
			return false;
		if(re[2].length == 12){
			Ai = number.substr(0, 17);
			date = [re[9], re[10], re[11]].join("-");
		}
		else{
			Ai = number.substr(0, 6) + "19" + number.substr(6);
			date = ["19" + re[4], re[5], re[6]].join("-");
		}
		if(!this.IsDate(date, "ymd"))
			return false;
		var sum = 0;
		for(var i = 0;i<=16;i++)
			sum += Ai.charAt(i) * Wi[i];
		Ai +=  verify.charAt(sum%11);
		return (number.length ==15 || number.length == 18 && number == Ai);
	};
	this.IsDate = function(op, formatString){
		formatString = formatString || "ymd";
		var m, year, month, day;
		switch(formatString){
			case "ymd" :
				m = op.match(new RegExp("^((\\d{4})|(\\d{2}))([-./])(\\d{1,2})\\4(\\d{1,2})$"));
				if(m == null )
					return false;
				day = m[6];
				month = m[5]*1;
				year =  (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
				break;
			case "dmy" :
				m = op.match(new RegExp("^(\\d{1,2})([-./])(\\d{1,2})\\2((\\d{4})|(\\d{2}))$"));
				if(m == null )
					return false;
				day = m[1];
				month = m[3]*1;
				year = (m[5].length == 4) ? m[5] : GetFullYear(parseInt(m[6], 10));
				break;
			default :
				break;
		}
		if(!parseInt(month))
			return false;
		month = month==0 ?12:month;
		var date = new Date(year, month-1, day);
        return (typeof(date) == "object" && year == date.getFullYear() && month == (date.getMonth()+1) && day == date.getDate());
		function GetFullYear(y){
			return ((y<30 ? "20" : "19") + y)|0;
		}
	};
	this.MustChecked = function(name, min, max){
		var groups = document.getElementsByName(name);
		var hasChecked = 0;
		min = min || 1;
		max = max || groups.length;
		for(var i=groups.length-1;i>=0;i--)
			if(groups[i].checked)
				hasChecked++;
		return min <= hasChecked && hasChecked <= max;
	};
	this.DoFilter = function(input, filter){
		return new RegExp("^.+\.(?=EXT)(EXT)$".replace(/EXT/g, filter.split(/\s*,\s*/).join("|")), "gi").test(input);
	};
	this.DoCount = function(obj) {
		var obj = obj || event.srcElement;
		var _max = obj.getAttribute("max") || Number.MAX_VALUE;
		this.countLength = function () {
			return (obj.getAttribute("dataType")=="LimitB") ? this.LenB(obj.value) : obj.value.length;
		}
		this.countLimit = function() {
			if (obj.getAttribute("dataType")=="LimitB") {
				var cn = obj.value.replace(/[^\x00-\xff]/g,"#^").split("#^").length-1;
				return obj.value.substring(0, _max-cn);
			}
			else
				return obj.value.substring(0, _max-1);
		}
		if (this.countLength() > _max) {		
			alert("对不起，您最多可录入"+_max+"字，请删减！");
			obj.value = this.countLimit();
			obj.focus();
		}
		document.getElementById(obj.getAttribute("keyObj")).value = this.countLength();
	};
	this.DoSafeLevel = function(obj) {
		var obj = obj || event.srcElement;
		this.WhichLevel = function () {
			var safeArray = ["LowSafe","MidSafe","HighSafe"];
			for (var i=0; i<safeArray.length; i++)
				if (this[safeArray[i]].test(obj.value))
					return safeArray[i];
				return "Error";
		}
		with (document.getElementById(obj.getAttribute("keyObj")))
			switch (this.WhichLevel()) {
				case "LowSafe":
					className = "LowSafe";
					innerHTML = "<span>不安全</span>";
					break;
				case "MidSafe":
					className = "MidSafe";
					innerHTML = "<span>普通</span>";
					break;
				case "HighSafe":
					className = "HighSafe";
					innerHTML = "<span>安全</span>";
					break;
				default:
					className = "";
					innerHTML = "<span>密码安全性检查</span>";
					break;
			}
	};
}