jquery验证不等待远程验证返回true,认为表单有效
$("#new_component_form").validate({
errorClass: 'input-error',
rules : {
"comp_data[account_name]" : {
required: true,
remote: {
url: "/validate",
data: {
provider: 'twitter'
}
}
}
},
onsubmit: true,
onfocusout: false,
onkeyup: false,
onclick: false
});
$("#new_component_form").submit(function(){
console.log($(this).valid());
即使该值无效,也会输出 true。我看到验证最终失败并显示错误消息,但表单仍已提交。
$("#new_component_form").validate({
errorClass: 'input-error',
rules : {
"comp_data[account_name]" : {
required: true,
remote: {
url: "/validate",
data: {
provider: 'twitter'
}
}
}
},
onsubmit: true,
onfocusout: false,
onkeyup: false,
onclick: false
});
$("#new_component_form").submit(function(){
console.log($(this).valid());
This outputs true, even if the value is invalid. I see the validation eventually fail and show the error message but the form is still submitted.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
更多
发布评论
评论(9)
从 jQuery Validate 1.11.1(甚至更旧)开始,接受的答案不起作用。另外,这个问题没有简单的答案,解决方案需要在 jQuery Validation 中添加自定义验证方法。
实际上,简单的答案可能就是:如果您只想提交表单,请不要手动调用
valid()
。只需让验证插件为您完成即可。在内部,它将等待所有异步请求完成,然后才允许提交表单。仅当您手动检查valid()
或element()
时,才会出现此问题。但是,您可能需要这样做的原因有很多。例如,我正在处理的页面需要在启用表单的其余部分之前使用远程验证器检查字段的有效性。我可以手动完成,而不是使用 jQuery 验证,但这是重复的工作。
那么,为什么设置
async: false
不起作用呢?如果将 async 设置为 false,请求将同步发出,但是插件无法正确处理此问题。内部remote
函数始终返回“pending”
,这将导致valid()
函数返回true
即使请求已经完成并收到错误响应!它直到稍后才会检查响应的值或显示错误。使用同步回调时,使
valid()
和element()
行为同步的解决方案是添加自定义验证方法。我自己尝试过这个,看起来效果很好。您只需从常规远程验证中复制源代码并修改它以处理同步ajax调用,并且默认情况下是同步的。v1.11.1 中远程函数的源代码从 jquery.validate.js 的第 1112 行开始:
请注意,即使 ajax 调用已完成,它也总是返回“pending”。
要解决此问题,请进行以下修改:
valid
变量的声明移到 ajax 调用和 success 函数之外以创建闭包,并为其分配默认值“pending” 。valid
变量的旧声明更改为赋值。valid
变量而不是常量“pending”。这是插件的完整代码。只需将其保存为 js 文件,并在包含 jQuery 验证后将其包含在您的页面或模板中:
我已经使用自己的表单对其进行了测试,效果非常好。在启用表单的其余部分之前,我可以测试我的元素的有效性。但是,您可能希望设置
onkeyup: false
以防止在每次按键时执行同步回调。我也喜欢使用onfocusout: false
。要使用此功能,只需将验证设置中的“remote”替换为“synchronousRemote”即可。例如:
As of jQuery Validate 1.11.1 (and perhaps even older), the accepted answer does not work. In addition, there is no easy answer to this question, and the solution requires adding a custom validation method to jQuery Validation.
Actually, the easy answer may just be: Don't call
valid()
manually if all you want to do is submit the form. Just let the Validate plugin do it for you. Internally, it will wait for all asynchronous requests to complete before allowing the form to be submitted. This issue only arises when you are manually checkingvalid()
orelement()
.However, there are plenty of reasons why you may need to do that. For instance, the page I am working on needs to check the validity of a field using a remote validator before enabling the rest of the form. I could just do it by hand instead of using jQuery Validation, but that's a duplication of effort.
So, why does setting
async: false
not work? If you set async to false, the request will be made synchronously, however, the plugin doesn't handle this correctly. The internalremote
function always returns"pending"
which will cause thevalid()
function to returntrue
even if the request is already complete and received a false response! It doesn't check the value of the response or show the error until later.The solution to making
valid()
andelement()
behave synchronously when using a synchronous callback is to add a custom validation method. I've tried this myself, and it seems to work fine. You can just copy the source code from the regular remote validation and modify it to handle synchronous ajax calls, and be synchronous by default.The source code of of the remote function in v1.11.1 starts on line 1112 of jquery.validate.js:
Notice how it always returns "pending" even if the ajax call is complete.
To fix this issue, make the following modifications:
valid
variable outside of the ajax call and the success function in order to make a closure, and assign it a default value of "pending".valid
variable to an assignment.valid
variable instead of the constant "pending".Here's the complete code for a plugin to the plugin. Just save this as a js file and include it in your page or template after the include for jQuery Validation:
I've tested this with my own form and it works great. I can test my element for validity before enabling the rest of the form. However, you probably want to set
onkeyup: false
to prevent performing a synchronous callback on every key press. I also like to useonfocusout: false
.To use this, just replace "remote" in your validation settings with "synchronousRemote" everywhere you'd like to use this. For example:
遇到同样的问题,似乎您已将远程调用设置为同步 - async: false
否则
$("form").valid()
将返回 true对于远程验证,请参阅下面我使用的Bumped into the same issue it seems that you have the set the remote call to synchronous - async: false
Otherwise the
$("form").valid()
will return true for the remote validation, please see below what I use这是我们在我的项目中提出的解决方案。
这利用了 $("#form").validate().pendingRequest 将始终 > 的事实。 0 每当有远程验证时。
注意:这不适用于在远程请求中设置
async: true
。Here's a solution that we came up with on my project.
This takes advantage of the fact that $("#form").validate().pendingRequest will always be > 0 whenever there is a remote validation.
Note: this will not work with setting
async: true
in the remote request.解决此问题的最简单方法(此处报告:https://github.com/jzaefferer /jquery-validation/issues/361) 是检查两次表单是否有效:
将远程规则设置为
async:false
并使用以下命令检查有效性valid()
实际上等待调用完成,但不使用它们的返回值。再次调用valid()
会将它们考虑在内。有点丑,但它有效。我正在使用 jquery 2.1.0 和 jquery-validation 1.11.1,顺便说一句。
The easiest way to fix this problem (it's reported here: https://github.com/jzaefferer/jquery-validation/issues/361) is to check twice if the form is valid:
Setting the remote rules to
async:false
and checking for validity usingvalid()
actually waits for the calls to finish, but their return values are not used. Callingvalid()
again takes them into account.A bit ugly but it works. I'm using jquery 2.1.0 and jquery-validation 1.11.1, BTW.
我通过创建一个检查
$("#form").valid()
和$("#form").validate().pendingRequest
的自定义函数解决了这个问题:这基于
$("#form").validate().pendingRequest
始终 > 的假设。 0 在远程
验证请求期间。这可以使用 jquery-validation 1.19.1 进行。I solved this by creating a custom function that checks both
$("#form").valid()
and$("#form").validate().pendingRequest
:This works on the assumption that
$("#form").validate().pendingRequest
will always be > 0 during aremote
validation request. This works using jquery-validation 1.19.1.您可以验证表单两次或检查当前的 ajax 调用是否完成。
或者
到目前为止,我发现的最佳解决方案已在该线程的顶部提到。 https://stackoverflow.com/a/20750164/11064080
但没有适当的解决方案。如果您以相同的形式使用两个远程验证函数,则上述所有方法都将失败。
You could validate the form twice or check for the current ajax call to finish.
or
So far the best solution i found was mentioned in the top of this thread. https://stackoverflow.com/a/20750164/11064080
But there is no proper solution. If you use two remote validation function in the same form all the above approaches will fail.
您必须停止浏览器的正常提交,以防验证返回 false。
You have to stop the normal submit of the browser in case that the validation returns false.
我知道这是补丁但是
我已经通过检查当前ajax是否挂起来修复它
我通过
$.active
检查当前ajax调用,如果没有ajax正在运行它会给你0I know this is patch but
I have fixed it by checking current ajax is pending
I check current ajax call by
$.active
, It will give you 0 if not ajax is running2022 答案:这是针对 Kendo 的,但我不明白为什么你不能将其转换为 jQuery。它检查 ajax 是否在某个时间间隔内处于活动状态(将在远程验证期间)。
2022 answer: This is for Kendo but I don't see why you couldn't convert it to jQuery. It checks if ajax is active on an interval (it will be during remote validation).