如何在“setCustomValidity(”...“)之后清除,删除或重置HTML5表单验证状态;”?

时间:2011-09-09 04:36:08

标签: javascript forms html5 validation

如何在setCustomValidity("...");之后清除,删除或重置HTML5表单验证状态?

在Firefox和Chrome中设置空字符串setCustomValidity("");会关闭表单验证错误消息。我不想关闭表单验证错误消息。我想重置验证状态,以便检查下一个答案,并保持显示的验证错误消息。如果未重置验证状态,则即使是下一个正确答案也会错误地显示验证错误消息。


所以不知何故,“清除”意味着“关闭”?

  

如果参数为空字符串,则清除自定义错误。

http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#the-constraint-validation-api


以下是验证测试用例:

<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Validation test case</title>
    </head>
    <body>
        <form id="testForm">
            <input type="text" id="answer" pattern="[A-Za-z]+" autofocus required/>
            <input type="submit" value="OK"/>
        </form>

        <script>
            /*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
            (function ()
            {
                "use strict";

                var form = null;
                var answer = null;

                var isCorrectAnswer = function (value)
                {
                    return (value === "a");
                };

                var closeValidation = function (element)
                {
                    // Close the form validation error message if displayed.
                    element.blur();
                    element.focus();
                };

                var validateForm = function (event)
                {
                    event.preventDefault();
                    event.stopPropagation();

                    var isValidForm = event.target.checkValidity();
                    if (isValidForm)
                    {
                        if (isCorrectAnswer(answer.value))
                        {
                            form.reset();
                            closeValidation(answer);

                            console.log("Correct answer.");
                            alert("Correct answer.");
                        }
                        else
                        {
                            console.log("Incorrect answer.");
                            answer.setCustomValidity("Incorrect answer.");
                            answer.checkValidity();
                            //answer.setCustomValidity("");
                        }
                    }
                };

                window.addEventListener("DOMContentLoaded", function ()
                {
                    form = document.getElementById("testForm");
                    answer = document.getElementById("answer");

                    form.addEventListener("submit", validateForm, false);
                }, false);
            }());
        </script>
    </body>
</html>

输入错误答案,输入任何字母,但输入“a”,然后按Enter键。 输入正确答案“a”,然后按Enter键。

在不更改测试用例的情况下,Opera,Firefox和Chrome中的行为相同(Chrome错误除外)。无论答案是正确还是不正确,验证错误消息都会持续存在。

现在,在取消注释answer.setCustomValidity("");之后,Opera会清除自定义验证错误,但不会关闭验证错误消息,这正是我所期望的。另一方面,Firefox和Chrome都清除了自定义验证错误并关闭验证错误消息(错误?)。


BUG: Chrome首次调用时没有“checkValidity()”。

在Chrome中,answer.checkValidity();在首次提交后未显示验证消息。后续提交显示验证错误消息。

http://code.google.com/p/chromium/issues/detail?id=95970

BUG:在Chrome中,验证错误消息被消隐,但输入更改时未关闭。

http://code.google.com/p/chromium/issues/detail?id=95973


Opera 11.51 Build 1087

Firefox 6.0.2

Google Chrome 13.0.782.220 m

1 个答案:

答案 0 :(得分:13)

如果在'submit'事件处理程序中调用了setCustomValidity(),则不会显示自定义验证消息。

@tkent:

  

我确认Opera 11.50符合您的期望,但Firefox 6和   Chrome 14没有。

     

但是,根据标准,Chrome的行为是正确的。

     

http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#form-submission-algorithm

     
    
        
  1. 如果没有设置从submit()方法提交的标志,那么     submitter元素的无验证状态为false,然后是交互式     验证表单的约束并检查结果:如果结果     是否定的(约束验证结论是有     无效的字段,可能通知用户这个)然后中止     这些步骤。
  2.     
  3. 如果没有设置从submit()方法提交的标志,那么就开火了     一个名为submit的可取消的简单事件,在表单中。如果     事件的默认操作被阻止(即如果事件被取消)     然后中止这些步骤。否则,继续(实际上是默认值     行动是执行提交)。
  4.        
     

浏览器必须在“提交”事件之前调用交互式验证   被解雇了。您需要在'submit'事件之前调用setCustomValidity()   如果您希望浏览器显示验证消息。歌剧似乎   以错误的顺序处理这些步骤。请注意checkValidity()中   你的代码无论如何都没有效果。 checkValidity()从不显示   验证信息。

http://code.google.com/p/chromium/issues/detail?id=95970


[Bug 11287]新:元素中的'setCustomValidity'调用应该使用'oninput'事件......

@Nick:

  元素中的'setCustomValidity'调用应该使用'oninput'   事件...

http://lists.w3.org/Archives/Public/public-html/2010Nov/0186.html


Re:[whatwg]表单元素无效消息

@Mounir Lamouri:

  

所以,你所做的是使元素在无效事件中有效   太晚了。在无效事件之后,Firefox会尝试显示UI   使用validationMessage时返回空字符串   表格有效。如果您不想使用UI,则应取消该事件   完全但仍取消提交。你应该用    onchange / oninput (强调添加)如果您想要表单,则更改有效性状态   提交。

http://www.mail-archive.com/whatwg@lists.whatwg.org/msg23762.html


修复是使用“input”事件处理程序而不是“submit”事件处理程序验证输入。

<!DOCTYPE html>
<html dir="ltr" lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Validation test case</title>
    </head>
    <body>
        <form id="testForm">
            <input type="text" id="answer" pattern="[A-Za-z]+" autofocus required/>
            <input type="submit" value="OK"/>
        </form>

        <script>
            /*jslint browser: true, vars: true, white: true, maxerr: 50, indent: 4 */
            (function (console)
            {
                "use strict";

                var form = null;
                var answer = null;

                var isCorrectAnswer = function (value)
                {
                    return (value === "a");
                };

                var closeValidation = function (element)
                {
                    // Close the form validation error message if displayed.
                    element.blur();
                    element.focus();
                };

                var validateForm = function (event)
                {
                    event.preventDefault();
                    event.stopPropagation();

                    var isValidForm = event.target.checkValidity();
                    if (isValidForm)
                    {
                        console.log("Correct answer.");
                        closeValidation(answer);
                        form.reset();
                    }
                    else
                    {
                        console.log("Incorrect answer.");
                    }
                };

                window.addEventListener("DOMContentLoaded", function ()
                {
                    form = document.getElementById("testForm");
                    answer = document.getElementById("answer");

                    form.addEventListener("submit", validateForm, false);
                    answer.addEventListener("input", function ()
                    {
                        // Only show custom form validation error message if the value matches the pattern.
                        if (answer.value.match(new RegExp(answer.getAttribute("pattern"))))
                        {
                            answer.setCustomValidity(isCorrectAnswer(answer.value) ? "" : "Incorrect answer.");
                        }
                    }, false);
                }, false);
            }(window.console));
        </script>
    </body>
</html>