jQuery 验证器和使用 AJAX 的自定义规则
Posted
技术标签:
【中文标题】jQuery 验证器和使用 AJAX 的自定义规则【英文标题】:jQuery validator and a custom rule that uses AJAX 【发布时间】:2011-02-07 09:01:54 【问题描述】:我阅读了您关于 jQuery 验证器的回复,您在其中概述了一种根据数据库中的值检查用户名的方法。
我尝试过实现此方法,但无论从 php 文件返回什么,我总是会收到用户名已被占用的消息。
这是自定义方法...
$.validator.addMethod("uniqueUserName", function(value, element)
$.ajax(
type: "POST",
url: "php/get_save_status.php",
data: "checkUsername="+value,
dataType:"html",
success: function(msg)
// if the user exists, it returns a string "true"
if(msg == "true")
return false; // already exists
return true; // username is free to use
), "Username is Already Taken");
这是验证代码...
username:
required: true,
uniqueUserName: true
,
是否有一种特定的方式我应该从 php 返回消息。
谢谢
一个
【问题讨论】:
【参考方案1】:对于其他偶然发现此问题的人,请验证支持“远程”方法,该方法在 2010 年可能不存在:
https://jqueryvalidation.org/remote-method/
$("#myform").validate(
rules:
email:
required: true,
email: true,
remote:
url: "check-email.php",
type: "post",
data:
username: function()
return $("#username").val();
);
【讨论】:
这是发出异步请求还是同步请求? @Raghav,这是一个异步验证 您能告诉我如何延迟这个远程请求吗?【参考方案2】:您正在执行 AJAX 请求,ergo:当您的自定义验证器返回 true 或 false 时,验证已经完成。
您需要使用async
。另见这篇文章:How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?
类似:
function myValidator()
var isSuccess = false;
$.ajax( url: "",
data: ,
async: false,
success:
function(msg) isSuccess = msg === "true" ? true : false
);
return isSuccess;
警告:
从 jQuery 1.8 开始,使用 async: false 和 jqXHR ($.Deferred) 是 已弃用;您必须使用成功/错误/完成回调选项 而不是jqXHR对象的相应方法如 jqXHR.done() 或已弃用的 jqXHR.success()。
【讨论】:
为了让它工作,我不得不将 msg==="true" 更改为 msg===true (Firefox)。顺便感谢您的解决方案! 对于将来遇到此问题的任何人,异步已被弃用。请参阅下面蒂姆的回答。 如果服务器验证需要时间,这将冻结页面。 基于async的贬值:false,我认为这应该不是正确答案【参考方案3】:我花了很长时间才弄清楚如何将包含页面中元素值的 jsonified 字符串放入远程请求中 - 这是多个小时和尝试多个搜索结果的组合结果。
重点:
async:false
已被弃用,
remote:
之后的函数调用是使用元素值创建数据字符串的关键。在data:
为字段返回空白值并将dataType
设置为json 之后尝试从表单访问当前值。
$("#EmailAddress").rules("add",
required: true,
remote: function () // the function allows the creation of the data string
// outside of the remote call itself, which would not
// return a current value from the form.
var emailData = "'address':'" +
$('#SignupForm :input[id$="EmailAddress"]').val() +
"'";
var r =
url: "foobar.aspx/IsEmailAvailable",
type: "post",
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
data: emailData,
dataFilter: function(response)
this.email_run = true; //fix for race condition with next button
return isAvailable(data); //return true or false
;
return r;
,
messages:
remote: "* Email in use"
);
.ASPX 页面:
<input id="EmailAddress" required name="Email" type="email" placeholder="Email Address*" runat="server"/>
C# 代码背后:
[WebMethod]
public static object IsEmailAvailable(string address)...
格式化响应对象:
function isAvailable(data)
var response = JSON.parse(getJsonObject(data));
return (response.isAvailable === "True") ? true : false;
;
//transform response string to a javascript Object()
//http://encosia.com/never-worry-about-asp-net-ajaxs-d-again/
function getJsonObject(data)
var msg = eval('(' + data + ')');
if (msg.hasOwnProperty('d'))
return msg.d;
else
return msg;
;
【讨论】:
关于您的声明 -1. async:false has been deprecated,
.. 是的,但是如果您使用适当的回调/处理程序,例如(complete:
、success:
、error:
)而不是一个 Promise 方法,例如 .then
或 .done
... 在此处查看以下参考 ==> bugs.jquery.com/ticket/11013#comment:40【参考方案4】:
这是我的“老派”技巧...
下面是一个实用函数,它允许通过“jquery.validate.js”库使用“异步”验证。此函数会在用户击键之间产生延迟,否则验证函数“validFunc”将被称为“所有时间”,这在某些情况下性能不佳,尤其是在“服务器端”/“后端”上执行验证的函数(基本上是 ajax 调用) )。这样,“validFunc”验证函数仅在用户停止输入一段时间后才被调用,这也允许在用户输入时进行“实时”验证(jqv 设置上的"onkeyup": true
)。
重要提示:涉及使用“jqvAsyncValid”函数的验证应始终放在最后,以避免由于异步而与其他验证发生冲突。
[...]
"rules":
"field_name":
"required": true,
"maxlength": 12,
"minlength": 4,
// NOTE: Validation involving the use of the "jqvAsyncValid" function. By Questor
"my_custom_ajax_validation": true
,
[...]
答案代码:
// NOTE: Adds the custom validation "my_custom_ajax_validation". By Questor
$.validator.addMethod("my_custom_ajax_validation", function (value, element)
return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);
, "My error message!");
// NOTE: My validation function. By Questor
function myValidationFunc(domElement)
if (someFuncWithAjaxCall(domElement.value) == "ALL_RIGHT!")
return true;
else
return false;
// NOTE: Global "json" variable that stores the "status" ("isValid") and cycle control
// ("toCtrl") of asynchronously validated elements using the "jqvAsyncValid" function.
// By Questor
var jqvAsyncVState = ;
// NOTE: A utility function that allows the use of asynchronous validations with
// "jquery.validate.js". This function creates a delay between one user keystroke and
// another otherwise the validation function "validFunc" will be called "all time"
// which is not very performative in some circumstances and especially problematic
// for functions that perform validations on the serverside/backend (ajax calls basically).
// In this way the "validFunc" validation function is only called when the user stops
// typing for a certain period of time, which also allows a "realtime" validation
// as it occurs while the user is typing. By Questor
// [Ref .: https://jqueryvalidation.org/ ]
//. domElement - DOM element informed by jqv in the "addMethod" for the anonymous
// function;
//. asyncRuleNm - Validation name added via "addMethod";
//. validFunc - Function that will do the validation. Must have the signature
// "funcName(domElement)" returning "true" for valid and "false" for not;
//. jQValidInst - Instance of the current jqv within "addMethod". It is usually
// denoted by "this";
//. toInMsecs - "Timeout" in "milliseconds". If not informed the default will be
// 1500 milliseconds. Be careful not to use a very short timeout especially in
// "ajax" calls so as not to overload the serverside/backend.
// Eg.: `return jqvAsyncValid(element, "my_custom_ajax_validation", myValidationFunc, this);`.
function jqvAsyncValid(domElement, asyncRuleNm, validFunc, jQValidInst, toInMsecs)
if (typeof toInMsecs === "undefined" || toInMsecs === "")
toInMsecs = 1500;
var domEKey = jQValidInst.currentForm.id + domElement.name;
// NOTE: The validation messages need to be "displayed" and "hidden" manually
// as they are displayed asynchronously. By Questor
function errMsgHandler()
if (jqvAsyncVState[domEKey]["isValid"])
// NOTE: If the current error message displayed on the element was that
// set in the rule added via "addMethod" then it should be removed since
// the element is valid. By Questor
// [Ref.: https://***.com/a/11652922/3223785 ,
// https://***.com/a/11952571/3223785 ]
if (jQValidInst.errorMap[domElement.name] == $.validator.messages[asyncRuleNm])
var iMsgNow = ;
iMsgNow[domElement.name] = "";
jQValidInst.showErrors(iMsgNow);
else
var iMsgNow = ;
// NOTE: If the element is invalid, get the message set by "addMethod"
// for current rule in "$.validator.messages" and show it. By Questor
iMsgNow[domElement.name] = $.validator.messages[asyncRuleNm];
jQValidInst.showErrors(iMsgNow);
if (!jqvAsyncVState.hasOwnProperty(domEKey))
// NOTE: Set the global json variable "jqvAsyncVState" the control attributes
// for the element to be asynchronously validated if it has not already been
// set. The key "domEKey" is formed by the "id" of the "form" that contains
// the element and the element's "name". By Questor
jqvAsyncVState[domEKey] =
"toCtrl": null,
"isValid": undefined
;
var useOnKeyup = true;
// NOTE: The "onblur" event is required for "first validation" that only occurs
// in a "blur" event - this is inherent to jqv - and for situations where the
// user types very fast and triggers "tab" and the event "onkeyup" can not deal
// with it. By Questor
domElement.onblur = function (e)
jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
errMsgHandler();
useOnKeyup = false;
if (useOnKeyup)
// NOTE: The strategy with the event "onkeyup" below was created to create
// a "delay" between a "keystroke" and another one otherwise the validation
// function "validFunc" will be called "all time" which is not very performative
// in some circumstances and especially problematic for functions that perform
// serverside/backend validations (ajax calls basically). In this way the
// "validFunc" validation function is only called when the user stops typing
// for a certain period of time ("toInMsecs"). By Questor
domElement.onkeyup = function (e)
// NOTE: Clear the "toCtrl" if it has already been set. This will
// prevent the previous task from executing if it has been less than
// "toInMsecs". By Questor
clearTimeout(jqvAsyncVState[domEKey]["toCtrl"]);
// NOTE: Make a new "toCtrl" set to go off in "toInMsecs" ms. By Questor
jqvAsyncVState[domEKey]["toCtrl"] = setTimeout(function ()
jqvAsyncVState[domEKey]["isValid"] = validFunc(domElement);
errMsgHandler();
, toInMsecs);
;
return jqvAsyncVState[domEKey]["isValid"];
【讨论】:
以上是关于jQuery 验证器和使用 AJAX 的自定义规则的主要内容,如果未能解决你的问题,请参考以下文章
Jquery Validate 相关参数及常用的自定义验证规则