jquery.validate插件 – 如何在表单validation之前修改值

我正在使用JörnZaefferer出色的jquery.validation插件 ,我想知道在validation之前是否有一种简单的方法可以自动修剪表单元素?

以下是validation电子邮件地址的表单的缩减但正在运行的示例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script> <script src="http://ajax.microsoft.com/ajax/jquery.validate/1.5.5/jquery.validate.js" type="text/javascript"></script> <script type="text/javascript"> $().ready(function() { $("#commentForm").validate({ rules: { email: { required: true, email: true } } }); }); </script> </head> <body> <form class="cmxform" id="commentForm" method="get" action=""> <label for="cemail">E-Mail:</label><input id="cemail" name="email" class="required email" /> <input class="submit" type="submit" value="Submit"/> </form> </body> </html> 

问题是有些用户会因为意外地在电子邮件地址中input一些空白而感到困惑,例如“test@test.com”。 而表单将不会提交,并有一个错误消息:“请input一个有效的电子邮件地址。” 非技术用户不知道如何发现空白,可能只是退出网站,而不是试图弄清楚他们做错了什么。

无论如何,我希望能够在validation之前链接“ jQuery.trim(value) ”,以便删除空白,并且validation错误永远不会发生?

我可以使用addMethod来build立我自己的电子邮件validationfunction。 但我确定有一个更优雅的解决scheme?

我成功地做到了这一点。

代替:

 Email: { required: true, email: true } 

我做到了这一点:

 Email: { required: { depends:function(){ $(this).val($.trim($(this).val())); return true; } }, email: true } 

这段代码适用于我。 我没有用太多,所以可能有错误。

它包装每个方法,并修剪第一个是价值的元素。

 (function ($) { $.each($.validator.methods, function (key, value) { $.validator.methods[key] = function () { if(arguments.length > 0) { arguments[0] = $.trim(arguments[0]); } return value.apply(this, arguments); }; }); } (jQuery)); 

如果你同时使用select2和validation,我build议把el.val($.trim(el.val())); 如果这样的话: if(el.prop('type') != 'select-multiple'){el.val($.trim(el.val()));} 。 这样,你的jQueryvalidation将按预期行事,它会让你select多个项目。

由于我想在默认情况下我所有的表单上的这种行为,我决定修改jquery.validate.js文件。 我将以下更改应用于onfocusout方法:

原版的:

 onfocusout: function (element, event) { if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { this.element(element); } } 

至:

 onfocusout: function (element, event) { if (element.tagName === "TEXTAREA" || (element.tagName === "INPUT" && element.type !== "password")) { element.value = $.trim(element.value); } if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { this.element(element); } } 

我希望在乞讨和密码结束时允许空格。

autoTrim可以作为属性添加到选项。

下载validator.js时,会有一个名为additional-methods.js的文件,其中包含“nowhitespace”和“lettersonly”方法,它们将删除字段中的任何空白。

 rules: { user_name: { required: true, minlength: 3, nowhitespace: true } } 

我喜欢xuser( https://stackoverflow.com/a/10406573/80002 )的方法,但是,我不喜欢搞乱插件源代码。

所以,我build议这样做:

  function injectTrim(handler) { return function (element, event) { if (element.tagName === "TEXTAREA" || (element.tagName === "INPUT" && element.type !== "password")) { element.value = $.trim(element.value); } return handler.call(this, element, event); }; } $("form").validate({ onfocusout: injectTrim($.validator.defaults.onfocusout) }); 

作为参考,直到我find一个更优雅的解决scheme,我使用addMethod如下:

 // Extend email validation method so that it ignores whitespace jQuery.validator.addMethod("emailButAllowTrailingWhitespace", function(value, element) { return (this.optional(element) || jQuery.validator.methods.email.call(this, jQuery.trim(value), element)); }, "Please enter a valid email"); $().ready(function() { $("#commentForm").validate({ rules: { cemail: { required: true, emailButAllowTrailingWhitespace: true } } }); }); 

注意:这实际上并没有从字段中删除空白,它只是忽略它。 因此,您需要确保在插入数据库之前在服务器端执行trim

从jqueryvalidation器中拉出正则expression式。 只需重写他们的电子邮件验

 $.validator.addMethod("email", function(value, element) { value = value.trim(); return this.optional(element) || /^((([az]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([az]|\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)))@((([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([az]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([az]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); }, "Please enter a valid email."); 

这对我有用:

 $(':input').change(function() { $(this).val($(this).val().trim()); }); 

你能不能将修剪绑定到模糊事件? 就像是…

 $( “#cemail”)。模糊(函数(){
   $(本).VAL(jQuery.trim($(本).VAL());
 });

我发现其中大部分并不完全是需要的。

只使用下面的表单更改,而不是使用关键字,这样您就可以检查其余validation的关键行程了。

将它包含在插件中并不那么整洁,但这是一个可以接受的妥协。

 $('body').on 'change', 'form input[type=text], form input[type=email]', -> $(@).val $.trim($(@).val()) 

添加一个新的jQueryvalidation器方法requiredNotBlank 。 然后将该函数应用于您的元素,而不是默认的required函数。 此解决scheme不会更改原始validation程序源代码,也不会修改默认的required函数,也不会直接修改元素的值。

 // jQuery Validator method for required not blank. $.validator.addMethod('requiredNotBlank', function(value, element) { return $.validator.methods.required.call(this, $.trim(value), element); }, $.validator.messages.required); // ... $('#requiredNotBlankField').rules('add', 'requiredNotBlank'); 

您可以在窗体如此检查之前运行代码:

 var origCheckForm = $.validator.prototype.checkForm; $.validator.prototype.checkForm = function() { $(this.currentForm).find('.CodeMirror').each(function() { if(this.CodeMirror && this.CodeMirror.save) { this.CodeMirror.save(); } }); return origCheckForm.apply(this, arguments); }; 

我用它将所有的CodeMirror实例保存回相应的texareas。 如果你愿意的话,你可以用它来修改值。

为什么不这样做?

validation发生在keyup事件之后。 在keyup中用替代值replace文本框的值(或使用正则expression式来删除任何空格):

 $("#user_name").on("keyup", function(){ $("#user_name").val($.trim($("#user_name").val())); }); 

在jQueryvalidation你会发现下面的代码:

 required: function( value, element, param ) { // Check if dependency is met if ( !this.depend( param, element ) ) { return "dependency-mismatch"; } if ( element.nodeName.toLowerCase() === "select" ) { // Could be an array for select-multiple or a string, both are fine this way var val = $( element ).val(); return val && val.length > 0; } if ( this.checkable( element ) ) { return this.getLength( value, element ) > 0; } return value.length > 0; } 

将value.length更改为$ .trim(value).length