1

所以这是我的问题。

我目前正在使用 jQuery Mobile 和用于表单验证的 Validation jQuery 插件开发 PhoneGap 应用程序。

我正在尝试设置一个自定义规则,以便它检查数据库中是否已经存在一个名称,如果是,则阻止提交表单,直到用户选择一个唯一的名称。

这个问题是我以前遇到过但尚未设法正确解决的问题。当我调用执行 SQL 选择语句的方法时,直到验证器已经完成并抛出 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 之前,它正在被验证器返回,从而导致 false 错误。

我应该如何更改我的代码以防止这种情况发生?我应该遵循哪些一般的编程实践来规避未来的类似问题?谢谢!

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 回答