// GlobalFunction.js

/*Web应用根目录的绝对路径。*/
var GRootPath  = "/NetAgentWeb";

/*调试级别及允许的方法，高级别可包含低级别方法：
	0、正常运行；>=5、允许使用 window.status 显示信息；>=6、允许使用 alert 显示信息；
	>=9、允许使用 debugger 调用调试工具。*/
var G_DEBUG_LEVEL = 0; 

var GFunction = new GlobalFunction();

/*公用函数集合定义*/
function GlobalFunction() {

	// 含有异步下载对象信息，仅供 getPageContent、onGetPageContentDone 方法使用。
	var downloadObjs = new Array();

	/*使用指定URL进行数据下载。
		如果是同步方法，则直接返回下载内容（指定URL的整个页面或其它的传回数据）;
		如果是异步方法，则在下载完成后，使用下载内容作为参数调用回调方法，而此方法直接返回空串；
		如果此方法发生错误则返回 null。
		传入url地址串、请求参数（可选）、异步下载时的回调方法（可选）、下载内容类型（可选，默认为字符串）；
		如果不需要请求参数，则可传入null；如果是异步下载，则必须提供回调方法，否则认为是同步下载。
		下载内容类型可为：0、字符串（默认）；1、XML DOMDocument 对象；2、二进制字节数组*/
	this.downloadData = function fnDownloadData(url, requestParameter, callBackMethod, resultType) {
		try {
			if (typeof(callBackMethod) != "function") callBackMethod = null;
			if (typeof(resultType) != "number" || resultType != 1 && resultType != 2) resultType = 0;
			var isAsync = (callBackMethod != null);
			var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //Msxml2.XMLHTTP // Msxml2.ServerXMLHTTP.4.0
			if (isAsync) {
				var index = 0;
				var downArray = null;
				for (; index < downloadObjs.length; index++) {
					if (downloadObjs[index][0] != null) continue;
					downArray = downloadObjs[index];
					break;
				}
				if (downArray == null) {
					downArray = new Array();
					index = downloadObjs.length;
					downloadObjs[index] = downArray;
				}
				downArray[0] = xmlhttp;
				downArray[1] = callBackMethod;
				downArray[2] = resultType;
				xmlhttp.onreadystatechange = new Function ("GFunction.onGetPageContentDone(" + index + ")");
			} else {
				window.status = "请稍候，正在查询数据。。。";
			}
			xmlhttp.open("POST", url, isAsync);
			xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			if (requestParameter && requestParameter.length) {
				requestParameter = encodeURI(requestParameter);
				xmlhttp.setRequestHeader("Content-Length", requestParameter.length);
				xmlhttp.send(requestParameter);
			} else {
				xmlhttp.send();
			}
			if (isAsync) {
				return "";
			} else {
				window.status = "";
				//alert(xmlhttp.responseText);
				//alert(xmlhttp.getAllResponseHeaders());
				switch (resultType) {
					case 1:
						return xmlhttp.responseXML;
					case 2:
						return xmlhttp.responseBody;
					default:
						return xmlhttp.responseText;
				}
			}
		} catch (error) {
			if (G_DEBUG_LEVEL >= 5) {
				window.status = "(" + (error.number & 0xFFFF) + ")" + error.description;
			} else {
				window.status = "";
			}
			return null;
		}
	}
	
	/*异步下载完成后，将使用此方法以调用回调方法，进行回调处理。*/
	this.onGetPageContentDone = function(index) {
		var xmlhttp = downloadObjs[index][0];
		if (xmlhttp.readyState == 4) {
			try { // 回调异步方法
				var value;
				switch (downloadObjs[index][2]) {
					case 1:
						value = xmlhttp.responseXML;
					case 2:
						value = xmlhttp.responseBody;
					default:
						value = xmlhttp.responseText;
				}
				downloadObjs[index][1].apply(null, new Array(value));
			} catch (error) {
				if (G_DEBUG_LEVEL >= 5) window.status = index + ":(" + (error.number & 0xFFFF) + ")" + error.description;
			}
			downloadObjs[index][0] = null;
		}
	}

//运行等待提示窗
	/*显示运行等待提示窗*/
	this.showRunningWnd = function (message) {
		var objDiv = document.getElementById("running_window");
		if (objDiv == null) {
			objDiv = document.createElement("iframe");
			objDiv.id = "running_window";
			objDiv.frameBorder = 0;
			objDiv.marginHeight = 0;
			objDiv.marginWidth = 0;
			objDiv.scrolling = "no";
			objDiv.className = "wnd_frame";
			document.body.appendChild(objDiv);
			if (message == null) {
				objDiv.src = GRootPath + "/netagent/pub/RunningWnd.htm";
			} else {
				objDiv.src = GRootPath + "/netagent/pub/RunningWnd.htm?" + message;
			}
		} else {
			document.frames("running_window").document.parentWindow.showRunningWnd(message);
			objDiv.style.display = "inline";
		}
	}
	/*停止并隐藏运行等待提示窗*/
	this.stopShowRunningWnd = function () {
		var objDiv = document.getElementById("running_window");
		if (objDiv != null) {
			document.frames("running_window").document.parentWindow.stopRunningWnd();
			objDiv.style.display = "none";
		}
	}

	/*对表单元素输入回车时视为按Tab键。*/
	this.enterToTab = function () {
		if (event.keyCode != 13) {
			return true;
		}
		if (event.keyCode == 13 && event.srcElement.tagName) {
			var obj = event.srcElement
			if (obj.tagName == "INPUT" && obj.type != "button" || obj.tagName == "SELECT") {
				event.keyCode=9;
			}
		}
		return true;
	}
	
	/*判断对象是否时表单输入控件。*/
	function isInputCtl(obj) {
		return (obj.tagName && (obj.tagName == "INPUT" || obj.tagName == "TEXTAREA" || obj.tagName == "SELECT"));
	}

	/*使指定元素所包含的所有表单元素有效(enabled)。*/
	this.enabledFormItem = function (element) {
		var items = element.all.tags("INPUT");
		var item = null;
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item.isDisabled) item.disabled = false;
		}
		items = element.all.tags("TEXTAREA");
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item.isDisabled) item.disabled = false;
		}
		items = element.all.tags("SELECT");
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item.isDisabled) item.disabled = false;
		}
	}

	/*使指定元素所包含的所有表单元素无效(disabled)或只读(readonly)。*/
	this.disabledFormItem = function (element) {
		var items = element.all.tags("INPUT");
		var item = null;
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item._canDisabled) continue;
		  //if (item.type == "text") {
			//	item.readOnly = true;
			//	continue;
			//}
			item.disabled = true;
		}
		items = element.all.tags("TEXTAREA");
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item._canDisabled) continue;
			item.disabled = true;
			//item.readOnly = true;
		}
		items = element.all.tags("SELECT");
		for (var i = 0, size = items.length; i < size; i++) {
			item = items[i];
		  if (item._canDisabled) continue;
			item.disabled = true;
		}
	}
	
	this.getRadioGroupValue = function (oRadioGroup) {
		if (oRadioGroup == null || !oRadioGroup.length) return null;
		for (var i = 0; i < oRadioGroup.length; i++) {
			if (oRadioGroup[i].checked) {
				return oRadioGroup[i].value;
			}
		}
		return null;
	}

	/*选择代码值及显示文本。若选择了代码，则更改传入对象的 value 为选择的值。
		传入代码值对象(或对象数组)、显示文本对象(或对象数组)，这两个对象(或对象数组元素)必须为表单对象。
		传入值既可是一个对象，也可是一个对象数组；若传入的是传入值对象数组，且传入了文本对象数组，则两者元素顺序应一致且元素一一对应；
		代码值对象(或对象数组第一个元素)必须指定 _codeid 或 name 属性（将作为查询代码表的标识），
		可以指定 _filter 属性（将作为查询代码表的过滤条件），
		可以指定 title 属性（将作为代码表的中文表名），*/
	this.selectCode = function(objCodes, objTexts) {
		if (objCodes == null || typeof(objCodes) != "object") return;
		
    var objCode = null;
    if (!objCodes.length || !objCodes.join) { // 代码值对象非数组
    	objCode = objCodes;
    } else {
    	if (typeof(objCodes[0]) == "undefined" || objCodes[0] == null) return;
    	objCode = objCodes[0];
    }
    
    var codeId = null;
    var oldCode = objCode.value;
    var titleStr = objCode.title;
    var filterStr = "";
    if (objCode._codeid) {
    	codeId = objCode._codeid;
    } else {
   		codeId = objCode.name;
    }
    if (objCode._filter) {
    	filterStr = objCode._filter;
    }
    
		var rtnValue = fnSelectCode(codeId, filterStr, oldCode, titleStr);
		if (rtnValue != null) {
			setObjSelectValue(objCodes, rtnValue[0]);
			if (objTexts != null) {
				setObjSelectValue(objTexts, rtnValue[1]);
			}
		}
	}
	
	function setObjSelectValue(objs, values) {
    if (objs == null) return;
		var obj = null;
		var isObjArray = false;
    if (!objs.length || !objs.join) { // 对象非数组
    	obj = objs;
    } else {
    	if (typeof(objs[0]) != "undefined") {
    		obj = objs[0];
    	}
    	isObjArray = true;
    }
 	 	if (!values.length || !values.join) { // 值非数组
 	 		if (obj != null) {
				obj.value = values;
			}
		} else {
			if (!isObjArray) { // 对象非数组, 值数组
	 	 		if (obj != null) {
	 	 			if (values.length == 0) { // 空数组
						obj.value = "";
					} else {
						obj.value = values[0];
					}
				}
			} else { // 对象数组, 值数组
				var valuesSize = objs.length;
				if (valuesSize > values.length) valuesSize = values.length;
				for (var i = 0; i < valuesSize; i++) {
					if (objs[i] != null) {
						objs[i].value = values[i];
					}
				}
				for (var i = valuesSize; i < objs.length; i++) {
					if (objs[i] != null) {
						objs[i].value = "";
					}
				}
			}
		}
	}

	function fnSelectCode(codeId, filterStr, oldCode, titleStr) {
		if (codeId == null || codeId == "") return null;
		var parameters = new Array();
		parameters[0] = GRootPath + "/netagent/pub/searchCode.jsp"; //  /MainSevlet?
		parameters[1] = codeId;
		parameters[2] = filterStr;
		parameters[3] = oldCode;
		parameters[4] = titleStr;
		var styleStr = "help:no;resizable:yes;scroll:no;status:no;";
		return showModalDialog('/NetAgentWeb/netagent/pub/selectDialog.jsp', parameters, styleStr);
	}
	
	/**打开一个全屏窗口。返回被打开的窗口。
		传入 url 路径、窗口标识名称(默认没有)。*/
	this.openFullWindow = function fnOpenFullWindow(urlStr, sName) {
		var newWindow = window.open(urlStr, sName, "fullscreen=yes");
		newWindow.focus();
		return newWindow;
	}

	/*居中打开一个新窗口。返回被打开的窗口。
		传入 url 路径、窗口标识名称(默认没有)、
		宽度(默认为屏幕的一般宽)、高度(默认为屏幕的一般宽)、
		是否允许调整大小(默认允许)、是否允许滚动(默认允许)、
		打开后是否立即将焦点转到新窗口(默认是)。*/
	this.openWindow = function fnOpenWindow(urlStr, sName, width, height,
			canResize, canScroll, setFocus) {
		if (!width || width < 1) {
			width = (screen.availWidth)/2;
		}if (!height || height < 1) {
			height = (screen.availHeight)/2;
		}
		var left = (screen.availWidth)/2 - width/2;
		var top = (screen.availHeight)/2 - height/2;
		var styleStr = 'toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=yes,width='
				+ width + ',height=' + height + ',left=' + left + ',top=' + top
				+ ',screenX=' + left + ',screenY=' + top;
		if (typeof(canResize) != "boolean" || canResize) {
			styleStr += ",resizable=yes";
		} else {
			styleStr += ",resizable=no";
		}
		if (typeof(canScroll) != "boolean" || canScroll) {
			styleStr += ",scrollbars=yes";
		} else {
			styleStr += ",scrollbars=no";
		}
		var newWindow = window.open(urlStr, sName, styleStr);
		newWindow.moveTo(left, top);
		newWindow.resizeTo(width, height)
		if (typeof(setFocus) != "boolean" || setFocus) {
			newWindow.focus();
		}
		return newWindow;
	}
	
	/*缩放弹出式窗口。返回缩放前窗口位置。
		传入缩放参数、原始大小窗口位置（可传入 null，表示）。
		缩放参数含义： -1、最小化；0、还原；1、最大化。
		窗口位置为数组型，数组元素对应窗口坐标体系参数，顺序对应 x坐标、y坐标、宽度、高度。
		原始大小窗口位置，若缩放参数是 0 还原时，可传入 null，表示当前窗口即原始大小窗口，一般用于首次显示窗口时。*/
  this.zoomDialog = function (zoomType, oldPos) {
	  if (oldPos == null || zoomType != 0
	  		&& ((parseInt(window.dialogWidth) < parseInt(screen.availWidth)-2)
	      || (parseInt(window.dialogHeight) < parseInt(screen.availHeight)-2))) {
	    if (oldPos == null) oldPos = new Array();
	    oldPos[0] = window.dialogLeft;
	    oldPos[1] = window.dialogTop;
	    oldPos[2] = window.dialogWidth;
	    oldPos[3] = window.dialogHeight;
	    if (zoomType == 0) return oldPos;
	  }
    if (zoomType == 0) {
      window.dialogWidth = oldPos[2];
      window.dialogHeight = oldPos[3];
      window.dialogLeft = oldPos[0];
      window.dialogTop = oldPos[1];
    } else {
	    if (zoomType > 0) {
	      window.dialogWidth = screen.availWidth + "px";
	      window.dialogHeight = screen.availHeight + "px";
	      window.dialogTop = "0px";
	    } else {
	      window.dialogWidth = "0px";
	      window.dialogHeight = "100px";
	      window.dialogTop = (screen.availHeight - 100) + "px";
	    }
	     window.dialogLeft = "0px";
    }
    return oldPos;
  }
	
	/*克隆源元素。返回新元素，如果失败，则返回 null。
		但只克隆源元素指定层次级数内的内部对象的方法(事件)，其它内部对象的方法可能丢失
		(一般如果源元素的 innerHTML 不包含方法定义，则会丢失)。
		传入源元素、最大层次级数。
		最大层次级数小于 0 表示克隆所有内部对象的方法，null 或 0 表示只克隆源元素的方法，
		1 表示源元素第一层内部子对象，依次类推*/
	this.cloneElement = function fnCloneElement(srcElement, maxLevel) {
		if (srcElement == null) return null;
		var newElement = srcElement.cloneNode(true);
		if (maxLevel == null) {
			 maxLevel = 0;
		} else if (maxLevel < 0) {
			maxLevel = null;
		}
		fnCloneAllMethods(srcElement, newElement, 0, maxLevel);
		return newElement;
	}
		//，源元素必须具有 outerHTML 属性  || !srcElement.outerHTML
		//var oDiv = document.createElement("DIV");
		//oDiv.innerHTML = srcElement.outerHTML;
		//if (!oDiv.children || oDiv.children.length == 0) return null;
		//var newElement = oDiv.children[0];
	
	/*将目标元素包含的所有内部对象清除后，替换为源元素包含的内部对象。返回成功与否。
		但只复制源元素指定层次级数内的内部对象的方法(事件)，其它内部对象的方法可能丢失
		(一般如果源元素的 innerHTML 不包含方法定义，则会丢失)。
		传入源元素、目标元素、最大层次级数。
		最大层次级数小于 0 表示复制所有内部对象的方法，null 或 0 表示只复制源元素第一层内部子对象的方法，
		1 表示源元素第二层内部子对象，依次类推*/
	this.replaceInnerObj = function fnInnerContent(srcElement, targetElement, maxLevel) {
		if (srcElement == null || targetElement == null) return false;
		targetElement.innerHTML = "";
		if (srcElement.childNodes) {
			var newNode = null;
			if (maxLevel == null) {
				 maxLevel = 0;
			} else if (maxLevel < 0) {
				maxLevel = null;
			}
			for (var i = 0, size = srcElement.childNodes.length; i < size; i++) {
				newNode = srcElement.childNodes[i].cloneNode(true);
				if (newNode == null) continue;
				targetElement.appendChild(newNode);
				fnCloneAllMethods(srcElement.childNodes[i], newNode, 0, maxLevel);
			}
		}
		return true;
	}
		//try {
		//targetElement.innerHTML = srcElement.innerHTML;
		//  htmla=srcElement.outerHTML + "  ****　　　 " + targetElement.outerHTML + "  ****　　　 ";
		
		/*} catch (error) {
			aerror = error;
			alert(error.name + "," + error.number + "," + error.message + ","+ error.description);
			alert(htmla+html);
		}*/
	/*
	var aerror = null;
	var htmla="";
	var html="";
	*/
	
	/*将源节点及其指定偏移级数范围内的所有子对象的方法克隆到目标节点及其对应子对象中，源节点树必须和目标节点树结构一致。
		传入源节点、目标节点、当前偏移级数、最大偏移级数。
		只要目标节点当前偏移级数小于最大偏移级数，则克隆其直接子对象的方法。*/
	function fnCloneAllMethods(srcNode, targetNode, curLevel, maxLevel) {
		fnCloneMethods(srcNode, targetNode);
		if (srcNode.childNodes && (curLevel < maxLevel || maxLevel == null)) {
			curLevel++;
			for (var i = 0, size = srcNode.childNodes.length; i < size; i++) {
				fnCloneAllMethods(srcNode.childNodes[i], targetNode.childNodes[i], curLevel, maxLevel);
			}
		}
	}
	/*将源节点的所有方法克隆到目标节点中。
		传入源节点、目标节点。*/
	this.cloneMethods = function fnCloneMethods(srcNode, targetNode) {
	  if (srcNode.attributes) {
		  var name = null;
		  var newValue = null;
		  var valueType = null;
			for (var i = 0, size = srcNode.attributes.length; i < size; i++) {
				name = srcNode.attributes[i].name;
				if (name == "dataFld" || name == "dataFormatAs" || name == "dataSrc") continue;
				newValue = srcNode.getAttribute(name);
			  valueType = typeof(newValue);
				if (valueType == "function") { // || valueType == "boolean" || valueType == "object") {
					targetNode.setAttribute(name, newValue);
				}
			}
		}
	}
		  //html=""
				//html += name + ",";
				//html += newValue + ",";
				//html += typeof(newValue) + ",";

	/*删除前导和尾随字符。返回结果字符串。
		传入待删除字符串、要匹配删除的字符（默认为空格）。*/
	this.trimStr = function fnTrimStr(inputString, removeChar) {
		var returnString = inputString;
		if (!removeChar) removeChar = " ";
		if (removeChar.length) {
			while(''+returnString.charAt(0)==removeChar) {
				returnString=returnString.substring(1,returnString.length);
			}
			while(''+returnString.charAt(returnString.length-1)==removeChar) {
				returnString=returnString.substring(0,returnString.length-1);
			}
		}
		return returnString;
	}
	

	/*检查指定元素所包含的所有表单元素值是否有效，若有效，则返回 true；
		若无效则返回 false, 返回前，将可能弹出一个错误定位窗口，
		以说明是哪些元素什么规则不符合，并可定位到含无效值的表单元素。
		表单元素可具有如下属性以用于校验，具体取值含义参见 validValue 方法：
		_minLen：值最小长度位数；_maxLen 或 maxLength：值最大长度位数；_type：值类型；
		
		_title：字段（名称）说明；_validLevel：校验级别（默认不定义为0级）。
		
		校验级别：若表单元素校验级别小于传入的指定元素的校验级别，则不校验此表单元素。
	 */
	this.validFormValue = function fnValidFormValue(element) {
		if (invalidObjWnd != null && !invalidObjWnd.closed) invalidObjWnd.close();
		invalidObjWnd = null;

	  var invalidObjAndTxt = new Array();
		var minValidLevel = 0;
		if (element._validLevel) minValidLevel = element._validLevel;
		
		var items = element.all.tags("INPUT");
		fnValidFormsCtlValue(items, invalidObjAndTxt, minValidLevel);
		items = element.all.tags("TEXTAREA");
		fnValidFormsCtlValue(items, invalidObjAndTxt, minValidLevel);
		items = element.all.tags("SELECT");
		fnValidFormsCtlValue(items, invalidObjAndTxt, minValidLevel);

		var invalidSize = invalidObjAndTxt.length;
	  var index = invalidSize;
	  var errTxt = "";
		var oPosObj = null;;
		var isSubmit = true;
		var validObjRtn;
		var validLevel = 0;
		items = element.all.tags("OBJECT_VALID"); // 对象校验方法标签
		for (var i = 0, size = items.length; i < size; i++) {
			if (items[i].isDisabled) continue;
			if (items[i]._validLevel) {
				validLevel = items[i]._validLevel;
			} else {
				validLevel = 0;
			}
			if (minValidLevel != null && minValidLevel > validLevel) continue;
			if (typeof(items[i].getAttribute("onvalid")) == "string") {  // 校验方法定义
				try {
					validObjRtn = eval(items[i].getAttribute("onvalid")); // 校验方法返回值为数组，首位表示是否继续提交，次位为错误信息。
					isSubmit &= validObjRtn[0];
				 	errTxt = validObjRtn[1];
				} catch (error) {
					continue;
				}
			} else {
				continue;
			}
			if (errTxt.length > 0) {
				invalidObjAndTxt[index] = new Array();
				oPosObj = null;
				if (typeof(items[i].getAttribute("posObjId")) == "string") { // 进行错误定位的对象ID
					oPosObj = document.getElementById(items[i].getAttribute("posObjId"));
				}
				if (oPosObj != null) {
					invalidObjAndTxt[index][0] = oPosObj;
				} else {
					invalidObjAndTxt[index][0] = "";
				}
				invalidObjAndTxt[index++][1] = errTxt;
			}
		}
		if (invalidSize > 0 || !isSubmit) {
			invalidObjWnd = window.showModelessDialog(GRootPath + "/netagent/pub/invalidObj.jsp", invalidObjAndTxt, "resizable:1;status:0;scroll:0");
		}
		return isSubmit && (invalidSize == 0);
	}
	var invalidObjWnd = null;
	
	function fnValidFormsCtlValue(items, invalidObjAndTxt, minValidLevel) {
	  var errTxt = "";
	  var index = invalidObjAndTxt.length;
		var oPosObj = null;;
		for (var i = 0, size = items.length; i < size; i++) {
			if (items[i].isDisabled) continue; //  || items[i].readOnly
			errTxt = fnValidObjValue(items[i], minValidLevel);
			if (errTxt.length > 0) {
				invalidObjAndTxt[index] = new Array();
				if (typeof(items[i].getAttribute("_posObjId")) == "string") { // 进行错误定位的对象ID
					oPosObj = document.getElementById(items[i].getAttribute("_posObjId"));
				} else {
					oPosObj = null;
				}
				if (oPosObj == null) {
					invalidObjAndTxt[index][0] = items[i];
				} else {
					invalidObjAndTxt[index][0] = oPosObj;
				}
				invalidObjAndTxt[index++][1] = errTxt;
			}
		}
	}

	/*检查指定元素其值是否有效，若有效，则返回空串；若无效将会返回信息串，以说明是什么规则不符合。
		元素必须具有 value 属性来存储值，并可具有如下属性以用于校验，具体取值含义参见 validValue 方法：
		_minLen：值最小长度位数；_maxLen 或 maxLength：值最大长度位数；_type：值类型；
		
		_title：字段（名称）说明；_validLevel：校验级别（默认不定义为0级）。
		
		校验级别：若传入的最小校验级别不为 null，且指定元素的校验级别小于最小校验级别，则不校验此元素，而直接返回空串。*/
	this.validObjValue = function fnValidObjValue(obj, minValidLevel) {
		var minLen = 0;
		var maxLen = 0;
		var valType = null;
		var nameMemo = null;
		var validLevel = 0;
		if (obj._validLevel) validLevel = obj._validLevel;
		if (minValidLevel != null && minValidLevel > validLevel) return "";
    if (obj._minLen) minLen = obj._minLen;
    if (obj._maxLen) {
	    maxLen = obj._maxLen;
	  } else if (obj.maxLength) {
	  	maxLen = obj.maxLength;
	  }
	  if (obj._type) valType = obj._type;
	  if (obj._title) nameMemo = obj._title;
		return fnValidValue(obj, minLen, maxLen, valType, nameMemo);
	}

	/*检测对象值是否符合指定规则。若符合，则返回空串；若不符合将会返回信息串，以说明是哪个字段什么规则不符合。
		传入参数为被检测的对象、值最小长度、值最大长度、值的类型、对象的中/英文名称（默认没有，不说明是哪个字段）；
		若最小长度和最大长度皆为 0，则表示不进行长度检测，
		若最小长度小于 1，则表示不检测最小长度，
		若最大长度小于 1，则表示不检测最大长度，
		值的类型若为 null，则表示不检测值的类型，类型为单字符，取值如下：
		9:数字型、a:从a至z的小写字母、A:从A至Z的大写字母、
		i:数字型和从a至z的小写字母、I:数字型和从A至Z的大写字母、
		k:数字型和从a至z的任意大小写字母、
		l:从a至z的任意大小写字母、 L:空格和从a至z的任意大小写字母、
		x:数字、空格和从a至z的任意大小写字母、X:任意单字符，包括数字、字母和常规符号（例如空格、@、#等）、
		e：Email 型、m：货币型
		*/
	this.validValue = function fnValidValue(obj, minLength, maxLength, valType, nameMemo) {
		if (minLength == 0 && maxLength == 0) return "";
		if (typeof(obj.value)=="undefined") return "";
		var newValue = obj.value;
		var newLength = 0;
		var hasDoubleChar = false;
		var msgStr = null;
		if(newValue != null) {
			switch (valType) {
				case 'e':
					if (minLength > 0 || newValue.length > 0) {
						if (newValue.isEmail()) {
							valType = 'X'; // 继续校验长度及是否含中文。
						} else {
							msgStr = "Email格式不正确！";
						}
					}
					break;
				case 'm':
					if (!isNaN(newValue)) {
						if (minLength <= newValue.length && maxLength > 0) {
							var pos = newValue.indexOf(".");
							if (pos > 0) {
								newValue = newValue.substring(0, pos);
							}
							newValue += ".00"; // 占两位小数位置
							obj.value = newValue;
						}
						valType = 'X'; // 继续校验长度及是否含中文。
					} else {
						msgStr = "不是数值格式！";
					}
					break;
			}
			var charCode;
			var isBegin = true;
			var spaceLen = 0;
			for (var i = 0, size = newValue.length; msgStr == null && i < size; i++) {
				charCode = newValue.charCodeAt(i);
				//if (charCode == 32) {
					// 首、尾空格不算作长度。
				//	if (!isBegin) spaceLen ++;
				//	continue;
				//}
				if (charCode < 256) {
					// 单字节
					if (fnValidCharType(charCode, valType, spaceLen)) {
						newLength ++;
					} else {
						// 不符合指定的值类型
						msgStr = "输入的字符必须是" + fnValTypeToStr(valType);
						break;
					}
				} else if (valType == null) {
					hasDoubleChar = true;
					newLength +=2;
				} else {
					// 不符合指定的值类型
					msgStr = "输入的字符不能为中文";
					break;
				}
				if (spaceLen != 0) {
					// 中间的空格算作长度。
					newLength += spaceLen;
					spaceLen = 0;
				}
				if (isBegin) isBegin = false;
			}
		}
		if (msgStr == null) {
			var noticeMsg = hasDoubleChar ? "！\n\r\n\r注意：每个汉字均占两个长度位数" : "";
			if (minLength > newLength) {
				if (minLength > 1) {
					msgStr = "的长度位数不能少于 " + minLength+" 位";
				} else {
					msgStr = "不能为空";
				}
			} else if (maxLength > 0 && maxLength	< newLength) {
				msgStr = "的长度位数不能超过 " + maxLength + noticeMsg;
			}
			if (msgStr != null) {
				if (minLength == maxLength) {
					msgStr = "的长度位数必须为 " + minLength + noticeMsg;
				}
				msgStr = "输入内容" + msgStr;
			}
		}
		if (msgStr != null) {
			if (nameMemo != null) {
				 msgStr = "“" + nameMemo + "”中" + msgStr;
			}
			return msgStr;
		}
		return "";
	}

	/*将值类型代码转换为中文说明字符串，私有方法。*/
	function fnValTypeToStr(valType) {
		switch (valType) {
			case '9':
				return "数字";
			case 'A':
				return "大写英文字母";
			case 'a':
				return "小写英文字母";
			case 'I':
				return "数字或大写英文字母";
			case 'i':
				return "数字或小写英文字母";
			case 'k':
				return "数字或英文字母";
			case 'l':
				return "英文字母";
			case 'L':
				return "空格或英文字母";
			case 'x':
				return "数字、空格或英文字母";
		}
	}

	/*检测单字节字符代码是否符合值类型要求，私有方法。符合则返回 true。
		传入参数为待检测字符、值类型（默认没有，符合）、其前导空格长度；
		值类型由下列定义的特殊字符以及其它非数字(9)、非字母(l)、非汉字的
		所有单字节符号(ASCII值小于128)组成，说明值必须属于这些类型所指定的范围：
		9：纯数字，即0、1、…、9
		a：纯小写字母，即a、b、…、z
		A：纯大写字母，即A、B、…、Z

		k：关键字(a、A、9)(l、9)(key)
		l：纯字母(a、A)(letter)
		m：金额(9、.、,)(money)
		n：名称(空格、.、_、-、a、A)(空格、.、_、-、l)(name)
		o：其它名称(空格、.、_、-、a、A、9)(n、9)(other)

		x：任意单字符（非双字节字符，如中文)（若指定，则不能再指定其它字符或符号）
		X: 任意字符（可为双字节字符的组成部分）（若指定，则不能再指定其它字符或符号）*/
	function fnValidChar(charCode, valType, spaceLen) {
		if (valType == null || valType == 'X') {
			return true;
		}
		var charType;
		if (charCode >= 48 && charCode <= 57) {
			charType = '9';
		} else if (charCode >= 65 && charCode <= 90) {
			charType = 'A';
		} else if (charCode >= 97 && charCode <= 122) {
			charType = 'a';
		} else {
			charType = 'X';
		}
		
		if (charCode >= 107 && charCode <= 111) {
			charType = 'k';
		}
	}

	/*检测单字节字符代码是否符合值类型要求，私有方法。符合则返回 true。*/
	function fnValidCharType(charCode, valType, spaceLen) {
		if (valType == null || valType == 'X') {
			return true;
		}
		var charType;
		if (charCode >= 48 && charCode <= 57) {
			charType = '9';
		} else if (charCode >= 65 && charCode <= 90) {
			charType = 'A';
		} else if (charCode >= 97 && charCode <= 122) {
			charType = 'a';
		} else {
			charType = 'X';
		}
		switch (valType) {
			case charType:
				if (spaceLen != 0) return false;
				break;
			case 'I':
				if (charType == '9' || charType == 'A') {
					if (spaceLen != 0) return false;
					break;
				}
				return false;
			case 'i':
				if (charType == '9' || charType == 'a')	{
					if (spaceLen != 0) return false;
					break;
				}
				return false;
			case 'k':
				if (charType == '9' || charType.toLowerCase() == 'a')	{
					if (spaceLen != 0) return false;
					break;
				}
				return false;
			case 'x':
				if (charType == '9') break;
			case 'L':
				if (charCode == 32) break;
			case 'l':
				if (charType.toLowerCase() != 'a') return false;
				if (spaceLen != 0 && valType == 'l') return false;
			default:
				return false;
		}
		return true;
	}
}

/* 校验字符串是否是 Email 地址。*/
String.prototype.isEmail = function() {
  var bIsOk = false;
	try {
		var xEmailAddress = /^[-_.\w]+@(((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))|(([-a-zA-Z0-9]+\.)+[a-zA-Z]{2,4}))$/;
		bIsOk = xEmailAddress.test(this);
	} catch (vError) {
	} finally {
		return bIsOk;
	}
}

/* 除去字符串首尾空格。可传入一位参数标识除去哪个部分的空格，参数取值如下：
	-1、除去首空格；0、除去首尾空格（默认）；1、除去尾空格。
	若参数值无效，则认为是传入 0。*/
String.prototype.trim = function() {
	var sTrimmedString = this;
	try {
		var iSide = 0;
		if (arguments.length > 0) {
			iSide = arguments[0];
		}
		if ((typeof iSide != 'number') || (iSide.toString().indexOf('.') != -1)) {
			iSide = 0;
		}
		if ((iSide != -1) && (iSide != 0) && (iSide != 1)) {
			iSide = 0;
		}
		switch (iSide) {
			case -1 : sTrimmedString = this.replace(/^\s*/, ''); break;
			case  1 : sTrimmedString = this.replace(/\s*$/, ''); break;
			case  0 :
			default : sTrimmedString = this.replace(/^\s*/, '').replace(/\s*$/, '');
		}
	} catch (vError) {
	} finally {
		return sTrimmedString;
	}
}