前言
:表单验证是十分常见的需求。公司做运维系统需要大量的编辑/新增表单,编辑之后提交,提交前需要进行表单验证,验证成功才能发起POST请求。由于项目前端大部分是基于Bootstrap开发的,可看官网 Bootstrap Validator
http://1000hz.github.io/bootstrap-validator/
,感觉比较容易上手。用bootstrap validator有个问题,需验证的input/select等标签的外部需要有一个
<div class="form-group">包着,验证失败时给class="form-group"的div变成红色。
1 <form data-toggle="validator" role="form"> 2 <div class="form-group"> 3 <label for="inputName" class="control-label">Name</label> 4 <input type="text" class="form-control" id="inputName" placeholder="Cina Saffary" required> 5 </div> 6 <div class="form-group has-feedback"> 7 <label for="inputTwitter" class="control-label">Twitter</label> 8 <div class="input-group"> 9 <span class="input-group-addon">@</span> 10 <input type="text" pattern="^[_A-z0-9]{1,}$" maxlength="15" class="form-control" id="inputTwitter" placeholder="1000hz" required> 11 </div> 12 <span class="glyphicon form-control-feedback" aria-hidden="true"></span> 13 <div class="help-block with-errors">Hey look, this one has feedback icons!</div> 14 </div> 15 <div class="form-group"> 16 <label for="inputEmail" class="control-label">Email</label> 17 <input type="email" class="form-control" id="inputEmail" placeholder="Email" data-error="Bruh, that email address is invalid" required> 18 <div class="help-block with-errors"></div> 19 </div> 20 <div class="form-group"> 21 <label for="inputPassword" class="control-label">Password</label> 22 <div class="form-inline row"> 23 <div class="form-group col-sm-6"> 24 <input type="password" data-minlength="6" class="form-control" id="inputPassword" placeholder="Password" required> 25 <div class="help-block">Minimum of 6 characters</div> 26 </div> 27 <div class="form-group col-sm-6"> 28 <input type="password" class="form-control" id="inputPasswordConfirm" data-match="#inputPassword" data-match-error="Whoops, these don't match" placeholder="Confirm" required> 29 <div class="help-block with-errors"></div> 30 </div> 31 </div> 32 </div> 33 <div class="form-group"> 34 <div class="radio"> 35 <label> 36 <input type="radio" name="underwear" required> 37 Boxers 38 </label> 39 </div> 40 <div class="radio"> 41 <label> 42 <input type="radio" name="underwear" required> 43 Briefs 44 </label> 45 </div> 46 </div> 47 <div class="form-group"> 48 <div class="checkbox"> 49 <label> 50 <input type="checkbox" id="terms" data-error="Before you wreck yourself" required> 51 Check yourself 52 </label> 53 <div class="help-block with-errors"></div> 54 </div> 55 </div> 56 <div class="form-group"> 57 <button type="submit" class="btn btn-primary">Submit</button> 58 </div> 59 </form> View Code
一、跳过的坑
后来没用Bootstrap Validator, 用了jquery.validate.js插件。 https://jqueryvalidation.org/ ,接下来学习jquery.validate.js,有点懒,直接用英文,不懂的可以评论问我,我在form表单验证踩了很多坑,比较有体会……
最开始用jquery.validate.js时,用来 验证Bootstrap模态框的Form表单 ,妈蛋,竟然 验证不了 ,根本没有反应。搞了很久很久,才知道是因为用模态框时, submit按钮没有放在Form表单里面,所以触发不了验证 。后来改用Bootstrap Validator,尼妈,得给要验证的input/select标签外的标签(验证不通过会变红)加上class="form-group",但是 加上form-group属性后我的表单样式出错了(变丑了 ),怎么办,我只想给这个标签加上form-group属性,但是不希望它带上form-group的样式,正所谓有名无实……我当时不懂,一直用浏览器调前端界面,然而并没有什么卵用,后来请教隔壁组做前端的PHP大神, 给这个标签的class最后加上自定义的样式,覆盖前面form-group的样式 ,前后只花了一两分钟,顿时膜拜铭哥大佬。比如说A标签的class有两个属性class="a b"当a和b的样式有冲突是,比时a样式是margin-top:10px,而b样式是margin-top:20px,这时会选取class最后的样式,b在a的后面,当a,b样式冲突时,会优先取b的样式。具体代码现在没有,要的话明天去公司的SVN找找看……
后来项目被我改用layer弹框,而不是模态框,老大让我做一个表单验证的接口……
因为总不能每一个HTML文件都写那么多JS来验证Form表单。验证接口参考了老大前公司的代码(TC公司)。
首先,页面初始化完成时,调用表单验证接口 validate_interface
<script> // layer.ready(callback) - 初始化就绪 $(document).ready(function () { var form_obj = $("#edit_instance_data"); validate_interface(form_obj); // 调用包装好的接口进行表单验证与ajax请求 }); </script>
封装好的表单验证接口+Ajax请求接口+关闭layer弹框接口。
接下来用插件自带的invalidHandler得出有多少个标签不通过验证。再利用noty插件弹出提示信息。这里我简单看了noty插件,直接会用就行了。
看我下面的代码closest是什么意思,嗯,当时我也不知道,后来去查了下JQ,知道是从当前标签一层一层外外找,直至找到。
$(element).closest('.selectpicker')
这句代码的意思是从当前标签一层一层往外找,直至找到class="selectpicker"的标签。
看我接口的代码会发现有highlight、success 的一些方法。这主要是因些我的form表单用了bootstrap-select插件来美化select标签,但是jquery.validate.js无法验证bootstrap-select的select标签,只能在提交表单时才会验证。这是个很奇葩的坑,我跳进出很久都出不来。网上stackoverflow看了很多解决方法,也没有什么用,是我姿势不对?
后来在一篇stackoverflow找到解决方法
form_obj.find("select").on('change', function(e) { console.log($(this)); // 手动调用select标签 $('.form-horizontal').validate().element($(this)); });
当验证不通过时,给标签(class:my-validate)加上has-error has-feedback属性,这样标签的边框就会变红。
$(element).closest('.my-validate').addClass('has-error has-feedback');
当验证通过时,移除对应的样式
label.closest('.my-validate').removeClass('has-error has-feedback');
二、以下是接口的代码,希望对你有帮助:
1 // 封装好的表单验证接口与ajax请求 2 function validate_interface(form_obj){ 3 form_obj.validate({ 4 invalidHandler: function(event, validator) { 5 // 验证不通过的数量 6 var errors = validator.numberOfInvalids(); 7 if (errors) { 8 console.log("errors", errors); 9 var msg = errors == 1 ? "你有 1 个必填字段未填,已经加红显示." : "你有 " + errors + " 个必填字段未填,已经加红显示。"; 10 console.log("msg", msg); 11 noty({ 12 text: msg, 13 type: "error", 14 timeout: 1500 15 }); 16 } 17 }, 18 highlight : function(element) { 19 console.log(element.tagName); 20 $(element).closest('.my-validate').addClass('has-error has-feedback'); 21 $(element).closest('.selectpicker').selectpicker('refresh'); 22 }, 23 //验证通过的处理 24 success : function(label) { 25 console.log("label", label); 26 label.closest('.my-validate').removeClass('has-error has-feedback'); 27 28 }, 29 30 submitHandler: function(form) { 31 console.log("form", form); 32 // ajax request after form validate true! 33 ajax_func(); 34 35 } 36 37 38 }); 39 40 41 form_obj.find("select").on('change', function(e) { 42 console.log($(this)); 43 $('.form-horizontal').validate().element($(this)); 44 }); 45 46 // 点击弹出框的确认按钮调用该函数 47 function ajax_func() { 48 var ajax_post_url = form_obj.attr("ajax_post_url"); 49 console.log("form_msg", form_obj.serialize()); 50 $.ajax({ 51 url: ajax_post_url, // 提交的页面 52 data: form_obj.serialize(), // 从表单中获取数据 53 type: "POST", // 设置请求类型为"POST",默认为"GET" 54 error:function (jqXHR, textStatus, errorThrown) { 55 alert(jqXHR.responseText); 56 alert(jqXHR.status); 57 }, 58 success: function(data) { 59 var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引 60 console.log("index", index); 61 parent.layer.close(index); //再执行关闭 62 alert("提交成功"); 63 } 64 }); 65 } 66 } 67 68 69 // interface of close layer 70 function close_layer() { 71 console.log("layer inter close"); 72 var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引 73 parent.layer.close(index); //再执行关闭 74 return false; 75 }
验证一通过则发起ajax请求,ajax请求成功扣则关闭当前layer弹框,对layer不了解的可以看我下篇博客……
三、自定义验证
接下来又有个新需求,DBA腾哥要我验证表单,比如 用户输入只能由字母、数字、下划线组成……还有IP地址,发须是IP的格式才能通过验证 ,给后台发起请求。
这就需要自定义表单验证方法,比如你想验证文本框验证的是不是IP地址,可以自定义表单验证方法,自己 写正则表达式进行匹配 ,匹配不通过是显示自定义的错误信息。
1 // layer.ready(callback) - 初始化就绪 2 $(document).ready(function () { 3 var form_obj = $("#edit_workflow"); 4 5 validate_interface(form_obj); // 调用包装好的接口进行表单验证与ajax请求 6 7 var url = location.search; 8 $("#url").val(url); 9 10 // my first validator function 11 jQuery.validator.addMethod("my_first_validator", function(value, element) { 12 return this.optional(element) || /^[a-zA-Z0-9_]+$/.test(value); 13 }, "用户名只能由字母、数字、下划线组成"); 14 15 // my second validator function 16 jQuery.validator.addMethod("my_second_validator", function(value, element) { 17 return this.optional(element) || /^[^\s]*$/.test(value); 18 }, "密码不能包含空格"); 19 20 // my third validator function 21 jQuery.validator.addMethod("my_third_validator", function(value, element) { 22 // 正则匹配文本框的IP 23 return this.optional(element) || /^(\s)*(([0-9]{1,3}\.){3}[0-9]{1,3}(\s)*)+(\s)*$/.test(value); 24 }, "ip格式不对,多个ip请用换行符分开!"); 25 26 });
至此,表单验证ending,如果你是第一次了解表单验证,想必你看完这篇博客也是一脸蒙逼的,你应该看了官网,我下面选了jquery.validate.js官网我觉得我有必要记录的一部分。可以看看,不爽就自己去看官网。
对了,还有一个坑,百度/谷哥jquery.validate.js,会出现博客园的这篇文章 jQuery验证控件jquery.validate.js使用说明+中文API ,当时我想 自定义错误信息 ,网上很多方法有用如下代码的方法,但我也引入了jquery.metadata.js,然而并没有反应。fuck!
使用class="{}"的方式,必须引入包:jquery.metadata.js 可以使用如下的方法,修改提示内容: class="{required:true,minlength:5,messages:{required:'请输入内容'}}"
解决方法:这个问题的实质是,我要对select标签进行验证,比如该标签是必填的,那我肯定要给标签加上required=“true",但是输入内容长度要如何加在标签?用上面代码的方法是不行的!! 还有,如果你自定义了验证方法,比如前端我自定义验证IP,那我如何让标签验证时调用这写的验证方法。其实很简单,没啥技术含量。看代码,代码现在没有,明天上班再看看
-----------------------分割线-----------------------
四、jquery.validate.js记录
submitHandler
(default:
native for m submit
)
Type: Function ()
Callback for handling the actual submit when the form is valid. Gets the form as the only argument. Replaces the default submit. The right place to submit a form via Ajax after it is validated.
Example: Submits the form via Ajax when valid.
$("#myform").validate({ submitHandler: function(form) { $(form).ajaxSubmit(); } });
Example: Use submitHandler to process something and then using the default submit. Note that "form" refers to a DOM element, this way the validation isn't triggered again.
$("#myform").validate({ submitHandler: function(form) { // do other things for a valid form form.submit(); } });
invalidHandler
Type: Function ()
Callback for custom code when an invalid form is submitted. Called with an event object as the first argument, and the validator as the second.
Example: Displays a message above the form, indicating how many fields are invalid when the user tries to submit an invalid form.
$("#myform").validate({ invalidHandler: function(event, validator) { // 'this' refers to the form var errors = validator.numberOfInvalids(); if (errors) { var message = errors == 1 ? 'You missed 1 field. It has been highlighted' : 'You missed ' + errors + ' fields. They have been highlighted'; $("div.error span").html(message); $("div.error").show(); } else { $("div.error").hide(); } } });
success
If specified, the error label is displayed to show a valid element. If a String is given, it is added as a class to the label. If a Function is given, it is called with the label (as a jQuery object) and the validated input (as a DOM element). The label can be used to add a text like "ok!".
Example: Add a class "valid" to valid elements, styled via CSS.
$("#myform").validate({ success: "valid", submitHandler: function() { alert("Submitted!") } });
Example: Add a class "valid" to valid elements, styled via CSS, and add the text "Ok!".
$("#myform").validate({ success: function(label) { label.addClass("valid").text("Ok!") }, submitHandler: function() { alert("Submitted!") } });
The callback gets passed two arguments:
-
label
Type: jQuery
The error label. Use to add a class or replace the text content.
-
element
Type: Element
The element currently being validated, as a DOMElement.
ignore
(default: ":hidden"
)
Type: Selector
Elements to ignore when validating, simply filtering them out. jQuery's not-method is used, therefore everything that is accepted by not() can be passed as this option. Inputs of type submit and reset are always ignored, so are disabled elements.
Example: Ignores all elements with the class "ignore" when validating.
$("#myform").validate({ ignore: ".ignore" });
highlight
(default: Adds errorClass (see the option) to the element
)
Type: Function ()
How to highlight invalid fields. Override to decide which fields and how to highlight.
Example: Adds the error class to both the invalid element and its label
$("#myform").validate({ highlight: function(element, errorClass, validClass) { $(element).addClass(errorClass).removeClass(validClass); $(element.form).find("label[for=" + element.id + "]") .addClass(errorClass); }, unhighlight: function(element, errorClass, validClass) { $(element).removeClass(errorClass).addClass(validClass); $(element.form).find("label[for=" + element.id + "]") .removeClass(errorClass); } })
The callback gets passed three arguments:
- element
Type: Element
The invalid DOM element, usually an input
.
- errorClass
Type: String
Current value of the errorClass
option.
- validClass
Type: String
Current value of the validClass
option.
unhighlight
(default: Removes the errorClass
)
Type: Function ()
Called to revert changes made by option highlight, same arguments as highlight.
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。