【问题标题】:Override function focusInvalid in jQuery validation plugin在jQuery验证插件中覆盖函数focusInvalid
【发布时间】:2016-03-26 03:15:42
【问题描述】:

我正在使用 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 中的代码 sn-ps。

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
            }
        }
    });
});

【问题讨论】:

  • 如果您可以提交有错误的表单,那么您已经破坏了插件。我们看不到相关的 HTML 或您对 .validate() 的完整调用,因此问题可能出在任何地方。否则,如果您试图覆盖focusInvalid 处理程序,那么您为什么要修改invalidHandler?它们不一样。
  • 还不确定您还可以尝试什么。但是,invalidHandler 将是下一个合乎逻辑的位置,因为它是在无效表单上触发的。但是,您的函数不会导致表单在无效时提交,因此您将不得不显示足够的代码来复制问题... 表单的相关 HTML 和整个调用到.validate()...减少代码到刚好能重现问题的程度。
  • 好的,谢谢。我创建了一个JSFiddle。这样,应该更容易深入了解这一点。您可以尝试添加 invalidHandler 或 focusInvalid 函数,并且应该能够重现我面临的问题。
  • 我会看一下jsFiddle,同时,请编辑您的OP以包含相关代码。我们不接受 jsFiddle 作为发布代码的替代品。谢谢。请参阅:how-to-ask ~ “如果可以创建一个可以链接到的问题的实时示例(例如,在sqlfiddle.comjsbin.com),那么就这样做 - 但也包括您问题本身的代码。并非每个人都可以访问外部网站,并且链接可能会随着时间的推移而中断。”
  • 当然,我明白你的意思。我在这里粘贴了 HTML 和 JS 代码。

标签: jquery jquery-validate


【解决方案1】:

这是您的 invalidHandler 函数中的这一行导致错误的“输入时提交”,而您仍然有错误,我不知道为什么。

firstInvalidElement.focus();

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

但是,我不知道您为什么需要在这里执行此操作。默认的focusInvalid 处理程序已经将焦点转移到第一个无效字段。即使没有该错误,尝试从invalidHandler 中关注它也是多余的。

演示https://jsfiddle.net/kfopux67/4/

【讨论】:

  • focusInvalid 处理程序不会将焦点带到第一个无效字段。正如开发人员网站上所述:“focusInvalid():通过 validator.focusInvalid() 将最后一个活动或第一个无效元素聚焦在提交上。最后一个活动元素是提交表单时具有焦点的元素,避免窃取其焦点。如果没有焦点元素,则表单中的第一个获取它,除非此选项被关闭。"
  • @gartoffel,这有什么关系?您需要在invalidHandler 中发生焦点(当表单无效时)......并且当表单无效时,它已经将焦点放在第一个无效元素上。请参阅上面的演示。
  • 否则,如果您需要报告错误或抱怨其工作原理,则必须将其带到开发人员的 GitHub 站点。您的代码中确实没有任何问题需要 StackOverflow 社区的帮助。
  • 不幸的是:否。请按照以下步骤操作:不要输入电子邮件地址。然后将光标放在密码字段中并提交。即使第一个无效字段是电子邮件,您也会看到密码字段将成为焦点。所以最后一个活动元素被聚焦,而不是第一个无效元素。对于简短的表格来说这可能还可以,但对于较长的表格来说就很烦人了。
  • 好的,感谢您的帮助。将其标记为“最有帮助”并因此解决。祝你好运!
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    相关资源
    最近更新 更多