使用Ajax vor验证的dojo中的ValidationTextBox
这是另一个我不敢相信还没有解决的问题。。。 我正在创建一个注册表。现在。。。我需要做一些ajax异步验证。 这就是我现在正在做的(请参阅底部的代码) 这很好,它可以缓存已经检查过的值,它是异步的,等等。但是:使用Ajax vor验证的dojo中的ValidationTextBox,dojo,validation,Dojo,Validation,这是另一个我不敢相信还没有解决的问题。。。 我正在创建一个注册表。现在。。。我需要做一些ajax异步验证。 这就是我现在正在做的(请参阅底部的代码) 这很好,它可以缓存已经检查过的值,它是异步的,等等。但是: 在提交之前,您永远无法确定它是否经过验证。这 这是一个很大的问题,因为我还检查服务器端的东西。但是 还是。。。使此代码在提交时“强制”验证 把它变成一个真正的怪物 似乎每件事都应该做的事情都需要做很多工作 准备出发 (可能与2有关)我想不出一个方法来让这实际上是通用的。我还有10个字段需要
define([
'dojo/_base/declare',
'dijit/form/ValidationTextBox',
'dojo/_base/lang',
'app/globals',
], function(
declare
, ValidationTextBox
, lang
, g
){
return declare('app.ValidationWorkspace', [ ValidationTextBox ], {
ajaxSaidNo: {},
ajaxSaidYes: {},
ajaxRequested: {},
onChange: function(value){
this.validate();
},
validator: function(value){
// console.log("Started validation for " + value);
// Ajax has already said no -- returning false straight away
if(this.ajaxSaidNo[value] ){
this.invalidMessage = 'Workspace taken';
return false;
}
// Run the normal field validators -- if they fail,
// return false
var validation = Validators.workspace(value);
if( ! validation.result){
this.invalidMessage = validation.message;
return false;
// At this point, regexp validators passed and Ajax hasn't said "no".
} else {
// console.log("OK, ajasSaidYes for " + value + " is " + this.ajaxSaidYes[value]);
if(! this.ajaxSaidYes[value] ){
g.stores.workspacesAnon.query({name: value}).then(
lang.hitch(this, function(res){
if(res && res.length ){
this.ajaxSaidNo[value] = true;
//console.log("Added to Ajaxfailed: " + value);
this.validate();
} else {
//console.log("Added to Ajaxsuccess: " + value);
this.ajaxSaidYes[value] = true;
this.validate();
}
})
);
}
return true;
}
},
invalidMessage: "Workspace name not valid",
missingMessage: "Workspace name cannot be empty",
});
}
);
将自己从文本框本身中抽象出来,并在Submit上自定义表单。formDom.submit()之前使用的常规回调只调用formDijit.validate(),并将该布尔值传递给form.submit(如果为false,当然不会进行提交) 换句话说,它期望验证器以阻塞/原子方式运行,并且在每个验证器函数解析返回值之前不会返回 在您的情况下,
dojo.Deferred
很方便。发现自己在form.onSubmit期间从ajax请求中获取响应——一旦所有“正在进行的”ajax调用都解决了,那么如果真的是fire提交
<div tada-dojo-type="dijit.form.Form" id="form">
<div data-dojo-type="app.ValidationWorkspace" name="inputfield" id="inputfield1"></div>
</div>
下面是一个例子,用以填充我在代码库中看不到的缺失内容
<script>
declare('app.ValidationWorkspace', [ ValidationTextBox ], {
invalidMessageLocal : 'JS renders your entry invalid',
invalidMessageServer: 'Server expects something different then you entered',
invalidMessage: '',
regExp: 'Foo*', // validates false if does not start with "Foo"
dfdValidator: undefined,
validator: function() {
var curVal = this.get("value");
if(new RegExp(this.regExp).test(curVal)) {
// client-side passes, run serverside
this.dfdValidator = dojo.xhrGet({
url: 'validate.sapi'+
'?field=' + this.inputNode.name +
'&value='+ value
});
// we cannot truly base anything form-wise here, but we might want
// to set a message (and show it, left out)
this.dfdValidator.then(dojo.hitch(this, function(response) {
this.invalidMessage = this.invalidMessageServer + " : " + response;
}));
}
}
});
</script>
声明('app.ValidationWorkspace',[ValidationTextBox]{
invalidMessageLocal:'JS使您的条目无效',
invalidMessageServer:'服务器要求与您输入的不同',
无效消息:“”,
regExp:'Foo*',//如果不以“Foo”开头,则验证false
dfdValidator:未定义,
验证器:函数(){
var curVal=this.get(“值”);
if(newregexp(this.RegExp.test(curVal)){
//客户端传递,运行服务器端
this.dfdValidator=dojo.xhrGet({
url:'validate.sapi'+
“?字段=”+this.inputNode.name+
“&value=”+value
});
//我们不能在这里真正建立任何形式上的基础,但我们可能需要
//设置消息(并显示,不显示)
this.dfdValidator.then(dojo.hitch)(this,function(response){
this.invalidMessage=this.invalidMessageServer+“:”+响应;
}));
}
}
});
并用类似的方法对提交的表单进行变异:
<script>
dojo.addOnLoad(function() {
dijit.byId('form').onSubmit = function() {
var immediate = true;
var deferreds = [];
dojo.some(dijit.byId('form')._getDescendantFormWidgets(), function(w) {
if(w.validate) {
var tmp = w.validate();
if(!tmp) immediate = false;
else { // check if it has servervalidation in flight
if(w.dfdValidator) {
// it does, store it so we can keep a count and
// not submit before all has passed
deferreds.push(w.dfdValidator);
}
}
}
return tmp; /* if false - one field failed - foreach(some) stops loop */
}); // end dojo.some
var form = this.domNode
var submit = function() {
// logic to submit your values here
store.put(dojo.formToJson(form));
}
// simply stop here if local validators fail
if(immediate == false) {
return false;
} else if(deferreds.length > 0) {
// do not act before all is done
var dfdCounter = new dojo.Deferred();
dfdCounter.then(submit);
var dfdCount = deferreds.length;
var incrCount = 0;
var delayed = true; // delayed validation
dojo.forEach(deferred, function(serverValidatedComplete) {
serverValidatedComplete.then(function(serverresponse) {
incrCount++;
if(/REGEXPTOTESTRESPONSEFALSE/.test(serverresponse))
delayed = false;
if(dfdCount == incrCount && delayed == true)
{ /* YES, all is done, any errors? */
dfdCounter.resolve(/* optional arguments here */);
}
});
});
} else {
// no server validators are running, local validation succeeds
submit();
}
// never return true - or <form> will submit as HTML should be doing
return false;
} // end mutation
});
</script>
dojo.addOnLoad(函数(){
dijit.byId('form')。onSubmit=function(){
var立即=真;
风险值递延=[];
dojo.some(dijit.byId('form')。_getDegenantFormWidgets(),函数(w){
如果(w.validate){
var tmp=w.validate();
如果(!tmp)immediate=false;
else{//检查它是否正在运行servervalidation
if(w.dfdValidator){
//是的,把它储存起来,这样我们就可以清点一下
//在一切都过去之前不要屈服
延迟推送(w.dfdValidator);
}
}
}
返回tmp;/*如果为false-一个字段失败-foreach(某些)停止循环*/
});//结束道场
var form=this.domNode
var submit=function(){
//在这里提交您的值的逻辑
store.put(dojo.formToJson(form));
}
//如果本地验证程序失败,只需在此停止
如果(立即==假){
返回false;
}否则,如果(延迟。长度>0){
//在一切完成之前不要行动
var dfdCounter=new dojo.Deferred();
DFD计数器。然后(提交);
var dfdCount=延迟的长度;
var incrCount=0;
var delayed=true;//延迟验证
forEach(延迟,函数(serverValidatedComplete){
serverValidatedComplete.then(函数(serverresponse){
incrCount++;
if(/REGEXPTOTESTRESPONSEFALSE/.test(serverresponse))
延迟=错误;
if(dfdCount==incrCount&&delayed==true)
{/*是的,全部完成,有错误吗*/
解析(/*此处为可选参数*/);
}
});
});
}否则{
//没有运行服务器验证程序,本地验证成功
提交();
}
//永远不要返回true,否则将按照HTML应该做的那样提交
返回false;
}//末端突变
});
公认的答案可能是正确的解决方案。
但是,对于非阻塞ajax检查,我最终编写了一个简单的mixin:
define([
'dojo/_base/declare',
'dojo/_base/lang',
'app/globals',
], function(
declare
,lang
, g
){
return declare(null, {
ajaxSaidNo: {},
ajaxSaidYes: {},
ajaxRequested: {},
constructor: function(){
// Declaring object variable in constructor to make sure that
// they are not class-wide (since they will be in the prototype)
this.ajaxSaidNo = {};
this.ajaxSaidYes = {};
this.ajaxRequested = {};
},
// Overloads the validator, adding extra stuff
ajaxValidate: function(value, options){
// Set some defaults
options.ajaxInvalidMessage = options.ajaxInvalidMessage || "Value not allowed";
options.ajaxStore = options.ajaxStore || null;
options.ajaxFilterField = options.ajaxFilterField || 'name';
// No ajaxStore query available, return true
if( ! options.ajaxStore ){
return true;
}
// console.log("Started validation for " + value);
// Ajax has already said no -- returning false straight away
if(this.ajaxSaidNo[value] ){
this.invalidMessage = options.ajaxInvalidMessage;
return false;
}
// console.log("OK, ajasSaidYes for " + value + " is " + this.ajaxSaidYes[value]);
if(! this.ajaxSaidYes[value] ){
var filterObject = {};
filterObject[options.ajaxFilterField] = value;
options.ajaxStore.query( filterObject ).then(
lang.hitch(this, function(res){
if(res && res.length ){
this.ajaxSaidNo[value] = true;
//console.log("Added to Ajaxfailed: " + value);
this.validate();
} else {
//console.log("Added to Ajaxsuccess: " + value);
this.ajaxSaidYes[value] = true;
this.validate();
}
})
);
}
return true;
}
});
}
);
然后在文本框(或任何字段)的validate函数中,只需添加最小值即可:
return this.ajaxValidate(value, {
ajaxInvalidMessage: "Workspace taken",
ajaxStore: g.stores.workspacesAnon,
ajaxFilterField: 'name',
});
就这样。。。很好很清晰,你可以把它应用到你喜欢的任何领域。
(如果我收到足够多关于我的方法的鼓舞人心的评论,我会将此作为“接受的”答案…)
Merc.应该将这两个功能划分为两个不同的功能流,我想,但请尝试一下:)虽然我没有运行实际的代码,但您会理解这个想法。。如果您希望在命令中显示invalidMessage,则可能会出现问题-此