在jQuery验证插件中覆盖函数focusInvalid

时间:2015-04-12 12:57:33

标签: jquery jquery-validate

我正在使用jQuery validation plugin并尝试根据我的需要调整 focusInvalid 功能。在提交(包含无效字段)时,我想:

  • 滚动到表单的第一个无效元素
  • 专注于此元素

验证必须在iPad / iPhone / ......上与在桌面上的行为几乎相同,这不是一件容易的事,因为人们只能根据用户触发器将一个元素集中在iOS中。但这是一个不同的故事 - 有关详细信息,请参阅iPad HTML focus

我的第一个方法是直接修改jquery.validate.js以测试我的改编。这就是我想出的:

focusInvalid: function() {
    if ( this.settings.focusInvalid ) {
        try {
            var firstInvalidElement = $(this.errorList[0].element);
            $('html,body').scrollTop(firstInvalidElement.offset().top);
            firstInvalidElement.focus()
        } catch ( e ) {
            // ignore IE throwing errors when focusing hidden elements
        }
    }
}

按预期工作。

现在我想在外部覆盖 focusInvalid 的默认行为(如:不修改原始jQuery验证源代码)。

这是我到目前为止所尝试的内容:

所以,例如:

invalidHandler: function(form, validator) {
    var errors = validator.numberOfInvalids();
    if (errors) {                    
        var firstInvalidElement = $(validator.errorList[0].element);
        $('html,body').scrollTop(firstInvalidElement.offset().top);
        firstInvalidElement.focus();
    }
}

不幸的是,如果我按ENTER键而不是使用提交按钮,我现在可以提交表单(即使仍有无效字段)。如果我删除此自定义invalidHandler,则验证不会出现此行为。

这种行为改变的想法来自何处?


修改

我创建了一个JSFiddle来证明这个问题。为了重现:

  • 输入有效的电子邮件地址
  • 按ENTER键

修改

以下是JSFiddle中粘贴的代码片段。

HTML:

<div class="pre-login">
    <form action="login" method="post" id="login">
        <div class="form-group">
            <input type="email" class="form-control" name="email" id="email" placeholder="Email Address" autofocus="autofocus" required />
        </div>
        <div class="form-group">
            <input type="password" class="form-control" name="pass" id="pass" placeholder="Password" required />
        </div>
        <button type="submit" class="btn btn-success btn-block">Submit</button>
    </form>
</div>

JavaScript的:

$(function () {
    $.validator.setDefaults({
        highlight: function (element) {
            $(element).closest('.form-group').addClass('has-error');
        },
        unhighlight: function (element) {
            $(element).closest('.form-group').removeClass('has-error');
        },
        errorElement: 'span',
        errorClass: 'error-message',
        errorPlacement: function (error, element) {
            if (element.parent('.input-group').length) {
                error.insertAfter(element.parent());
            } else {
                error.insertAfter(element);
            }
        }
    });

    $('#login').validate({
        invalidHandler: function(form, validator) {
            var errors = validator.numberOfInvalids();
            if (errors) {                    
                var firstInvalidElement = $(validator.errorList[0].element);
                $('html,body').scrollTop(firstInvalidElement.offset().top);
                firstInvalidElement.focus();
            }
        },
        rules: {
            email: {
                required: true,
                email: true
            },
            pass: {
                required: true
            }
        }
    });
});

2 个答案:

答案 0 :(得分:0)

您的invalidHandler函数中的这一行是导致错误的&#34;提交输入&#34;虽然你仍然有错误,但我不知道为什么。

firstInvalidElement.focus();

focusInvalid设置为false无效。也许这是一个你应该在his GitHub page上向开发者报告的错误。 focusInvalid()函数在插件的内部submit处理函数中使用。)

然而,我不知道为什么你甚至需要在这里做到这一点。默认的focusInvalid处理程序已将焦点置于第一个无效字段。即使没有这个错误,尝试从invalidHandler内集中它也是多余的。

DEMO https://jsfiddle.net/kfopux67/4/

答案 1 :(得分:0)

我知道这是一篇非常古老的帖子,但它可能对其他人有所帮助。你只需要将focusInvalid设为false并编写一个invalidHandler,它将关注第一个错误元素(这里是第一个文本框)

$("form").validate({
    focusInvalid: false,
    invalidHandler: function() {
      $(this).find(":input.error:first").focus();
    }
});