web-dev-qa-db-ja.com

「setCustomValidity( "...");」の後にHTML5フォームの検証状態をクリア、削除、またはリセットする方法

setCustomValidity("...");の後でHTML5フォームの検証状態をクリア、削除、またはリセットする方法は?

Firefoxで空の文字列setCustomValidity("");を設定すると、Chromeはフォーム検証エラーメッセージを閉じます。フォーム検証エラーメッセージを閉じたくありません。リセットします検証状態。これにより、次の回答を確認し、表示された検証エラーメッセージを保持できます。検証状態がリセットされない場合、次の正しい回答でも、検証エラーメッセージが誤って表示されます。


では、どういうわけか、「クリア」は「近い」という意味ですか?

引数が空の文字列の場合、カスタムエラーをクリアします。

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=9597

BUG:Chromeでは、入力が変更されたときに検証エラーメッセージが空白になりますが閉じられません。

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


Opera 11.51ビルド1087

Firefox 6.0.2

Google Chrome 13.0.782.220 m

30
XP1

「送信」イベントハンドラーで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要素のno-validate状態がfalseの場合、フォームの制約をインタラクティブに検証し、結果を調べます。結果が負の場合(制約の検証により、無効であったフィールドとおそらくこれをユーザーに通知します)、これらの手順を中止します。
  2. Submit()メソッドから送信されたフラグが設定されていない場合は、フォームでsubmitという名前のキャンセル可能な単純なイベントを発生させます。イベントのデフォルトアクションが阻止された場合(つまり、イベントがキャンセルされた場合)、これらの手順を中止します。それ以外の場合は続行します(事実上、デフォルトのアクションは送信を実行することです)。

ブラウザは、「送信」イベントが発生する前にインタラクティブ検証を呼び出す必要があります。ブラウザに検証メッセージを表示させる場合は、「送信」イベントの前にsetCustomValidity()を呼び出す必要があります。 Operaは、これらの手順を間違った順序で処理しているようです。コードのcheckValidity()は何の影響もないことに注意してください。checkValidity()は検証メッセージを表示しません。

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


[Bug 11287]新規:要素の 'setCustomValidity'呼び出しは 'oninput'イベントを使用する必要があります...

@ニック:

要素内の「setCustomValidity」呼び出しは「oninput」イベントを使用する必要があります...

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


Re:[whatwg]フォーム要素の無効なメッセージ

@Mounir Lamouri:

だから、あなたがやっていることは、遅すぎる無効なイベントで要素を有効にすることです。無効なイベントの後、Firefoxは、validationMessageを使用してUIを表示しようとします。これは、フォームが有効な場合に空の文字列を返します。 UIをまったく使用せずに送信をキャンセルする場合は、イベントをキャンセルする必要があります。フォームを送信する場合は、onchange/oninput(強調を追加)を使用して、有効性の状態を変更する必要があります。

http://www.mail-archive.com/[email protected]/msg23762.html


修正は、「送信」イベントハンドラーの代わりに「入力」イベントハンドラーで入力を検証することです。

<!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>
13
XP1