1

所以我按照 Dojo - Using the Dojo JavaScript Library to Build Ajax Applications 中的示例将服务器端验证添加到表单上的用户名验证文本框字段。基本上我添加了一个提交 xhrGet 请求的 usernameOnChange 函数,xhrGet 返回 JSON 并由 usernameValidationHandler 处理。

它工作得很好,但 usernameValidationHandler 仅将工具提示显示消息设置为错误。它不会将该字段设置为无效,因此用户仍然可以提交表单。如何将字段设置为无效,以便表单不会提交?

    <input type="text" id="userName" name="userName" size="20" 
       dojoType="dijit.form.ValidationTextBox"
       trim="true" 
       required="true" 
       onChange="userNameOnChange"
       regExp="\w+"
       invalidMessage="User name is required"
    />

function userNameOnChange() { 
    var userName = dijit.byId("userName").getValue();
    if (userName == "") {
        return;
    }        
    dojo.xhrGet( { 
        url: "validateUserName.jsp?userName=" + userName,
        handleAs: "json",
        handle: userNameValidationHandler
    });
}

function userNameValidationHandler(response) {
    dijit.byId("userName").displayMessage();

    if (!response.valid) {
     var errorMessage = "User name already taken";
        // Display error message as tooltip next to field
        dijit.byId("userName").displayMessage(errorMessage);
        // HOW DO I SET THE FIELD TO BE INVALID NOW???
    }
}
4

2 回答 2

3

当我对控件使用验证方法(验证器)时,我似乎遇到了同样的问题。我认为问题在于 xhrGet 方法的性质,因为它是异步的,因此确定值是否有效的方法在查询完成之前返回。无论如何,这就是我为使其正常工作所做的。如果有其他方法,希望有人可以发布。

 dojo.require("dijit.form.ValidationTextBox");

 function validateUsername(value, constraint) {
   // I believe the whole reason you have to hack at control to get it to 
   // display an error is due to the nature of the xhrGet call. Since the
   // call is being made asychronously, the method would have already
   // returned a result to the html control before query has finished.
   // Therefore you have to do the extra method calls below. Also note
   // that when the form goes for submission, it calls each controls validator
   // method again! Meaning it will query the webpage again.
   var loginID = dijit.byId("user_login");

   var bNoNameFound = ("Error" == loginID.get("state")) ? false : true;

   if ("" == loginID.value) {
     // for some required=true is not kicking in, so we are forcing it.
     bNoNameFound = false;
   } else {
     if (false == loginID._focused) {
       console.log("Checking username...");
       dojo.xhrGet({
         url: "functions/does_user_exist.php?user_login=" + value,
         handleAs: 'text',
         content: {
           l: value
         },
         timeout: 10000,
         load: function(data) {
           if (1 == data) {
             // setting the state to error since the username is already taken
             bNoNameFound = false;
             loginID.set("state", "Error");
             loginID.displayMessage("The username is already taken...");
             // used to change the style of the control to represent a error
             loginID._setStateClass();
             console.log("Invalid username");
           } else {
             bNoNameFound = true;
             loginID.set("state", "");
             loginID.displayMessage("");
           }
         }
       });
     }
   }

   return bNoNameFound;
 }
<input dojoType="dijit.form.ValidationTextBox" type="text" name="user_login" id="user_login" value="" minSize="1" maxSize="25" tabindex="10" required="true" trim="true" regExp="\w+" validator=validateUsername />

注意:我也尝试在 xhrGet 参数中使用“同步”。它也有问题(除了在查询完成之前锁定控件很明显)......

于 2011-01-09T16:03:45.453 回答
0

您可以对小部件进行子类化以覆盖验证器方法。也许链接起来,如果您想要基本功能,那么,如果结果为真,请使用 getXhr 运行您自己的测试并返回结果。

dojocampus 的一个例子只是破坏了验证器方法。这也可能有效,具体取决于您想要做什么。

于 2010-01-12T20:58:18.600 回答