/**
* jquery自定义表单验证插件
* 使用方法:
* 在需要做验证的输入框,单选框,多选框,下拉框中加入validate属性
* validate:写法如下:
* {required:true,email:true,maxLength:50}
* 如:
*
* 注意一组单选框,或多选框 只需在其中一个input标记中 加入validate 属性
* 如:
*
*
*
*
* tipId:错误信息显示的容器ID,设置了这个属性后,错误信息会显示到该标签中。
*
*
*
* 调用方式:
*
* $("a.save").click(function(){
* var rtn=$("#shipOrderForm").form().valid();
* if(rtn){
* $("#shipOrderForm").submit();
* }
* });
* 同时也可以扩展验证的规则
* var rtn=$("#form").form({
* //扩展验证规则 追加到已有的规则中
* rules:[{
* //规则名称
* name:"QQ",
* //判断方法 返回 true 或false
* rule:function(v){
* },
* //错误的提示信息
* msg:""
*
* }],
* //显示的错误信息样式 element 当前验证的元素,msg:错误信息
* errorPlacement:function(element,msg){
* },
* //成功后的样式 element 当前验证的元素
* success:function(element){
* },
* excludes:":hidden"
* }).valid()
*
* 扩展 : by xianggang
* 1、如果需要弹出错误提示的具体信息 可以这样使用
* var rtn=CustomForm.validate({returnErrorMsg:true});
* 或者 $("form").valid({returnErrorMsg:true});
* 其中form即为您要验证的表单或者域
* if(!rtn.success){
* $.ligerDialog.tipDialog($lang.tip.msg,"表单验证错误信息如下",rtn.errorMsg,null,function(){
* $.ligerDialog.hide();
* });
* return;
* }
* 2、如果想要自定义错误提示信息 可以这样使用
*
* 其中的errormsgtips即为自定义错误提示信息的json对象。
*/
(function($) {
$.extend($.fn, {
// 表单初始化,可以添加自定义规则,出错处理和成功后的处理。
form : function(conf) {
if (conf) {
if (conf.errorPlacement) {
this.errorPlacement = conf.errorPlacement;
};
if (conf.rules) {
for (var i = 0, len = conf.rules.length; i < len; i++) {
this.addRule(conf.rules[i]);
}
};
if (conf.success) {
this.success = conf.success;
};
if (conf.excludes) {
this.excludes = conf.excludes;
}
}
var form = this;
form.delegate("input[validate],select[validate],textarea[validate]", "blur", function() {
form.handValidResult(this);
});
form.delegate("input[validate],select[validate],textarea[validate]", "focus", function() {
form.success(this);
});
//处理验证ckeditor
$("[validate].ckeditor",form).each(function(){
var me= $(this),name = me.attr("name");
setTimeout(function(){//等待ckeditor渲染完成再进行处理
var editor= CKEDITOR.instances[name],ck=me.next();
if(editor){
editor.on( 'blur', function(){
form.handValidResult(me);
});
editor.on( "focus", function(){
form.success(me);
});
}
},1000);
})
return this;
},
// 添加验证规则。
// 扩展规则和现有的规则名称相同,则覆盖,否则添加。
addRule : function(rule) {
var len = this.rules.length;
for (var i = 0; i < len; i++) {
var r = this.rules[i];
if (rule.name == r.name) {
this.rules[i] = rule;
return;
}
}
this.rules.push(rule);
},
/**
* 判断元素是否在不需要校验的范围内。
*/
isInNotValid : function(obj) {
//在fieldControl.flt的文件上传中的textarea添加属性validatable,为true表示在验证范围内
if($(obj).is(":hidden")){
if($(obj).attr("validatable")!="true"){
return true;
}
}
if (!this.excludes)
return false;
var scope = $(this.excludes, this);
var aryInput = $(
"input:text,input:hidden,textarea,select,input:checkbox,input:radio",
scope);
for (var i = 0, len = aryInput.length; i < len; i++) {
var tmp = aryInput.get(i);
if (obj == tmp) {
return true;
}
}
return false;
},
// 对所有有validate表单控件进行验证。
valid : function(conf) {
if(!conf){
this.ignoreRequired=false;
}
else{
if(conf.ignoreRequired==undefined){
this.ignoreRequired=false;
}
else{
this.ignoreRequired=conf.ignoreRequired;
}
}
var _v = true, form = this,msgs={};
$('[validate]', form).each(function() {
var returnObj = form.handValidResult(this);
for(var i in returnObj){
if (i=="success"&&!returnObj.success)
_v = false;
else
msgs[i]=returnObj[i];
}
});
if(conf&&conf.returnErrorMsg){
var returnTextObj={};
if(!_v){
var errorMsg="
";
var i=1;
for(var m in msgs){
if(m=="success")continue;
errorMsg=errorMsg+(i++)+"、"+
m+"   "+msgs[m]+"";
}
errorMsg+="
"
}
returnTextObj.success=_v;
returnTextObj.errorMsg=errorMsg;
return returnTextObj;
}
return _v;
},
// 显示表单处理结果
handValidResult : function(obj) {
//判断验证的控件是否是a标签,是的不处理,直接返回
var isATag=$(obj).is("a");
if(isATag) return;
// 是否在不需要验证的范围内,在的话就不需要验证。
var returnObj={};
if (this.isInNotValid(obj)){
returnObj.success=true;
return returnObj;
}
var msg = this.validEach(obj);
if (msg != '') {
this.errorPlacement(obj, msg);
returnObj.success=false;
var opinionReg = /.*:.*:(.*)|opinion:(.*)/.exec($(obj).attr("name"));
if(opinionReg&&opinionReg.length==2){
var lableName = "";
var lableTemp = $(obj).attr("lablename");
if(lableTemp){
lableName = lableTemp;
}else{
var title = $(obj).parents("tr").children("td.formTitle").text();
title=title.replaceAll(":","");
if(title)lableName = title;
}
var msgName=/.*:.*:(.*)|opinion:(.*)/.exec($(obj).attr("name"))[1]+" ("+lableName+")";
returnObj[msgName]=msg;
}
return returnObj;
} else {
this.success(obj);
if($(obj).hasClass('validError')){ //引对子表单的
$(obj).removeClass('validError');
}
returnObj.success=true;
return returnObj;
}
},
// 验证单个控件。
validEach : function(obj) {
var element = $(obj),
rules = this.rules,
validRule = element.attr('validate'),
value = "",
name = element.attr("name");
// 处理单选框和多选框
if(element.is(":checkbox,:radio")) {
var parentObj = element.closest("[formtype]"),
brotherObjs = (parentObj&&parentObj.length>0)?$(":checked[name='" + name + "']",parentObj):$(":checked[name='" + name + "']");
brotherObjs.each(function() {
if (value == "") {
value = $(this).val();
} else {
value += "," + $(this).val();
}
});
}else if (element.is("select")) {// 处理select
value = element.find("option:selected").val();
if(typeof(value)==undefined || value==null || $.trim(value) == '' || value.indexOf("请选择")>-1){
value = '';
}
}else if (element.hasClass("ckeditor") ) {// 处理ckeditor编辑器
var editor= CKEDITOR.instances[name];
if($.isEmpty(editor))//ckeditor没渲染的,则取textarea的值
value = element.val();
else
value = editor.getData();
}else if(element.hasClass("selectFile")){//处理附件
value = element.siblings("textarea[controltype='attachment']").val();
}else if(element.hasClass("dicComboBox")||element.hasClass("dicComboTree")||element.hasClass("dicCombo")){ //处理数据字典
var textboxname = element.attr("textboxname");
if(!textboxname)
textboxname = element.attr("name").replaceAll(":","") +"_id";// 修改bug,但是去除字符的有问题
value = element.parents("td.formInput").find("input[name='"+textboxname+"']").val();
}else {
value = element.val();
}
// 处理值
value = value == null ? "" : value.trim();
// 获取json。
var json = eval('(' + validRule + ')');
var isRequired = json.required;
// 非必填的字段且值为空 那么直接返回成功。
if ((isRequired == false || isRequired == undefined) && value == "")
return "";
//忽略必填规则。
if(this.ignoreRequired==true && value == "") return "";
// 遍历json规则。
for (var name in json) {
var validValue = json[name];
//验证规则
var msg = this._validRules({
rules:rules,//规则json
ruleName:name,// 规则名称
validValue:validValue,//验证的值
value:value,//实际的值
errormsgtips:element.attr("errormsgtips"),
element:element
});
if (msg != '')
return msg;
}
return "";
},
/**
* 验证规则
**/
_validRules :function(conf){
var _valid = true,
rules = conf.rules,//规则json
ruleName = conf.ruleName,// 规则名称
validValue = conf.validValue,//验证的值
value =conf.value,//实际的值
element = conf.element;//当前对象
try{
//处理当element为货币时,value会类似:¥10.00 但这事实上应该是数字
// 所以需要处理一下value,让其变成 10.00
var str=$(element).attr('showtype').replace(new RegExp("'","gm"),"\"");
var cv=JSON.parse(str).coinValue;
if(value.startWith("+"+cv)||value.startWith("-"+cv)||value.startWith(cv)){
value=value.replace(cv,"");
}
}catch(e){}
for (var m = 0; m < rules.length; m++) {
// 取得验证规则。
var rule = rules[m];
if (ruleName.toLowerCase() != rule.name.toLowerCase()) continue;
// 验证规则如下:
// email:true,url:true.
//验证规则是boolean类型
if ($.type(validValue) === "boolean")
_valid = (!rule.rule(value) && validValue == true) ? false:true;
else
_valid = rule.rule(value, validValue,element);
if (!_valid){ //验证不通过返回消息
var errorMsg=rule.msg;
if(conf.errormsgtips){
var errormsgtips=eval("("+conf.errormsgtips.replaceAll("'","\"")+")")
for(var i in errormsgtips){
if(i==ruleName){
errorMsg=errormsgtips[i];
break;
}
}
}
return this.format(errorMsg, validValue);
}
}
return "";
},
/**
* 消息格式化
**/
format:function(msg,args){
//boolean类型的直接返回
if ($.type(args) === "boolean")
return msg;
if (!$.isArray(args)) //不是数组类型的
args = [args];
//数组类型的
$.each(args,function(d, e) {
msg = msg.replace(RegExp("\\{" + d + "\\}", "g"), e)
});
return msg;
},
// 错误显示位置。
errorPlacement : function(element, msg) {
var errorId = $(element).attr("tipId");
if (errorId) {
$('#' + errorId).find('label.error').remove();
$('#' + errorId).append($(''));
return;
}
var parent =$(element).parent();
parent.find('label.error').remove();
parent.append($(''));
},
// 验证成功时,删除错误提示信息。
success : function(element) {
var errorId = $(element).attr("tipId");
if (errorId) {
$('#' + errorId).find('label.error').remove();
return;
}
$(element).parent().find('label.error').remove();
},
// 内置的规则。
rules : [{
name : "required",
rule : function(v) {
if (v == "" || v.length == 0)
return false;
return true;
},
msg : $lang_js.customValid.rules.required
}, {
name : "number",
rule : function(v) {
return /^-?((\d{1,3}(,\d{3})+?|\d+)(\.\d{1,5})?)$/
.test(v.trim());
},
msg : $lang_js.customValid.rules.number
}, {
name : "variable",
rule : function(v) {
return /^[A-Za-z_0-9]*$/gi.test(v.trim());
},
msg : $lang_js.customValid.rules.variable
}, {
name : "fields",
rule : function(v){
return /^[A-Za-z]{1}([a-zA-Z0-9_]{1,17})?$/gi.test(v.trim());
},
msg : $lang_js.customValid.rules.fields
},{
name : "minLength",
rule : function(v, b) {
return (v.length >= b);
},
msg : $lang_js.customValid.rules.minLength
}, {
name : "maxLength",
rule : function(v, b) {
return (v.trim().replace(/[^x00-xFF]/g,'**').length <= b);
},
msg : $lang_js.customValid.rules.maxLength
}, {
name : "rangeLength",
rule : function(v, args) {
return (v.trim().length >= args[0] && v.trim().length <= args[1]);
},
msg : $lang_js.customValid.rules.rangeLength
},{
name : "officephone",
rule : function(v) {
return /^(0\d{2,3}-?)?\d{7,8}$/
.test(v.trim());
},
msg : "请输入正确的办公电话号码"
}, {
name : "phone",
rule : function(v) {
return /^0?1[3|4|5|8][0-9]\d{8}$/
.test(v.trim());
},
msg : "请输入正确的移动电话号码"
}, {
name : "email",
rule : function(v) {
return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i
.test(v.trim());
},
msg : $lang_js.customValid.rules.email
}, {
name : "url",
rule : function(v) {
return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i
.test(v.trim());
},
msg : $lang_js.customValid.rules.url
}, {
name : "date",
rule : function(v) {
var re = /^[\d]{4}-[\d]{1,2}-[\d]{1,2}\s*[\d]{1,2}:[\d]{1,2}:[\d]{1,2}|[\d]{4}-[\d]{1,2}-[\d]{1,2}|[\d]{1,2}:[\d]{1,2}:[\d]{1,2}$/g
.test(v.trim());
return re;
},
msg : $lang_js.customValid.rules.date
}, {
name : "digits",
rule : function(v) {
return /^\d+$/.test(v.trim());
},
msg : $lang_js.customValid.rules.digits
}, {
name : "equalTo",
rule : function(v, b) {
var a = $("#" + b).val();
return (v.trim() == a.trim());
},
msg : $lang_js.customValid.rules.equalTo
}, {
name : "range",
rule : function(v, args) {
return v <= args[1] && v >= args[0];
},
msg : $lang_js.customValid.rules.range
}, {
name : "maxvalue",
rule : function(v, max) {
return v <= max;
},
msg : $lang_js.customValid.rules.maxvalue
},{
name : "minvalue",
rule : function(v, min) {
return v >= min;
},
msg :$lang_js.customValid.rules.minvalue
},{
// 判断数字整数位
name : "maxIntLen",
rule : function(v, b) {
return (v + '').split(".")[0].replaceAll(",","").length <= b;
},
msg : $lang_js.customValid.rules.maxIntLen
}, {
// 判断数字小数位
name : "maxDecimalLen",
rule : function(v, b) {
return (v + '').replace(/^[^.]*[.]*/, '').length <= b;
},
msg : $lang_js.customValid.rules.maxDecimalLen
}, {
/**
* 判断日期开始范围{dateRangeStart:{
* target:'endXXX',
* mode:'name',
* range:''
* }}
* target:查找对象 结束时间的日期对象(必填)
* mode:查找方式(默认是:name) 【可选值:id,name,class】
* range:查找范围(默认是‘’,查找所有body) 【可选值:'',main,sub】
*
* 支持旧版的id查找 dateRangeStart:'xxxID' //结束时间的日期对象ID
*
*/
name : "dateRangeStart",
rule : function(v, b,e) {
if(!$.isPlainObject(b))
b = { target:b,mode:'id'};
var target = b.target,//查找对象
mode = b.mode?b.mode:'name',//查找方式
range = b.range?b.range:'';//查找范围
val ='';
if(mode == 'name'){
if(range =="" || range =="main" ){//空或者主表
val = $("[name='" +target+"']").val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("[name='" +target+"']").val();
}
}else if(mode == 'id'){
if(range =="" || range =="main" ){//空或者主表
val = $("#" +target).val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("#" +target).val();
}
}else{
if(range =="" || range =="main" ){//空或者主表
val = $("." +target).val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("." +target).val();
}
}
return daysBetween(val, v);
},
msg : $lang_js.customValid.rules.dateRangeStart
}, {
/**
* 判断日期开始范围{dateRangeStart:{
* target:'startXXX',
* mode:'name',
* range:''
* }}
* target:查找对象 开始时间的日期对象(必填)
* mode:查找方式(默认是:name) 【可选值:id,name,class】
* range:查找范围(默认是‘’,查找所有body) 【可选值:'',main,sub】
*
* 支持旧版的id查找 dateRangeStart:'xxxID' //开始时间的日期对象ID
*
*/
name : "dateRangeEnd",
rule : function(v,b,e) {
if(!$.isPlainObject(b))
b = { target:b,mode:'id'};
var target = b.target,//查找对象
mode = b.mode?b.mode:'name',//查找方式
range = b.range?b.range:'';//查找范围
val ='';
if(mode == 'name'){
if(range =="" || range =="main" ){//空或者主表
val = $("[name='" +target+"']").val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("[name='" +target+"']").val();
}
}else if(mode == 'id'){
if(range =="" || range =="main" ){//空或者主表
val = $("#" +target).val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("#" +target).val();
}
}else{
if(range =="" || range =="main" ){//空或者主表
val = $("." +target).val();
}else if(range ="sub"){//子表
val = $(e).closest('[formtype]').find("." +target).val();
}
}
return daysBetween(v, val);
},
msg : $lang_js.customValid.rules.dateRangeEnd
},
{
// 空的字段(永远通过验证,返回true) 防止在验证JSON中出现有多余的逗号
name : "empty",
rule : function(v, b) {
// var start = $("#" + b).val();
return true;
},
msg : ""
},
{
// 不能以数字开头
name : "noDigitsStart",
rule : function(v) {
return !/^(\d+)(.*)$/.test(v.trim());
},
msg : $lang_js.customValid.rules.noDigitsStart
}, {
name : "varirule",
rule : function(v) {
return /^[a-zA-Z]\w*$/.test(v.trim());
},
msg : "只能为字母开头,允许字母、数字和下划线"
}, {
//不能以数字开头
name : "chNum",
rule : function(v) {
return /^[0-9\u4e00-\u9fa5]+$/.test(v.trim());
[\u4e00-\u9fa5]
},
msg : "只允许输入中文和数字"
}, {
name : "chinese",
rule : function(v) {
return /[\u4e00-\u9fa5]/.test(v.trim());
},
msg : "只允许输入中文"
}
]
});
})(jQuery);