/** * 用于处理表单验证的JS文件 110609 注意:iframe默认是有最大的宽高限制的,要想iframe加载的页面较大时 * 也能自动调整大小,应该为iframe的css样式增加:width: 100%;height: 100%; 否则iframe大到一定程序就不能再大了 */ //var validationManagerPath = '/wd/js/validation'; function isMobile() { const screenWidth = (window !== window.top ? window.top : window).innerWidth <= 768; const userAgent = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); // 检测触摸支持 const hasTouchScreen = ( 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ); return hasTouchScreen && (userAgent || screenWidth); } // 为真,则在用户输入数据时实现进行检查 var realTimeCheck = true; var chartDiv; var validationTimeOutId = null; if (realTimeCheck) { // 如果需要在用户输入数据时实现进行检查,则把相应的iframe写入页面 /* * var divStr = '
'; var * topBody = top.document.getElementsByTagName('BODY')[0]; topBody.innerHTML = * divStr; */ // alert(window.top.document.getElementsByTagName("body")[0]); // document.write('
'); var topDoc = top.document; chartDiv = topDoc.getElementById("msgDiv"); if (chartDiv == null || typeof chartDiv == "undefined") { chartDiv = topDoc.createElement("div"); topDoc.body.appendChild(chartDiv); chartDiv.id = "msgDiv"; chartDiv.innerHTML += '
'; // chartDiv.innerHTML = '';//错误的 with (chartDiv.style) { zIndex = 65535; position = "absolute"; // background = '#F5F5F5'; width = "auto"; height = 0; top = -500; left = 0; // border = "1px solid"; display = "block"; style = "position:absolute;border-radius:3px;overflow:hidden;"; } } } // 保存校验结果的变量 var message = ""; function ValidationManager() { // 用于处理表单验证的工具类构造器 /** 保存所有要校验的信息的集合* */ this.validationInfos = []; } ValidationManager.MSG_TYPE_SUCCESS = 0; // 消息类型――正确 ValidationManager.MSG_TYPE_ERROR = 1; // 消息类型――错误 ValidationManager.MSG_TYPE_WARNING = 2; // 消息类型――警告 ValidationManager.prototype = { /** 用于显示表单验证结果的Div* */ MsgDiv: chartDiv, /** 如果为真,则如果代码报错会alert出来,在实际项目中应设为false* */ debug: true, /** 通过NAME或ID获得页面元素的通用方法* */ getElement: function (nameOrId) { var rs = document.getElementById(nameOrId); if (!rs) { // 如果上面的方法失败,则采用下面的方法取得对象实例 var arr = document.getElementsByName(nameOrId); if (arr != null) rs = arr[0]; } console.log(rs); return rs; }, getElements: function (nameOrId) { var rs = new Array(); var ele = document.getElementById(nameOrId); if (!ele) { // 如果上面的方法失败,则采用下面的方法取得对象实例 var arr = document.getElementsByName(nameOrId); if (arr != null) { for (var i = 0; i < arr.length; i++) { rs.push(arr[i]); } } } else { rs.push(ele); } // console.log(rs) return rs; }, /** 获取参数s指定的方法引用* */ getFunRef: function (s) { if (!s) return null; try { var r = eval(s); } catch (e) { //alert("方法不存在 :"+s) console.log("方法不存在 :" + s); } return r; }, /** * 为DOM元素targetElem的evenName事件追加事件触发时回调函数activeFun * 通过此函数为DOM元素绑定监听事件的好处在于:可以把新添加的监听函数与DOM元素 * 已绑定的旧的监听函数合并成为新的监听函数,而不会覆盖DOM元素旧的同名监听函数。 */ addEventListener: function ( targetElem, // 需绑定监听事件的DOM元素 eventName, // 事件名称,如:onclick activeFun ) { // 事件触发的回调函数 // DOM元素原来的监听事件 var oriListener = targetElem[eventName]; if (oriListener) { // 如果原来已经存在同名的监听事件了 targetElem[eventName] = function () { oriListener.call(targetElem); // 调用原来已经存在监听方法 activeFun.call(targetElem); // 调用新添加的监听方法 }; } else { targetElem[eventName] = function () { activeFun.call(targetElem); // 调用新添加的监听方法 }; } }, /** 当前页面的第一个FORM元素* */ form: null, /** 用于显示表单验证结果的iframe的Id或Name* */ MsgIframeIdorName: "msgIframe", /** 用于显示表单验证结果的div的Id或Name* */ MsgDivIdorName: "msgDiv", /** 用于显示表单验证结果的iframe* */ MsgIframe: null, /** 已经初始化成功* */ initOk: false, /** * 如果表单存在,则为表单绑定onsubmit校验事件 * * @param {} * targetForm 需要校验的FORM的name或者ID * @return {Boolean} 返回校验结果,为真则校验通过 */ checkForm: function (targetForm) { try { var THIS = this; if (!targetForm) { // 如果目标form不存在 //alert('checkForm方法执行出错,参数不能为空!'); console.log("checkForm方法执行出错,参数不能为空!"); return; } if ((typeof targetForm).toUpperCase() == "STRING") // 如果输入的是FORM的name或者ID var targetForm = this.getElement(targetForm); if (!targetForm.validationManager) { // 如果FORM中没校验器,则添加一个校验器 targetForm.validationManager = this; var activeFun = function (showerror) { // 为表单绑定onsubmit事件 try { if (window.beforeBatchSubmit) { window.beforeBatchSubmit(); } } catch (e) { console.log(e); } var rsArr = targetForm.validationManager.checkAll( targetForm.validationManager.validationInfos ); console.log(rsArr) var totalMsg = ""; // 保存校验显示的消息 for (var i = 0; i < rsArr.length; i++) { var rs = rsArr[i]; var msg = rs.msg; var regExp = /[\n\r]+$/; // 测试校验结果结尾有没有换行符的正则表达式 var hasLineBreak; // 有换行符 hasLineBreak = regExp.test(msg); // if(hasLineBreak)//如果有换行符 // totalMsg+=msg; // else totalMsg += msg + "
"; } if (totalMsg) { // 如果校验不通过 if (showerror == false) return false; //如果不显示错误 try { var windowId = new Date().getTime(); var width = 400; var high = 400; // wd.topWindow.dhxWins.enableAutoViewport(true);//让窗口大小自动适应内容 var w = wd.topWindow.dhxWins.createWindow( windowId, 0, 0, width, high ); //----------------加遮罩层开始 ---------------- if (!wd.topWindow.wd.display.wdDialogOpeners) { wd.topWindow.wd.display.wdDialogOpeners = {}; } var wdDialogId = windowId; wd.topWindow.wd.display.wdDialogOpeners[wdDialogId] = window; var containerObj = wd.topWindow.wd.display; if (wd.topWindow.document.querySelector("#validationTotalMsg")) { wd.topWindow.document .querySelector("#validationTotalMsg") .close(); } //----------------加遮罩层结束 ---------------- w.keepInViewport(true); // 保持在窗口内 w.center(); // 居中 var title = "录入数据错误"; w.setText(title); // 设置窗口标题 w.setModal(true); // 设置模式窗口 w.bringToTop(); // 置顶 // 隐藏不需要的按钮 // alert(document.getElementById("mainContainer")==wd.topWindow.document.body); if (w.button("help")) w.button("help").hide(); if (w.button("stick")) w.button("stick").hide(); if (w.button("sticked")) w.button("sticked").hide(); if (w.button("park")) w.button("park").hide(); if (w.button("minmax1")) // 隐藏最大化按钮 w.button("minmax1").hide(); w.denyResize(); // 不允许改变大小 var innerDiv = '
' + totalMsg + '
'; w.attachHTMLString(innerDiv); w.setAttribute("id", "validationTotalMsg"); var currentDialogZIndex = w.zi; // 弹出窗口的z-index wd.display.dxwindowsCreateMaskDiv(currentDialogZIndex); w.attachEvent("onClose", function (win) { wd.display.dxwindowsCloseMaskDiv(); //关闭wddialog时,移除遮罩层 return true; }); try { wd.display.initStyleWdButtons(); $(w).on("click", "#closeButton", function () { w.close(); }); } catch (e) { console.log(e); } var divArr = wd.topWindow.document.querySelectorAll("[ida=dhxMainCont]"); for (var i = 0; i < divArr.length; i++) { divArr[i].style.backgroundColor = ""; } } catch (e) { //alert(totalMsg);// 弹出校验结果 } THIS.hideMsgDiv(); return false; } else return true; }; //end function //如果用户直接调用form的submit方法,则校验不会生效。因此,这里覆盖原来form的submit方法\ targetForm.oriSubmit = targetForm.submit; targetForm.checkOnly = function (boo) { boo = typeof boo == "undefined" ? true : boo; // !(boo == null ? true : boo); return activeFun(boo); }; targetForm.submit = function () { if (activeFun()) targetForm.oriSubmit(); }; wd.c.addEventListener( targetForm, //需绑定监听事件的DOM元素 "onsubmit", //事件名称,如:onclick activeFun ); } } catch (e) { if (this.debug) //alert('方法checkForm执行异常:'+e); console.log("方法checkForm执行异常:" + e); } }, /** 如果为真则自动为当前页面的第一个表单绑定onsubmit校验事件* */ formAutoCheck: true, /** 初始化变量的方法,只需执行一次* */ init: function () { try { if (this.initOk) return; // 如果已经初始化过了,就返回。 if (!this.MsgIframe) this.MsgIframe = this.getElement(this.MsgIframeIdorName); if (!this.MsgDiv) this.MsgDiv = this.getElement(this.MsgDivIdorName); if (this.formAutoCheck) { // var forms = document.getElementsByTagName('form'); var forms = $("form:visible"); //过滤隐藏form this.form = forms[forms.length - 1]; // 当前页面的第一个FORM元素 if (this.form) { // 如果表单存在,则为表单绑定onsubmit事件 this.checkForm(this.form); } } this.initOk = true; } catch (e) { if (this.debug) //alert('方法init执行异常:'+e); console.log("方法init执行异常:" + e); } }, /** 设定显示表单验证结果的iframe的显示内容* */ setMsg: function (rsArr) { // try{ // 调用iframe中的方法,设置表单验证结果的iframe的显示内容 if (!rsArr || rsArr.length == 0) return; // console.log(rsArr) //this.MsgDiv.firstChild.innerHTML = rsArr[0].msg + "
"; this.MsgDiv.querySelector(".msgDiv-content").innerHTML = rsArr[0].msg; // 暂时隐藏20181128 // window.top.frames[this.MsgIframeIdorName].setMsg(rsArr); // alert(document.frames.length); // }catch(e){ // if(this.debug) // alert('方法setMsg执行异常:'+e.message); // } }, /** * 返回传入对象e的绝对坐标,并作为一个对象返回 * * @param {} * e * @return {"x": x, "y": y} */ getAbsPoint: function (e) { try { var x = e.offsetLeft; var y = e.offsetTop; var w = e.offsetWidth; var h = e.offsetHeight; /** * OffsetParent为从中计算偏移量的元素。 如果某个元素的父级或此元素层次结构中的其他元素使用相对或绝对定位, 则 OffsetParent * 将成为当前元素嵌套到的第一个相对或绝对定位元素。如果当前元素以上的任何元素都不是绝对 或相对定位的,则 OffsetParent 将是文档的 * BODY 标记。 * * obj.offsetTop 指 obj 距离上方或上层控件的位置,整型,单位像素。 obj.offsetLeft 指 obj * 距离左方或上层控件的位置,整型,单位像素。 * * offsetTop与offsetLeft均为相对偏移量,但是下面不断地拿offsetParent的偏移量来累加, * 直至拿到offsetParent为body之后,就没有offsetParent了,此时循环才终止。 * 最终计算出来的x,y为e相对body的绝对坐标。 */ while ((e = e.offsetParent)) { // 只要对象的offsetParent存在,则继续累加XY, x += e.offsetLeft; y += e.offsetTop; } return { x: x, y: y, w: w, h: h, }; } catch (e) { if (this.debug) //alert('方法getAbsPoint执行异常:'+e); console.log("方法getAbsPoint执行异常:" + e); } }, /** * refleshIframeFun:function(){ if(!this.hasRefleshedIframe){ * document.getElementById("validationDiv").innerHTML=''; this.hasRefleshedIframe = true; } }, */ /** * MsgDiv定位于要校验的目标input元素的上方 * * @param {} * targetInput 要校验的目标input元素 */ showMsgDiv: function (targetInput, msg) { try { wd.flashMsg.show({ el: targetInput, // 吸附的元素 msg: msg, // 内容 animate: false, }); } catch (e) { console.log(e); } if (true) return; // try{ // this.refleshIframeFun(); var win = window; var xy = this.recursionIframe(win); // var inputElem = document.getElementsByName(targetInput.name)[0]; var offset = this.getInputOffset(targetInput, true); var height = this.MsgDiv.offsetHeight; this.MsgDiv.style.left = xy.x + offset.left + "px"; var tailDiv = this.MsgDiv.querySelector(".msgDiv-tail"); var msgtop; if (offset.top < window.innerHeight / 2) { //录入框下方,尾巴向上 msgtop = xy.y + offset.top + 38 + "px"; tailDiv.setAttribute("class", "msgDiv-tail flashMsg-up"); } else { //录入框上方,尾巴向下 msgtop = xy.y + offset.top - height - 38 + "px"; tailDiv.setAttribute("class", "msgDiv-tail flashMsg-down"); } this.MsgDiv.style.top = msgtop; // 调用隐藏的方法,让tips在3s后隐藏 var dom = this.MsgDiv; function hideDom(dom) { dom.style.top = "-500px"; } if (validationTimeOutId) clearTimeout(validationTimeOutId); validationTimeOutId = setTimeout(function () { hideDom(dom); }, 3000); /** * }catch(e){ if(this.debug) alert('方法执行异常:'+e); } */ }, /** * 获取输入光标在页面中的坐标 【..】 * * @param {HTMLElement} * 输入框元素 * @param {Boolean} * 返回焦点光标顶部的top值(默认false) * @return {Object} 返回left和top */ getInputOffset: function (elem, focusTop) { var that = this, cloneDiv = "{$clone_div}", cloneLeft = "{$cloneLeft}", cloneFocus = "{$cloneFocus}", cloneRight = "{$cloneRight}", none = ' ', div = elem[cloneDiv] || document.createElement("div"), left = elem[cloneLeft] || document.createElement("span"), focus = elem[cloneFocus] || document.createElement("span"), right = elem[cloneRight] || document.createElement("span"), offset = that._offset(elem), index = this._getFocus(elem), focusOffset = { left: 0, top: 0, }; div.style.width = this._getStyle(elem, "width"); div.style.height = this._getStyle(elem, "height"); try { div.scrollLeft = elem.scrollLeft; div.scrollTop = elem.scrollTop; } catch (e) {} // IE8 left.innerHTML = ((elem.value && elem.value.substring(0, index)) || "") .replace(//g, ">") .replace(/\n/g, "
") .replace(/\s/g, none); right.innerHTML = ( (elem.value && elem.value.substring(index, elem.value.length)) || "" ) .replace(//g, ">") .replace(/\n/g, "
") .replace(/\s/g, none); focus.style.display = "inline-block"; try { focusOffset = this._offset(focus); } catch (e) {} focus.style.display = "none"; return { left: offset.left + focusOffset.left, top: offset.top + focusOffset.top + (focusTop ? focus.offsetHeight : 0), }; }, // 获取元素在页面中位置 _offset: function (elem) { var box = elem.getBoundingClientRect(); var doc = elem.ownerDocument; var body = doc.body; var docElem = doc.documentElement; var clientTop = docElem.clientTop || body.clientTop || 0; var clientLeft = docElem.clientLeft || body.clientLeft || 0; var top = box.top + (self.pageYOffset || docElem.scrollTop) - clientTop; var left = box.left + (self.pageXOffset || docElem.scrollLeft) - clientLeft; return { left: left, top: top, }; }, // 获取光标在文本框的位置 _getFocus: function (elem) { var index = 0; if (elem.nodeName === "TEXTAREA") { if (document.selection) { // IE Support elem.focus(); var Sel = document.selection.createRange(); var Sel2 = Sel.duplicate(); Sel2.moveToElementText(elem); var index = -1; while (Sel2.inRange(Sel)) { Sel2.moveStart("character"); index++; } } else if (elem.selectionStart || elem.selectionStart == "0") { // Firefox // support index = elem.selectionStart; } return index; } else { // input if (document.selection) { // IE Support elem.focus(); var Sel = document.selection.createRange(); Sel.moveStart("character", -elem.value.length); index = Sel.text.length; } else if (elem.selectionStart || elem.selectionStart == "0") { // Firefox // support index = elem.selectionStart; } return index; } }, // 获取最终样式 _getStyle: "getComputedStyle" in window ? function (elem, name) { return getComputedStyle(elem, null)[name]; } : function (elem, name) { return elem.currentStyle[name]; }, /** 隐藏MsgDiv的方法* */ hideMsgDiv: function () { // try{ // this.MsgDiv.style.top = "-500px"; /** * }catch(e){ if(this.debug) alert('方法showMsgD\niv执行异常:'+e); } */ try { wd.flashMsg.clear(); } catch (e) { console.log(e); } }, /** * 为指定的input元素绑定校验方法的公共方法 */ initInput: function (validationInfo) { try { this.init(); // 初始化变量的方法 this.validationInfos.push(validationInfo); for (var i = 0; i < validationInfo.formElems.length; i++) { // 被校验的表单元素 var targetInput = validationInfo.formElems[i]; // 保存校验信息到表单元素中 if (!targetInput.validationInfos) { targetInput.validationInfos = []; } targetInput.validationInfos.push(validationInfo); // console.log(targetInput.validationInfos) /** 保存原来的borderBottomColor* */ if (targetInput.style.borderBottomColor) targetInput.oldBorderColor = targetInput.style.borderBottomColor; else targetInput.oldBorderColor = "default"; targetInput.validationManager = this; // $(targetInput).addClass("validation-"+targetInput.tagName.toLowerCase()); $(targetInput).addClass("border-" + targetInput.tagName.toLowerCase()); if (realTimeCheck) { // 如果要进行实时检查 var activeFun = function () { //if(this.value!==''&&this.value!==null){ this.validationManager.checkForRealTime(this); // 检查目标input元素的值 /* }else{ this.style.borderBottomColor='';//清空则去掉红框 this.validationManager.hideMsgDiv();// 隐藏MsgDiv } */ // targetInput.style.borderBottomColor="blue" }; /** 为要校验的input元素绑定获得焦点事件* */ this.addEventListener( targetInput, // 需绑定监听事件的DOM元素 "onfocus", // 事件名称,如:onclick activeFun ); // 事件触发的回调函数 this.mouseoverEvent(targetInput, activeFun); /** 为要校验的input元素绑定失去焦点事件* */ var onblurFun = function () { // 隐藏MsgDiv 暂时去掉20181128 // this.validationManager.hideMsgDiv(); // targetInput.style.borderBottomColor="" }; this.addEventListener( targetInput, // 需绑定监听事件的DOM元素 "onblur", // 事件名称,如:onclick onblurFun ); // 事件触发的回调函数 //初始化ueditor的校验事件 if ( typeof EditorManager != "undefined" && EditorManager && (validationInfo.argsObj.isUeditor == true || validationInfo.argsObj.isUeditor == "true") ) { var vmr = this; window.ueCallback = window.ueCallback || []; var name = validationInfo.argsObj.editorName; window.ueCallback[name] = window.ueCallback[name] || []; window.ueCallback[name].push(function () { EditorManager.getWDEditor(validationInfo.argsObj.editorName) .getUeditor() .addListener("selectionchange", function () { // vmr.addEventListener(targetInput, // 需绑定监听事件的DOM元素 // 'onblur', // 事件名称,如:onclick // onblurFun); // vmr.addEventListener(targetInput, // 需绑定监听事件的DOM元素 // 'onfocus', // 事件名称,如:onclick // activeFun); // 事件触发的回调函数 var iframe_ = EditorManager.getEditorFrame(name); iframe_.validationInfo = targetInput.validationInfo; iframe_.validationInfos = targetInput.validationInfos; iframe_.validationManager = targetInput.validationManager; onblurFun.call(iframe_); activeFun.call(iframe_); }); }); } // if(targetInput.tagName.toUpperCase()=='SELECT'){// 如果要校验的不是select元素 // /** 为要校验的input元素绑定键盘点击事件* */ // this.addEventListener(targetInput,// 需绑定监听事件的DOM元素 // 'onkeyup',// 事件名称,如:onclick // activeFun);// 事件触发的回调函数 // }else{ // // /** 为要校验的input元素绑定键盘点击事件* */ // this.addEventListener(targetInput,// 需绑定监听事件的DOM元素 // 'onchange',// 事件名称,如:onclick // activeFun);// 事件触发的回调函数 // } var eventType = null; //选择合适的时间为元素绑定 //select if (targetInput.tagName == "SELECT") { eventType = "onchange"; //input } else if ( targetInput.tagName == "INPUT" || targetInput.tagName == "TEXTAREA" ) { eventType = "onkeyup"; if (targetInput.type == "button") { eventType = "onclick"; } //button } else if (targetInput.tagName == "button") { eventType = "onclick"; } if (eventType == null) { console.log(targetInput); console.log("元素不支检验"); //alert("元素不支检验") return; } //为元素绑定即时校验事件 this.addEventListener( targetInput, // 需绑定监听事件的DOM元素 eventType, // 事件名称,如:onclick activeFun ); // 事件触发的回调函数 } } // for //预校验,不用等到提交表单才校验 By Rd 2015-11-12 this.checkAll(targetInput.validationInfos); // this.MsgDiv.style.top = "-500px" this.hideMsgDiv(); } catch (e) { console.log(e); if (this.debug) //alert('方法initInput执行异常:'+e); console.error("方法initInput执行异常:" + e); } }, /** * 为指定的表单元素绑定校验方法 */ add: function ( validatorStr, // 内容为校验方法全路径的字符串 formElems, // 被校验的表单元素的name或id argsObj, // 内容为当前校验器使用的参数组成的关联数组 type ) { // 校验结果严重等级 try { if (!type) type = ValidationManager.MSG_TYPE_ERROR; var validationInfo = {}; // 保存一次校验所需信息的集合 validationInfo.funRef = this.getFunRef(validatorStr); // 校验器方法引用 validationInfo.argsObj = argsObj; // 内容为当前校验器使用的参数组成的关联数组 validationInfo.type = type; // 校验结果严重等级 validationInfo.formElems = []; // 被校验的表单元素 validationInfo.isNull = function () { return this.formElems[0].value ? false : true; }; // validationInfo.formElems=this.getElements(eName); //查找表单元素 for (var i = 0; i < formElems.length; i++) { var eName = formElems[i]; if (window.growHeightList && window.growHeightList[eName]) { var gh = window.growHeightList[eName]; var elems = [gh.getInputElement()]; if (elems) validationInfo.formElems = validationInfo.formElems.concat(elems); } else { var elems = this.getElements(eName); if (elems) validationInfo.formElems = validationInfo.formElems.concat(elems); } } //bmxy1.xy //批量录入 if (formElems[0].split(/\./).length == 2) { argsObj["namePrefix"] = formElems[0].split(/\./)[0] + "."; } else { argsObj["namePrefix"] = ""; } validationInfo.name = formElems[0]; // console.log(validationInfo) //只有找到对应表单元素时才绑定校验方法 张敏聪2015-10-30 if (validationInfo.formElems.length > 0) { // 为指定的input元素绑定校验方法的公共方法 this.initInput(validationInfo); } } catch (e) { if (this.debug) console.log("方法add执行异常:" + e); //alert('方法add执行异常:'+e); } }, remove: function ( validatorStr, // 校验器方法的全路径字符串 formElems // 需要移除校验的表单元素的 name 或 id ) { try { // 获取校验方法引用 var validationInfo = { funRef: this.getFunRef(validatorStr), formElems: [] }; // 查找表单元素 for (var i = 0; i < formElems.length; i++) { var eName = formElems[i]; var elems = this.getElements(eName); if (elems) { validationInfo.formElems = validationInfo.formElems.concat(elems); } } // 如果找到了对应的表单元素 if (validationInfo.formElems.length > 0) { for (var j = 0; j < validationInfo.formElems.length; j++) { var elem = validationInfo.formElems[j]; // 1. 移除所有校验相关事件绑定 $(elem).off('input.validation keyup.validation change.validation focus.validation blur.validation'); // 2. 移除校验提示信息(如错误消息) $(elem).removeClass('validation-error'); // 移除错误样式 $(elem).next('.validation-error-msg').remove(); // 移除错误提示信息 // 3. 恢复原始样式(例如,边框颜色) if (elem.oldBorderColor) { elem.style.borderBottomColor = elem.oldBorderColor; } else { elem.style.borderBottomColor = ''; // 如果没有保存原始样式,使用默认样式 } // 4. 移除与必填项标记 `span` 无关的样式 var spanId = elem.name + "Span"; // 拼接出对应的 span id,例如 "jfrxmSpan" var spanElem = document.getElementById(spanId); if (spanElem) { spanElem.remove(); // 直接删除这个 span 元素 } // 5. 移除校验信息缓存 this.validationInfos = this.validationInfos.filter(function(info) { return info.funRef !== validationInfo.funRef || !info.formElems.some(elem => validationInfo.formElems.includes(elem)); }); // 6. 清理校验信息缓存 if (elem.validationInfos) { elem.validationInfos = elem.validationInfos.filter(function(info) { return info.funRef !== validationInfo.funRef; }); } } } } catch (e) { if (this.debug) console.log("方法 remove 执行异常: " + e); } } , /** * 执行一次校验 * * @param {} * validationInfo 保存一次校验的配置的对象 * 单个校验 */ check: function (validationInfo, targetinput) { var rs = {}; // 保存校验结果的对象 var funRef = validationInfo.funRef; // 校验器方法引用 var argsObj = validationInfo.argsObj; // 内容为当前校验器使用的参数组成的关联数组 var type = validationInfo.type; // 校验结果严重等级 // console.log(targetinput.validationInfos) var funArgs = []; //2017-12-4 zhangmincong radio判断 // if (targetinput.type && 'radio|checkbox'.indexOf(targetinput.type.toLowerCase()) > -1) { // var rdos = document.querySelectorAll("[type='" + targetinput.type + "'][name='" + targetinput.name + "']"), // value; // console.log(rdos) // for (var i = 0; i < rdos.length; i++) { // console.log(rdos[i].checked) // if (rdos[i].checked == true) { // value = rdos[i].value; // break; // } // } // funArgs.push([value]); // } else if ((typeof EditorManager != "undefined") && (argsObj.isUeditor == true || argsObj.isUeditor == "true")) { // if (EditorManager.getWDEditor(argsObj.editorName)) { // var value = EditorManager.getWDEditor(argsObj.editorName).getUeditor().getContent(); // value = wd.display.toPlainText(value); // // console.log("ueditorValue:"+value); // funArgs.push([value]); // } // } else if (targetinput.tagName == "DIV") { // funArgs.push([targetinput.innerHTML]) // } else if (targetinput.GrowHeight) { // funArgs.push([targetinput.GrowHeight.val()]); // } else { // funArgs.push([targetinput.value]) // } // console.log(targetinput); // funArgs.push(argsObj) // var win = window; // var xy = this.recursionIframe(win); // 调用校验器进行校验 var msg; try { // msg = funRef.apply(window, funArgs); //校验器获取根据name获得其他录入 var environment = { argsObj: argsObj, getElementValue: function (name) { //单个或 批量 取值 var n = this.argsObj.namePrefix + name; //id查找 var ele = document.querySelector("input[id='" + n + "']"); if (ele) return ele.value; //name查找 var box = wd.display.getInputBox(n, true); return box ? box.getValue() : null; }, setElementValue: function (name, value) { //单个或 批量 设值.....自动填写性别、出生地区、出生日期 var n = this.argsObj.namePrefix + name; //name查找 var box = wd.display.getInputBox(n, true); if (!box) { console.log("set value fail:" + n); return; } box.setValue(value); }, modify: function (names, canModify) { //names:["xm","xbm"] 录入可修改,不可修改 for (var i = 0; i < names.length; i++) { var n = this.argsObj.namePrefix + names[i]; var box = wd.display.getInputBox(n); if (box) { box.modify(canModify); } } }, }; var vbox = wd.display.getInputBox(validationInfo.name, true); var vv = vbox ? vbox.getValue() : ""; funArgs.push([vv]); funArgs.push(argsObj); msg = funRef.apply(environment, funArgs); } catch (e) { console.error(e); msg = "校验方法错误:" + validationInfo.funRef; } // 保存校验信息 rs.msg = msg; rs.formElems = [targetinput]; if (msg) // 如果校验不通过 rs.type = type; else rs.type = ValidationManager.MSG_TYPE_SUCCESS; // console.log(rs); return rs; }, checks: function (validationInfo, targetInput) { var result = []; if (targetInput) { var elem = targetInput; var rs = this.check(validationInfo, elem); //校验未通过 if (rs.msg && rs.msg.length > 0) { result.push(rs); elem.style.borderBottomColor = "red"; } else { //通过 this.hideMsgDiv(); // 如果运行到这里证明校验通过 if (elem.oldBorderColor == "default") elem.style.borderBottomColor = ""; else elem.style.borderBottomColor = elem.oldBorderColor; } } else { for (var i = 0; i < validationInfo.formElems.length; i++) { var elem = validationInfo.formElems[i]; var rs = this.check(validationInfo, elem); // console.log(rs.msg) //校验未通过 if (rs.msg && rs.msg.length > 0) { result.push(rs); elem.style.borderBottomColor = "red"; } else { //通过 this.hideMsgDiv(); // 如果运行到这里证明校验通过 if (elem.oldBorderColor == "default") elem.style.borderBottomColor = ""; else elem.style.borderBottomColor = elem.oldBorderColor; } } } return result; }, checkInput: function (targetinput) { var result = []; // targetinput里存有校验器 if (targetinput.validationInfos) { var validationInfos = targetinput.validationInfos; for (var i = 0; i < validationInfos.length; i++) { var elem = targetinput; var rs = this.check(validationInfos[i], elem); //校验未通过 if (rs.msg && rs.msg.length > 0) { result.push(rs); // elem.style.borderBottomColor='red'; } else { //通过 // this.hideMsgDiv() // // 如果运行到这里证明校验通过 // if(elem.oldBorderColor=='default') // elem.style.borderBottomColor=''; // else // elem.style.borderBottomColor=elem.oldBorderColor; } } } return result; }, /** * 对数组中消息进行排序。 */ sortRs: function (a, b) { if (!a || !b) return -1; var typeA = a.type; var typeB = b.type; if (typeB == ValidationManager.MSG_TYPE_ERROR) { return 1; } else return -1; }, /** * 获取表单元素的名字或ID */ getNameOrId: function (formElem) { if (formElem.name) return formElem.name; else return formElem.id; }, /** * 为保存到数组rsArr的消息,添加前缀。 */ addMsgPrefix: function (rsArr) { for (var i = 0; i < rsArr.length; i++) { var rs = rsArr[i]; var prefix; if (rs.type == ValidationManager.MSG_TYPE_SUCCESS) { prefix = "正确:"; } else if (rs.type == ValidationManager.MSG_TYPE_ERROR) { prefix = "错误:"; } else if (rs.type == ValidationManager.MSG_TYPE_WARNING) { prefix = "警告:"; } rs.msg = prefix + rs.msg; console.log(rs); } }, /** * 检查所有要校验的input元素,并返回校验失败的结果 */ checkAll: function (validationInfos, targetInput) { var rsArr = []; // 返回的校验结果 var allFormElems = []; // 保存所有要校验的表单元素 var errFormElems = {}; // 所有校验不通过的表单元素 for (var i = 0; i < validationInfos.length; i++) { // 一个校验信息 var validationInfo = validationInfos[i]; /** * 校验并获得校验结果 rs.msg = msg; rs.type = type; rs.formElems = formElems; */ for (var j = 0; j < validationInfo.formElems.length; j++) { var elem = validationInfo.formElems[j]; var rs = this.check(validationInfo, elem); // console.log(rs.msg) //校验未通过 if (rs.msg && rs.msg.length > 0) rsArr.push(rs); this.via(elem, rs.msg); // if (rs.msg && rs.msg.length > 0) { // rsArr.push(rs) // elem.style.borderBottomColor = 'red'; // this.checkObjectPicker(elem,rs.msg); // } else { //通过 // // // 如果运行到这里证明校验通过 // if (elem.oldBorderColor == 'default') // elem.style.borderBottomColor = ''; // else // elem.style.borderBottomColor = elem.oldBorderColor; // // this.checkObjectPicker(elem); // this.hideMsgDiv() // } } } // 对消息进行排序 // rsArr.sort(this.sortRs); // 为保存到数组rsArr的消息,添加前缀。 // this.addMsgPrefix(rsArr); // console.log(rsArr) return rsArr; }, /** * 如果校验通过,返回true */ passValidation: function (rsArr) { var rs = true; if (rsArr && rsArr.length > 0) rs = false; return rs; }, /** * 实时校验的方法 * * @param {} * targetInput目标input元素 */ checkForRealTime: function (targetInput) { // try{ if (window.event && "focus" == window.event.type) { // this.MsgDiv.style.top = "-500px" this.hideMsgDiv(); return; } // 获得当前表单元素校验不通过的消息集 var rsArr = this.checkInput(targetInput); var isnullFunction = false; // if(targetInput.validationInfos&&targetInput.validationInfos.length==1){ //// console.log(targetInput.validationInfos[0].funRef==wd.commonValidator.notNull) // isnullFunction=(targetInput.validationInfos[0].funRef==wd.commonValidator.notNull) // } // isnullFunction = !$(targetInput).val() // 去掉,导致鼠标进入时不显示错误信息 -- 不知干啥用???Lin // console.log(targetInput.validationInfos); if (window.event) { if (window.event.type == "keyup") isnullFunction = false; } if (!isnullFunction) this.setMsg(rsArr); // 设定显示表单验证结果的iframe的显示内容 // console.log(rsArr); this.via(targetInput, rsArr, isnullFunction); //console.log(targetInput) // 校验不通过,显示校验信息 // if (!this.passValidation(rsArr)) { //// this.checkObjectPicker(targetInput,rsArr); //// targetInput.style.borderBottomColor = "red" // this.showMsgDiv(targetInput); // MsgDiv定位于要校验的目标input元素的上方 // } else { // 校验通过 //// this.checkObjectPicker(targetInput); // //// if (targetInput.oldBorderColor == 'default') { //// targetInput.style.borderBottomColor = ''; //// } else { //// targetInput.style.borderBottomColor = targetInput.oldBorderColor; //// } // this.hideMsgDiv(); // 隐藏MsgDiv // } return rsArr; /* * }catch(e){ if(this.debug) alert('方法checkForRealTime执行异常:'+e.message); } */ }, recursionIframe: function (win) { if (win.parent == top && win.parent == win) { // var xy = this.getAbsPoint(win); return { x: 0, y: 0, w: 0, h: 0, }; } var winPar = win.parent; // .opener var iframeArr = winPar.document.getElementsByTagName("IFRAME"); var targetIframe; for (var i = 0; i < iframeArr.length; i++) { var iframeElem = iframeArr[i]; if (iframeElem.contentWindow == win) { targetIframe = iframeElem; break; } } // alert(targetIframe==null) var xy = this.getAbsPoint(targetIframe); if (winPar.parent != winPar) { var xy2 = this.recursionIframe(winPar); xy.x += xy2.x; xy.y += xy2.y; } return xy; }, findObjectPickerInputer: function (target) { var name = target.getAttribute("name"); if (!name) return; var inputer = document.querySelector("[name=" + name + "Name]"); if (!inputer) { inputer = document.querySelector("[name=" + name + "Input]"); if (!inputer && /id$/.test(name)) { var inputName = name.replace(/id$/, "Name"); inputer = document.querySelector("[name=" + inputName + "]"); } if (!inputer && /m$/.test(name)) { var inputName = name.replace(/m$/, "Name"); inputer = document.querySelector("[name=" + inputName + "]"); } } return inputer; }, checkObjectPicker: function (target, msg) { var name = target.getAttribute("name"); var obj = wd.edit.objectPicker.getInstance(name); if (!obj) return; if (msg) { obj.failValidation(); } else { obj.passValidation(); } // var inputer=this.findObjectPickerInputer(target); // if(!inputer)return; // if(msg){ // inputer.style.border="red 1px solid"; // }else{ // inputer.style.border=""; // // } }, via: function (targetInput, msg, isnullFunction) { var gh = targetInput.GrowHeight; var name = targetInput.getAttribute("name"); if (gh != null) { name = targetInput.GrowHeight.getName(); } if (!name || !wd.edit) return; var leftSpan = document.getElementById(name + "Span"); if (!leftSpan) { leftSpan = document.createElement("span"); leftSpan.setAttribute("id", name + "Span"); // leftSpan.setAttribute("class","validation-span"); leftSpan.setAttribute("class", "border-input-error vLine-leftWarning"); // leftSpan.style.borderLeft=" 1px solid red", // leftSpan.style.height="100%"; // leftSpan.style.display= "none"; // leftSpan.style.position="absolute"; // leftSpan.style.left="0px"; } if (gh != null) { var growHeightElement = gh.getElement(); growHeightElement.parentNode.insertBefore(leftSpan, growHeightElement); } else { targetInput.parentNode.insertBefore(leftSpan, targetInput); } var obj; try { obj = wd.edit.objectPicker ? wd.edit.objectPicker.getInstance(name) : null; } catch (e) { console.log(e); } // // 获取或创建错误提示容器 // function getErrorContainer() { // let errorContainer = document.getElementById("error-container"); // if (!errorContainer) { // errorContainer = document.createElement("div"); // errorContainer.id = "error-container"; // 设置唯一ID // errorContainer.style.cssText = ` // position: fixed; // left: 0; // right: 0; // bottom: 0; // text-align: center; // background-color: #fff; // padding: 10px; // z-index: 1000; // display: flex; // font-size:1rem; // color: red; // justify-content: center; // align-items: center; // flex-direction: column; // min-height: 50px; /* 限制为五条信息的高度 */ // overflow-y: auto; /* 超过五条信息时出现滚动条 */ // `; // document.body.appendChild(errorContainer); // } // return errorContainer; // } // // 添加错误信息 // function addErrorMessage(name, msg) { // const errorContainer = getErrorContainer(); // const errorId = `${name}-error`; // 基于 name 属性生成唯一的错误消息 ID // let errorMessage = document.getElementById(errorId); // if (!errorMessage) { // // 如果不存在,创建新的错误消息 // errorMessage = document.createElement("div"); // errorMessage.id = errorId; // 给错误消息设置唯一 ID // errorContainer.appendChild(errorMessage); // } // // 更新错误消息内容 // errorMessage.textContent = msg; // } // // 移除特定错误信息 // function removeErrorMessage(name) { // const errorId = `${name}-error`; // const errorMessage = document.getElementById(errorId); // if (errorMessage) { // errorMessage.remove(); // 删除对应的错误消息 // } // } // // 检查并移除错误容器 // function removeErrorContainerIfEmpty() { // const errorContainer = document.getElementById("error-container"); // if (errorContainer && errorContainer.children.length === 0) { // errorContainer.remove(); // 容器中无内容时移除 // } // } // 添加错误信息到指定的td元素中 function addErrorMessage(name, msg) { const element = document.getElementsByName(name)[0]; // 获取 name 对应的元素 if (element) { const tdElement = element.closest('td'); // 查找最近的父级 td 元素 if (tdElement) { let errorMessage = tdElement.querySelector('.error-message'); // 查找是否已有错误信息元素 if (!errorMessage) { // 如果不存在,创建一个新的错误信息元素 errorMessage = document.createElement("div"); errorMessage.className = "error-message"; // 设置一个类名,方便样式管理 errorMessage.style.cssText = ` position: absolute; left: 0; bottom: 0; text-align: center; color: red; font-size:12px; width: 100%; text-align: right; line-height: 18px; height: 18px; `; tdElement.appendChild(errorMessage); // 将错误信息添加到 td 中 tdElement.style.borderBottom = "1px solid red"; } errorMessage.textContent = msg; // 更新错误信息内容 } } } // 移除特定错误信息 function removeErrorMessage(name) { const element = document.getElementsByName(name)[0]; // 获取 name 对应的元素 if (element) { const tdElement = element.closest('td'); // 查找最近的父级 td 元素 if (tdElement) { const errorMessage = tdElement.querySelector('.error-message'); // 查找错误信息元素 if (errorMessage) { errorMessage.remove(); // 删除错误信息元素 } } tdElement.style.borderBottom = ""; } } if (!this.passValidation(msg)) { leftSpan.style.display = ""; if (msg && msg.length > 0 && msg[0].msg) { if (!isnullFunction) { if (obj) { if(isMobile()){ addErrorMessage(obj, msg[0].msg); // 添加或更新错误消息 }else{ this.showMsgDiv(obj.getDisplayElement(), msg[0].msg); } } else { // 如果是移动端,在底部显示错误信息,否则在气泡 if(isMobile()){ addErrorMessage(name, msg[0].msg); // 添加或更新错误消息 }else{ this.showMsgDiv(targetInput, msg[0].msg); } } } } } else { // 校验通过 removeErrorMessage(name); // 移除当前 name 对应的错误消息 //removeErrorContainerIfEmpty(); // 如果没有错误信息,移除容器 // this.checkObjectPicker(targetInput); leftSpan.style.display = "none"; // targetInput.style.borderColor = ''; this.hideMsgDiv(); //隐藏MsgDiv; } }, mouseoverEvent: function (targetInput, activeFun) { var THIS = this; var target = targetInput; var name = targetInput.getAttribute("name"); if (name && wd.edit && wd.edit.objectPicker) { var obj = wd.edit.objectPicker.getInstance(name); if (obj) { target = obj.getDisplayElement(); } } var f = function () { activeFun.call(targetInput); }; $(target) .on("mouseenter", f) .on("mouseout", function () { // console.log(window.event) // if(window.event.srcElement!=target)return false if ($(target).find(window.event.relatedTarget).length == 1) return false; // console.log(window.event.srcElement) // THIS.MsgDiv.style.top = "-500px" THIS.hideMsgDiv(); }); // this.addEventListener(target, // 需绑定监听事件的DOM元素 // 'onmouseenter', // 事件名称,如:onclick // f); // 事件触发的回调函数 }, };