jQuery Validation with promises

jQuery Validation with promises

本文关键字:promises with Validation jQuery      更新时间:2023-09-26

我正在使用jQuery验证插件作为注册表单,并尝试检查电子邮件地址是否已作为验证的一部分。问题是检查是通过承诺进行的,我不知道如何(或是否)可以使用验证插件使其工作。这是我目前拥有的:

$("#signup form").validate({
    rules: {
        emailSignup: {
            email: true,
            required: true,
            remote: checkAvailable
        }
    }
});
function checkAvailable() {
    var email = $("#emailSignup").val(),
        available;
    App.isEmailAvailable(email)
        .then(function(response) {
            available = response;
        })
        .error(function() {
            available = response;
        });
    setTimeout(function() {
        if (available == true) {
            console.log("is available");
            return true;
        } else {
            console.log("not available");
            return false;
        }
    }, 100);
}

setTimeout只是一种黑客方式,以确保我在尝试记录它之前有响应(我知道这很糟糕,但这只是为了测试)。

问题是,这将正确记录is availablenot available,具体取决于我输入的电子邮件地址,因此它可以一直工作到那时。但是我似乎无法实际将true/false返回到remote方法,以便它启动错误处理。因此,发生的情况是,任何语法上有效的电子邮件都会被标记为有效,即使它根据响应记录not available

这可能吗?


更新:我也尝试在自定义方法中执行此操作:

jQuery.validator.addMethod("email", function(value, element) {
    var field = this,
        available;
    App.isEmailAvailable(value)
        .then(function(response) {
            available = response;
        })
        .error(function() {
            available = response;
        });
    setTimeout(function() {
        if (available == true) {
            console.log("is available");
            return field.optional(element) || /^['w-+'.]+@(['w-]+'.)+['w-]{2,4}$/.test(value);
        } else {
            console.log("not available");
            return false;
        }
    }, 100);
}, jQuery.validator.format("Please enter a valid email address."));

所以这里的想法是它会检查地址是否可用,如果是,那么它将检查它在语法上是否有效。同样,它根据我输入的地址正确记录is available/not available,但不会正确返回true/false以将该字段标记为有效或无效。

基于 "remote" jquery 验证规则:

$.validator.addMethod('users_email_exists', function (value, element) {
    var method = 'remote';
    var previous = this.previousValue(element, method);
    var validator = this;
    if (!this.settings.messages[element.name]) {
        this.settings.messages[element.name] = {};
    }
    previous.originalMessage = previous.originalMessage || this.settings.messages[element.name][method];
    this.settings.messages[element.name][method] = previous.message;
    var optionDataString = $.param({data: value});
    if (previous.old === optionDataString) {
        return previous.valid;
    }
    previous.old = optionDataString;
    this.startRequest(element);
    new Promise(function (fulfill) {
        // YOUR STUFF, YOUR AJAX GET/POST REQUEST AND URL WITH PARAMS
        $.get('/backend/users/ajax/filtered-users-list', {email: value})
            .done(function (data) {

                    // YOUR STUFF TO VALIDATE DATA
                    // IF VALID TRUE -> validation success
                    // IF VALID FALSE -> validation failure

                var valid = !data.length;


                fulfill(valid);
            })
    }).then(function(valid) {
        validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
        if ( valid ) {
            submitted = validator.formSubmitted;
            validator.resetInternals();
            validator.toHide = validator.errorsFor( element );
            validator.formSubmitted = submitted;
            validator.successList.push( element );
            validator.invalid[ element.name ] = false;
            validator.showErrors();
        } else {
            errors = {};
            message = validator.defaultMessage( element, { method: method, parameters: value } );

            // YOUR STUFF, YOUR VALIDATION MESSAGE HERE
            errors[ element.name ] = previous.message = 'EMAIL ALREADY ASSIGNED TO AN USER';

            validator.invalid[ element.name ] = true;
            validator.showErrors( errors );
            }
            previous.valid = valid;
            validator.stopRequest( element, valid );
        });
        return "pending";
    },
    "EMAIL ALREADY ASSIGNED TO AN USER"
);

然后调用自定义规则:

$("#signup form").validate({
rules: {
    emailSignup: {
        email: true,
        required: true,
        users_email_exists: true
        }
    }
});

包含此脚本作为 Promise 类引用:

<!-- promise -->
<script src="https://www.promisejs.org/polyfills/promise-7.0.4.min.js"></script>
<script src="https://www.promisejs.org/polyfills/promise-done-7.0.4.min.js"></script>

你传递给 setTimeout() 的函数将在将来(又名异步)执行 - 在你的 checkAvailable() 完成后。所以它的返回值对于 checkAvailable() 毫无意义。

您应该执行以下操作:

DisableTheForm();
App.isEmailAvailable(value)
        .then(function(response) {
            $("#signup form").validate();
            if( it is valid) {
               EnableTheForm();
               PostFormData(); 
            }
        })
        .error(function() {
           CryAsItIsNotAvailable();
           EnableTheForm();
        });

因此,要根据您的积极反馈进行验证 isEmail可用

您不能使用 remote 方法,因为它正在寻找一个 URL 参数以通过 ajax() "远程"访问。

你显然不会用ajax()调用JavaScript函数,所以使用remote调用JavaScript函数是没有意义的。


您可以使用 .addMethod() 方法创建自定义函数。 但是,如果异步执行其中的任何部分,则会遇到问题,因为在获得结果之前将评估自定义规则。