1

これが私の問題です。

私は現在、フォーム検証にjQueryMobileとValidationjQueryプラグインを使用してPhoneGapアプリケーションに取り組んでいます。

名前がデータベースに既に存在するかどうかを確認し、存在する場合は、ユーザーが一意の名前を選択するまでフォームが送信されないように、カスタムルールを設定しようとしています。

問題は私が以前に遭遇したものですが、まだ適切に解決することができていません。SQL selectステートメントを実行するメソッドを呼び出すと、バリデーターが既に完了してfalseがスローされるまで、成功コールバックは完了しません。つまり、ユーザーが一意の名前を入力するとエラーが表示されますが、ユーザーがフィールドの再検証を強制すると、成功コールバックがその間に完了したため、有効になります。

関連するコードは次のとおりです。

var nameUnique;

jQuery.validator.addMethod("nameIsUnique", function(value, element) {
        checkNameSQL();
        return this.optional(element) || nameUnique;
    }, "This name is already in use. Please choose another.");

$('#createForm').validate({
    rules: {
      createName: {
        required: true,
        nameIsUnique: true
      },
      createDescription: {
        required: true
      }
    },
    //snip//
});

function checkNameSQL()
{
var name =   document.forms['createForm'].elements['createName'].value;
if (!(name == null || name == ""))
{
    dbShell.transaction(function(tx) {
       tx.executeSql("SELECT STATEMENT",[name],function(tx,results){if(results.rows.length==0){nameUnique = true;}},errorHandler)
    },errorHandler);
}
}

私はそれが理にかなっているところでそれを単純化し、質問に関係のないコードを切り取った。ご覧のとおり、名前が存在するかどうかを確認するためにメソッドを呼び出しますが、成功コールバック関数がnameUniqueをtrueに設定するようにトリガーする前に、バリデーターによって返され、誤ったエラーが発生します。

これが発生しないようにコードを変更するにはどうすればよいですか?将来、同様の問題を回避するために、どのような一般的なプログラミング手法に従う必要がありますか?ありがとう!

4

1 に答える 1

1

検証を遅らせるために使用できる true と false 以外pendingの値として返すことができます。addMethod()詳細については、検証ライブラリのソースを確認してください。

この方法を試してください:

$.validator.addMethod("nameIsUnique", function(value, element) {
    var validator = this;
    var previous = this.previousValue(element);
    checkNameSQL(value, function(status) {
        var valid = status === true;
        if (valid) {
            var submitted = validator.formSubmitted;
            validator.prepareElement(element);
            validator.formSubmitted = submitted;
            validator.successList.push(element);
            validator.showErrors();
        } else {
            var errors = {};
            var message = status || validator.defaultMessage(element, "remote");
            errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
            validator.showErrors(errors);
        }
        previous.valid = valid;
        validator.stopRequest(element, valid);
    });
    return "pending";
}, "This name is already in use. Please choose another.");

function checkNameSQL(name, callback) {
    if (!(name == null || name == "")) {
        dbShell.transaction(function(tx) {
            tx.executeSql("SELECT STATEMENT", [name], function(tx, results) {
                if (results.rows.length == 0) {
                    nameUnique = true;
                    callback(true);
                }else{
                    callback(false);
                }
            }, errorHandler)
        }, errorHandler);
    }
}

デモについては、このフィドルを確認してください - http://jsfiddle.net/dhavaln/GqsVt/

于 2012-07-01T16:50:51.893 に答える