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パラメーターでも「sync」を使用してみました。また、問題もありました(クエリが完了するまでコントロールをロックするという明らかなことは別として)...

于 2011-01-09T16:03:45.453 に答える
0

ウィジェットをサブクラス化して、バリデータメソッドをオーバーライドできます。基本的な機能が必要な場合は、連鎖して、結果が true の場合は、getXhr を使用して独自のテストを実行し、結果を返します。

dojocampus での例では、バリデータ メソッドを単純に破壊しています。やりたいことによっては、それもうまくいくかもしれません。

于 2010-01-12T20:58:18.600 に答える