手机表单验证插件mvalidate的使用

使用

1.引入js和css

<script type="text/javascript" src="../script/jquery-mvalidate.js"></script>
<link rel="stylesheet" type="text/css" href="../css/mvalidate.css">

2.html处理

        <li class="aui-list-item">
            <div class="aui-list-item-inner">
                <div class="aui-list-item-input">
                    <input type="text" name="name" data-required="true" data-descriptions="name" placeholder="收货人姓名">
                </div>
            </div>
        </li>
        <li class="aui-list-item">
            <div class="aui-list-item-inner">
                <div class="aui-list-item-input">
                    <input type="text" name="tel" placeholder="手机号码" data-required="true" data-descriptions="tel" data-pattern="^0?1[3|4|5|8][0-9]\d{8}$">
                </div>
            </div>
        </li>

3.js处理

$("#myform").mvalidate({
    type:1,
    onKeyup:true,
    sendForm:true,
    firstInvalidFocus:true,
    valid:function(event,options){
        //点击提交按钮时,表单通过验证触发函数
        //alert("验证通过!接下来可以做你想做的事情啦!");
        event.preventDefault();
    },
    invalid:function(event, status, options){
        //点击提交按钮时,表单未通过验证触发函数
        // alert("表单未通过验证!");
    },
    eachField:function(event,status,options){
        //点击提交按钮时,表单每个输入域触发这个函数 this 执向当前表单输入域,是jquery对象
        // alert("每个都弹出!");
    },
    eachValidField:function(val){},
    eachInvalidField:function(event, status, options){},
    conditional:{
    },
    descriptions:{
        name:{
            required : '请输入收货人姓名'
        },
        tel : {
            required : '请输入手机号码',
            pattern : '手机号格式不正确'
        }
    }
});

jquery版本

(function (factory) {
	if (typeof define === 'function' && define.amd ) {
		define(['jquery'], function(jquery){
			// 返回构造函数
			factory(jquery); // 初始化插件	
		});
	}else if(typeof define === 'function' && define.cmd){
		define(['jquery'], function(require,exports,moudles){
			factory(
			require('jquery')); // 初始化插件
		})
	}else{
		factory(jQuery);
	}
})(function($){
	var type = ['input:not([type]),input[type="color"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="file"],input[type="hidden"],input[type="month"],input[type="number"],input[type="password"],input[type="range"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"],textarea', 'select', 'input[type="checkbox"],input[type="radio"]'],
		allTypes=type.join(","),
		extend={};
	var fieldValidTypeHand=function($field,status,options){
				if($field.prop("type")=="radio" || $field.prop("type")=="checkbox"){
					var $fields=options.$form.find('[name="'+$field.prop('name')+'"]');

					if($fields.filter(":checked").length > 0){
						$fields.removeClass('field-invalid')
					}else{
						$fields.addClass('field-invalid')
					}
				}else{
					if(status.required && status.pattern && status.conditional) {
						$field.removeClass('field-invalid');
					}else{
						$field.addClass('field-invalid');
					}
				}
	};
	var fieldTooltip=(function(){
			var instance=null;
				function show(text){
					if(!instance){
						var $container=$('<div class="field-tooltipWrap"><div class="field-tooltipInner"><div class="field-tooltip fieldTipBounceIn">'+text+'</div></div></div>');
		    			$container.appendTo($("body"));
		    			instance=true;
		    			setTimeout(function(){
							$container.remove();
							instance=false;
						},1500)
					}
				}
		   
			return {
				show:show
			}
	})();
	var validateField=function(event,options){
		var $field=$(this),
			status={
				required:true,
				conditional:true,
				pattern:true
			},
			log,//验证提示信息存储变量
			
			errorTipFormat=$.fn.mvalidate.errorTipFormat,//错误信息输出的格式化
			
			fieldValue =$.trim($field.val()) || "",

		    //*****获取当前字段的data-validate
			fieldValidate=$field.attr("data-validate"),
			validation=(fieldValidate != undefined) ? extend[fieldValidate]:{},
			//*****获取当前字段的data-required
			fieldRequired=$field.attr("data-required"),
			//*****获取当前字段的data-pattern
			fieldPattern = ($field.attr('data-pattern') || ($.type(validation.pattern) == 'regexp' ? validation.pattern : /(?:)/)),


			//*****获取当前字段的data-conditional
			fieldConditional=$field.attr("data-conditional") || validation.conditional,
			//*****获取当前字段的data-description
			fieldDescription=$field.attr("data-descriptions") || validation.descriptions,
			//*****获取当前字段的data-describedby
			fieldDescribedby=$field.attr("data-describedby") || validation.describedby;

			fieldDescription = $.isPlainObject(fieldDescription) ? fieldDescription : (options.descriptions[fieldDescription] || {});
			fieldRequired=fieldRequired !='' ? (fieldRequired || !!validation.required ) : true;
			if($.type(fieldPattern) != 'regexp') {
				fieldPattern=RegExp(fieldPattern);
			}

		//如果是必填验证,那么就要判断是什么类型的表单
		if(fieldRequired) {
			//如果是那种可以通过val()来判断的
			if($field.is(type[0] + ',' + type[1])) {
				if(!fieldValue.length > 0){
					status.required = false;
				}
			//如果是raido和checkbox,通过name和checked来判断
			}else if($field.is(type[2])){
				if($field.is('[name]')) {
					if(options.$form.find('[name="'+$field.prop('name')+'"]:checked').length==0){
						status.required = false;
					}
				}else{
					status.required = field.is(':checked');
				}
			}
		}
		/**如果是正则验证
		 * 只有那些类似type=text的文本框我们才能通过正则表达式去验证pattern,
		 * 而对于select,radio,checkbox pattern显然是无效的
		 */
		if($field.is(type[0])) {
			//如果不匹配
			if(!fieldPattern.test(fieldValue)){
				if(fieldRequired){
					status.pattern=false;
				}else{
					if(fieldValue.length > 0){
						status.pattern = false;
					}
				}
			}
		}

		//如果是data-conditional="name"函数验证,函数返回true或者是false
		if(fieldConditional !="undefined"){
			if($.isFunction(fieldConditional)){
				status.conditional=!!fieldConditional.call($field, fieldValue,options);
			}else{
				if(options.conditional.hasOwnProperty(fieldConditional) && !options.conditional[fieldConditional].call($field,fieldValue,options)){
					status.conditional=false;
				}
			}
		}

     
		//验证通过的信息所在对象
		log = errorTipFormat(fieldDescription.valid);
		if(!status.required) {
			log = errorTipFormat(fieldDescription.required);
			
		}else if(!status.pattern) {
			log = errorTipFormat(fieldDescription.pattern);
			
			
		} else if(!status.conditional) {
			log =errorTipFormat(fieldDescription.conditional);
		}

		var $describedShowElem=$('[id="' + fieldDescribedby +'"]');
		//如果找打提示的容器,是第二种类型的验证
		if($describedShowElem.length > 0 && options.type==2){
			//如果是change 或者是keyup 同时是第一次输入的时候就不要验证
			if((event.type=="keyup" || event.type=="change") && (!$describedShowElem.children().length || !$.trim($describedShowElem.text()))){

			}else{					
				$describedShowElem.html(log || '');
				fieldValidTypeHand($field,status,options)
			}
		}

		if(typeof(validation.each) == 'function') {
			validation.each.call($field, event, status, options);
		}
		options.eachField.call($field, event, status, options);

		if(status.required && status.pattern && status.conditional) {	
			
			if(typeof(validation.valid) == 'function') {//二外拓展的
				validation.valid.call($field, event, status, options);
			}
			options.eachValidField.call($field, event, status, options);
		}else{//验证未通过
			if(!options.firstInvalid && options.firstInvalidFocus){
				options.firstInvalid=true;
				$field.focus();
			}
			if(options.type==1){
				fieldTooltip.show(log)
			}
			if(typeof(validation.invalid) == 'function') {
				validation.invalid.call($field, event, status, options);
			}
			options.eachInvalidField.call($field, event, status, options);	
		}
		
	/**
	 * 如果是data-describedby="elemId"验证信息要显示的地方,类型3的验证:
		 * 		第一元素获取焦点,keyUp的时候要一直验证,如果正确那么错误信息就隐藏,如果不正确,那么错误
		 * 		提示信息要根据状态而改变,对于与验证通过,那么可以通过eachInvalid来让用户自定义,而无需要
		 * 		在插件中写它的操作方式
		 */
		return status;
	};
	$.extend($,{
		mvalidateExtend:function(options){
			return $.extend(extend, options);	
		},
		mvalidateTip:function(text){
			var txt=$.fn.mvalidate.errorTipFormat(text);
			fieldTooltip.show(txt)
		}
	});



	
	
	$.fn.mvalidate=function(options){
		var defaults={
			type:1,
			validateInSubmit:true,
			sendForm:true,
			onKeyup:false,
			onChange:true,
			firstInvalidFocus:true,//第一个未通过验证的表单是否获得交代呢
			conditional:{},
			descriptions:{},
			eachField : $.noop,
			eachValidField:$.noop,
			eachInvalidField : $.noop,
			valid:$.noop,
			invalid:$.noop,
			namespace:"mvalidate"
		},
		opts=$.extend(true,defaults,options),
		flag,
		namespace=opts.namespace;

		opts.type=Number(opts.type);
		opts.firstInvalid=false;
		flag=opts.type==1 ? false : true;
		return this.mvalidateDestroy().each(function(event) {
			
			var $form=$(this),
				$fields;//存放当前表单下的所有元素;
			if(!$form.is("form")) return;
			opts.$form=$form;
			$form.data(name,{"options":opts});
			$fields=$form.find(allTypes);
			
			//
			if(flag && opts.onKeyup){
				$fields.filter(type[0]).each(function() {

					$(this).on("keyup."+namespace,function(event){
						validateField.call(this,event,opts)
					})
				});
			}

			if(flag && opts.onChange){
				$fields.each(function() {
					var $this=$(this);
					if($this.is(type[1]+ ',' + type[2])){
						$(this).on('change.' + namespace, function(event) {
							validateField.call(this, event, opts);
						})
					}	
				})
			}

			//如果需要验证的时候,在提交表单的时候对所有的字段进行验证
			if(opts.validateInSubmit){
				$form.on("submit."+namespace,function(event){
					var formValid = true;
					opts.firstInvalid=false;
					$fields.each(function() {
						var status=validateField.call(this,event,opts);
						if(!status.pattern || !status.conditional || !status.required) {
							formValid = false;
						}
					});
					
					if(formValid){
						if(!opts.sendForm){
							event.preventDefault();
						}
						if($.isFunction(opts.valid)){
							opts.valid.call($form,event,opts);
						}
					//验证没有通过,禁用提交事件,以及绑定在这个elem上的其他事件	
					}else{
						event.preventDefault();
						event.stopImmediatePropagation();
						if($.isFunction(opts.invalid)) {
							opts.invalid.call($form,event,opts)
						}
					}
					
				})
			}
		})
	};
	$.fn.mvalidateDestroy=function(){
		var $form=$(this),$fields,
			dataValidate=$form.data(name);
		if($form.is('form') && $.isPlainObject(dataValidate) && typeof(dataValidate.options.nameSpace) == 'string') {
			$fields = $form.removeData(name).find(allTypes);
			$fields.off('.' + dataValidate.options.nameSpace);
		}	
		return $form;
	};
	$.fn.mvalidate.errorTipFormat=function(text){
		return '<div class="zvalid-resultformat">'+text+'</div>';
	}


})

zetpo版本

(function (factory) {
	if (typeof define === 'function' && define.amd ) {
		define(['Zepto'], function(zepto){
			// 返回构造函数
			factory(zepto); // 初始化插件	
		});
	}else if(typeof define === 'function' && define.cmd){
		define(['Zepto'], function(require,exports,moudles){
			factory(require('Zepto')); // 初始化插件
		})
	}else{
		factory(Zepto);
	}
})(function($){
	var type = ['input:not([type]),input[type="color"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="file"],input[type="hidden"],input[type="month"],input[type="number"],input[type="password"],input[type="range"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"],textarea', 'select', 'input[type="checkbox"],input[type="radio"]'],
		allTypes=type.join(","),
		extend={};
	var fieldValidTypeHand=function($field,status,options){
				if($field.prop("type")=="radio" || $field.prop("type")=="checkbox"){
					var $fields=options.$form.find('[name="'+$field.prop('name')+'"]');

					if($fields.filter(":checked").length > 0){
						$fields.removeClass('field-invalid')
					}else{
						$fields.addClass('field-invalid')
					}
				}else{
					if(status.required && status.pattern && status.conditional) {
						$field.removeClass('field-invalid');
					}else{
						$field.addClass('field-invalid');
					}
				}
	};
	var fieldTooltip=(function(){
			var instance=null;
				function show(text){
					if(!instance){
						var $container=$('<div class="field-tooltipWrap"><div class="field-tooltipInner"><div class="field-tooltip fieldTipBounceIn">'+text+'</div></div></div>');
		    			$container.appendTo($("body"));
		    			instance=true;
		    			setTimeout(function(){
							$container.remove();
							instance=false;
						},1500)
					}
				}
		   
			return {
				show:show
			}
	})();
	var validateField=function(event,options){
		var $field=$(this),
			status={
				required:true,
				conditional:true,
				pattern:true
			},
			log,//验证提示信息存储变量
			
			errorTipFormat=$.fn.mvalidate.errorTipFormat,//错误信息输出的格式化
			
			fieldValue =$.trim($field.val()) || "",

		    //*****获取当前字段的data-validate
			fieldValidate=$field.attr("data-validate"),
			validation=(fieldValidate != undefined) ? extend[fieldValidate]:{},
			//*****获取当前字段的data-required
			fieldRequired=$field.attr("data-required"),
			//*****获取当前字段的data-pattern
			fieldPattern = ($field.attr('data-pattern') || ($.type(validation.pattern) == 'regexp' ? validation.pattern : /(?:)/)),


			//*****获取当前字段的data-conditional
			fieldConditional=$field.attr("data-conditional") || validation.conditional,
			//*****获取当前字段的data-description
			fieldDescription=$field.attr("data-descriptions") || validation.descriptions,
			//*****获取当前字段的data-describedby
			fieldDescribedby=$field.attr("data-describedby") || validation.describedby;

			fieldDescription = $.isPlainObject(fieldDescription) ? fieldDescription : (options.descriptions[fieldDescription] || {});
			fieldRequired=fieldRequired !='' ? (fieldRequired || !!validation.required ) : true;
			if($.type(fieldPattern) != 'regexp') {
				fieldPattern=RegExp(fieldPattern);
			}

		//如果是必填验证,那么就要判断是什么类型的表单
		if(fieldRequired) {
			//如果是那种可以通过val()来判断的
			if($field.is(type[0] + ',' + type[1])) {
				if(!fieldValue.length > 0){
					status.required = false;
				}
			//如果是raido和checkbox,通过name和checked来判断
			}else if($field.is(type[2])){
				if($field.is('[name]')) {
					if(options.$form.find('[name="'+$field.prop('name')+'"]:checked').length==0){
						status.required = false;
					}
				}else{
					status.required = field.is(':checked');
				}
			}
		}
		/**如果是正则验证
		 * 只有那些类似type=text的文本框我们才能通过正则表达式去验证pattern,
		 * 而对于select,radio,checkbox pattern显然是无效的
		 */
		if($field.is(type[0])) {
			//如果不匹配
			if(!fieldPattern.test(fieldValue)){
				if(fieldRequired){
					status.pattern=false;
				}else{
					if(fieldValue.length > 0){
						status.pattern = false;
					}
				}
			}
		}

		//如果是data-conditional="name"函数验证,函数返回true或者是false
		if(fieldConditional !="undefined"){
			if($.isFunction(fieldConditional)){
				status.conditional=!!fieldConditional.call($field, fieldValue,options);
			}else{
				if(options.conditional.hasOwnProperty(fieldConditional) && !options.conditional[fieldConditional].call($field,fieldValue,options)){
					status.conditional=false;
				}
			}
		}

     
		//验证通过的信息所在对象
		
		log = errorTipFormat(fieldDescription.valid);
		if(!status.required) {
			log = errorTipFormat(fieldDescription.required);
			
		}else if(!status.pattern) {
			log = errorTipFormat(fieldDescription.pattern);
			
			
		} else if(!status.conditional) {
			log =errorTipFormat(fieldDescription.conditional);
		}

		var $describedShowElem=$('[id="' + fieldDescribedby +'"]');
		//如果找打提示的容器,是第二种类型的验证
		if($describedShowElem.length > 0 && options.type==2){
			//如果是change 或者是keyup 同时是第一次输入的时候就不要验证
			if((event.type=="keyup" || event.type=="change") && (!$describedShowElem.children().length || !$.trim($describedShowElem.text()))){

			}else{					
				$describedShowElem.html(log || '');
				fieldValidTypeHand($field,status,options)
			}
		}

		if(typeof(validation.each) == 'function') {
			validation.each.call($field, event, status, options);
		}
		options.eachField.call($field, event, status, options);

		if(status.required && status.pattern && status.conditional) {	
			
			if(typeof(validation.valid) == 'function') {//二外拓展的
				validation.valid.call($field, event, status, options);
			}
			options.eachValidField.call($field, event, status, options);
		}else{//验证未通过
			if(!options.firstInvalid && options.firstInvalidFocus){
				options.firstInvalid=true;
				$field.focus();
			}
			if(options.type==1){
				fieldTooltip.show(log)
			}
			if(typeof(validation.invalid) == 'function') {
				validation.invalid.call($field, event, status, options);
			}
			options.eachInvalidField.call($field, event, status, options);	
		}
		
	/**
	 * 如果是data-describedby="elemId"验证信息要显示的地方,类型3的验证:
		 * 		第一元素获取焦点,keyUp的时候要一直验证,如果正确那么错误信息就隐藏,如果不正确,那么错误
		 * 		提示信息要根据状态而改变,对于与验证通过,那么可以通过eachInvalid来让用户自定义,而无需要
		 * 		在插件中写它的操作方式
		 */
		return status;
	};
	$.extend($,{
		mvalidateExtend:function(options){
			return $.extend(extend, options);	
		}
	});

	
	
	$.fn.mvalidate=function(options){
		var defaults={
			type:1,
			validateInSubmit:true,
			sendForm:true,
			onKeyup:false,
			onChange:true,
			firstInvalidFocus:true,//第一个未通过验证的表单是否获得交代呢
			conditional:{},
			descriptions:{},
			eachField : $.noop,
			eachValidField:$.noop,
			eachInvalidField : $.noop,
			valid:$.noop,
			invalid:$.noop,
			namespace:"mvalidate"
		},
		opts=$.extend(true,defaults,options),
		flag,
		namespace=opts.namespace;

		opts.type=Number(opts.type);
		opts.firstInvalid=false;
		flag=opts.type==1 ? false : true;
		return this.mvalidateDestroy().each(function(event) {
			
			var $form=$(this),
				$fields;//存放当前表单下的所有元素;
			if(!$form.is("form")) return;
			opts.$form=$form;
			$form.data(name,{"options":opts});
			$fields=$form.find(allTypes);
			
			//
			if(flag && opts.onKeyup){
				$fields.filter(type[0]).each(function() {

					$(this).on("keyup."+namespace,function(event){
						validateField.call(this,event,opts)
					})
				});
			}

			if(flag && opts.onChange){
				$fields.each(function() {
					var $this=$(this);
					if($this.is(type[1]+ ',' + type[2])){
						$(this).on('change.' + namespace, function(event) {
							validateField.call(this, event, opts);
						})
					}	
				})
			}

			//如果需要验证的时候,在提交表单的时候对所有的字段进行验证
			if(opts.validateInSubmit){
				$form.on("submit."+namespace,function(event){
					var formValid = true;
					opts.firstInvalid=false;
					$fields.each(function() {
						var status=validateField.call(this,event,opts);
						if(!status.pattern || !status.conditional || !status.required) {
							formValid = false;
						}
					});
					
					if(formValid){
						if(!opts.sendForm){
							event.preventDefault();
						}
						if($.isFunction(opts.valid)){
							opts.valid.call($form,event,opts);
						}
					//验证没有通过,禁用提交事件,以及绑定在这个elem上的其他事件	
					}else{
						event.preventDefault();
						event.stopImmediatePropagation();
						if($.isFunction(opts.invalid)) {
							opts.invalid.call($form,event,opts)
						}
					}
					
				})
			}
		})
	};
	$.fn.mvalidateDestroy=function(){
		var $form=$(this),$fields,
			dataValidate=$form.data(name);
		if($form.is('form') && $.isPlainObject(dataValidate) && typeof(dataValidate.options.namespace) == 'string') {
			$fields = $form.removeData(name).find(allTypes);
			$fields.off('.' + dataValidate.options.namespace);
		}	
		return $form;
	};
	$.fn.mvalidate.errorTipFormat=function(text){
		return '<div class="zvalid-resultformat">'+text+'</div>';
	}
})

css

.field-invalid{
    border-color:#a94442;
}
.field-invalidmsg{
    color:#a94442;
}
.field-validmsg{
    color:#3c763d;
}
.field-tooltipWrap{
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    z-index: 19891014;
}
.field-tooltipInner{
    pointer-events: none;
    display: table;
    position:fixed;
    left:0;
    top:0;
    width:100%;
    height:100%;
}
.field-tooltip{
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}
.field-tooltip .field-invalidmsg,
.field-tooltip .field-validmsg{
    color: #fff;
}
.field-tooltip .zvalid-resultformat{
    display: inline-block;
    position: relative;
    background-color:rgba(0,0,0,0.8);
    color: #fff;
    padding: 10px 15px;
    font-size: 14px;
    border-radius: 6px;
    box-shadow: 0 0 8px rgba(0,0,0,.1);
    pointer-events: auto;
    animation-name:fieldTipBounceIn;
    -webkit-animation-name:fieldTipBounceIn;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-duration: .18s;
    animation-duration: .18s;
}

@-webkit-keyframes fieldTipBounceIn{

  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3);
  }
  100% {
    opacity: 1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}


@keyframes 

{


  0% {
    opacity: 0;
    -webkit-transform: scale3d(.3, .3, .3);
    transform: scale3d(.3, .3, .3);
  }
  100% {
    opacity: 1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}

posted @ 2016-11-04 15:29  TBHacker  阅读(9660)  评论(0编辑  收藏  举报