ValidationAPIを使用した標準に対するフォームの検証

かつて、ほとんどの人がAn​​gular 2+を気に入っていました。これは、エンジニアリングパフォーマンスの点で、他の一般的なフロントエンドフレームワークよりも優れた設計のフレームワークです。しかし、彼には非常に奇妙な欠陥もありました。それらの1つは、フォームの検証または再検証を手動で呼び出すことができないことです。これは、少なくとも8番目のバージョンまで観察されました。これは、彼らが反応性を非常に好むということではありませんが、このサブシステムでは、いくつかの反応性の考慮事項により、開発者はバインディングのみを介して検証を実装するように促され、アプリケーション開発者は、フィールドの状態を「手つかず」に設定するなどの問題に目を向けることを余儀なくされ、一般に、高度な一度にいくつかの分野の論理と参加。Angularバリデーターやフレームワークの他のいくつかの機能を扱った経験は、フレームワークやライブラリを使用しなくても、最新のブラウザーで「正しく機能する」フォーム検証にHTML5 APIを使用した後、どれほどエレガントでシンプルであるかという印象を強めました。



要素属性はバリデーターの基礎です。属性を使用して、次の制限をすぐに設定できます。

必須-フィールドは必須です。記入が必要です

最小 最大 ステップ-最小値と最大許容値は、同様に変更するステップ

MINLENGTHMAXLENGTHを-許可された入力文字の数にリミッター

のパターン-正規表現

ないたくさんのようですが、しかし、パターンは私たちに値をチェックするための非常に豊富な機会を与えて、規則的なパターンを簡単にGoogleで検索されています電話番号、電子メールアドレス、URLなどの需要をすぐに確認できます。

フォーム要素に配置されたこれらの属性では、サーバーへの値の送信を実行する同じフォームからボタンを自動的にトリガーすることはできませんが、今日、そのような場合は多くの人にとって時代遅れに見えるかもしれません。しかし、これは問題ではありません。クライアント側のJavaScriptを使用すると、これらすべてのバリデーターを同じ方法またはさらに優れた方法で使用できます。したがって、input type = emailは使用しませんが、入力が電子メールアドレスを生成するためのルールに準拠しているかどうかを確認して、独自のフィールドを作成しようとします。簡単なフォームを作成しましょう:

<form name="myform" id="myform">
   <input type="text" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" placeholder="email here"/>
   <input type="submit">
</form>


バリデーターはすぐに機能し、ボタンを押そうとすると、ブラウザーロケールの言語で警告を発行します。







したがって、mail @ example.comと入力すると、フォームの送信が成功します。

動作を開発するには、フォームインスタンスにアクセスする必要があります。これは、名前、インデックス(id)、またはゼロから始まる順序でグローバルドキュメントを介して行うことができます。

<script type="module">
   document.forms.myform.onsubmit = (event) => {
       console.log('validate');
       return false;
   };
</script>


または、document.getElementById()document.querySelector()などのいずれかのメソッドを使用するセレクターで

結果を確認するには、http-serverを実行します。

npx http-server


コマンドの実行後、ブラウザのコンソール127.0.0.1:8080 /またはコマンドが書き込んだアドレスを開いて、結果をデバッグできます。



送信を通常のボタンに置​​き換えて、例を少し変更して、フォーム検証を手動で呼び出しましょう。

<form id="myform" action="#">
   <input type="text" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="email here" />
   <input type="button" name="subm" value="OK" />
</form>

<script type="module">;
   myform.subm.onclick = (event) => {
       console.log(form.checkValidity());
       return false;
   };
</script>


この例では、IDと名前によるフォームオブジェクトのマッピングが、フォームに関連する子要素に対して機能することがわかります。これは非常にエレガントに見えます。これで、コードはフォームの有効状態をコンソールに出力します。

検証を手動で起動するためのメソッドが存在するからといって、それらを呼び出さずに実行できないわけではありません。

フォームへの入力およびその他の変更の結果は、すぐにその状態に反映されます。これは、有効スタイル無効なスタイルの疑似クラスが存在する場合に現れます色の強調表示を追加すると、検証がどのように機能するかをすぐに確認できます。

<style>
  :valid {
       border: 1px solid green;
   }
  :invalid {
       border: 1px solid red;
   }
</style>








ユーザーがフォームに何かを入力しようとする前にフォームが赤で目を煩わせるのを防ぐために、プレースホルダーを使用してライフハックを使用できます。

<style>
   input:valid {
       border: 1px solid green;
   }
   input:not(:placeholder-shown):invalid {
       border: 1px solid red;
   }
</style>


検証イベントの外部ハンドラーは、フォーム要素に掛けることができます。

<script type="module">
   myform.email.oninvalid = (event) => {
       alert('Wrong email !!11');
   };
   myform.subm.onclick = (event) => {
       console.log(form.checkValidity());
       return false;
   };
</script>


この場合、イベント名によるフックのメカニズムが使用されます。要素でサポートされているイベントがある場合は、+ <event_name>という名前の関数をそれに割り当てることで、起動時に確実に呼び出されるようになります。



そして、ここでもう1つのすばらしい点は、データが入力されたときに呼び出されるのではなく、プログラムで検証を急いでいるときにのみ呼び出されることです。 checkValidity()メソッドを呼び出します。



したがって、この動作を処理できます。

myform.subm.onclick = (event) => {
   if (myform.checkValidity()) {
       alert('Valid !');
   } else {
       alert('Invalid !')
   }
   return false;
};


実際には、検証でフォーム送信手順を中止できない場合は、event.preventDefault()を呼び出す必要がある場合もあります。



checkValidity()アナログであるreportValidity()再検証を引き起こすことなく、結果を返します。



どのフィールドが間違っているかをどうやって知るのですか?



各フォーム入力要素には.validityプロパティがあり、検証メソッドを呼び出す機能もあります。このプロパティの構造は次のとおり です



。ValueState:{

valid-

valueMissingの正しさの一般的な記号-値は必須ですが、

typeMismatchが設定されていません-間違ったタイプの値

が入力されていますpatternMismatch-導入されました値の不一致

tooLong-maxlengthより大きい

値tooShort-

最小

未満の値rangeUnderflow-最小範囲未満の値Overflow-最大値より大きい

stepMismatch-値がステップと一致しません

badInput-入力を値に

強制できませんcustomError-任意のエラー

}



基本的に、ご覧のとおり、標準の検証属性に対応するエラープロパティ。.customErrorは拡張のヘッドルームです。エラー文字列を引数として.setCustomValidity()

メソッド呼び出すことにより、フォーム要素を無効としてマークできます。.validationMessageプロパティを使用してエラーテキストを設定または取得することもできます..。

ブラウザの検証を設定しないために、.willValidateプロパティを使用できます。これは、標準の検証がフィールドで呼び出されるかどうかを示します。

空の文字列を引数として.setCustomValidity()渡すことにより、その状態を有効に戻すことができます。明確にするために同じ方法で値を通常の式と照合する

独自のmy-pattern属性のサポートを追加しましょう

エラーが発生した場合は、ブラウザに表示されたメッセージに加えて、フィールドの横にメッセージが表示されます。

代替フィールドの値が変更され、ボタンが押されると、検証がトリガーされます。

<form id="myform" action="#">
   <div>
       <input type="text" name="email" id="email" value="" pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="email here" />
       <span class="msg"></span>
   </div>
   <div>
       <input type="text" name="customInput" id="customInput" my-pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" required placeholder="text here" />
       <span class="msg"></span>
   </div>
   <button type="submit" name="subm" value="OK">OK</button>
</form>
<style>
   input:valid {
       border: 1px solid green;
   }
   input:not(:placeholder-shown):invalid {
       border: 1px solid red;
   }
</style>
<script type="module">
   myform.customInput.oninvalid = (event) => {
       let el = event.target;
       let msg = el.parentElement.querySelector('.msg');
       msg.innerText = el.validationMessage;
       console.log('oninvalid, id: ', el.id);
   };
   myform.customInput.oninput = (event) => {
       let el = event.currentTarget;
       validateWithMyPattern(el);
       markValidity(el);
   };
   function markValidity(el) {
       el.checkValidity();
       let msg = el.parentElement.querySelector('.msg');
       if (el.validity.valid) {
           msg.innerText = '';
       } else {
           msg.innerText = el.validationMessage;
       }
   }
   function validateWithMyPattern(field) {
       if (field.value) {
           if (field.hasAttribute('my-pattern') &&
               field.value.match(field.getAttribute('my-pattern'))) {
               field.setCustomValidity('');
           } else {
               field.setCustomValidity('My pattern error');
           }
       }
   }
   myform.subm.onclick = (event) => {
       for (let formEl of myform.querySelectorAll('input')) {
           validateWithMyPattern(formEl);
           markValidity(formEl);
       }
       if (myform.reportValidity()) {
           alert('Valid !');
       } else {
           alert('Invalid !')
       }
       return false;
   };
</script>


これで、標準のバリデーターで値をチェックする2つの同様のフィールドと、自分で作成したフィールドがあります。







可能性は豊富ではないように思われるかもしれませんが、それらの助けを借りて、以下を含む任意の検証を実装できます。一般的なフレームワークのように技術的な制限があまりないフィールドグループ。



Validation APIの制限のうち、私はフィールドの最初の無効化のみを覚えています。そのため、プレースホルダーまたは特別な状態をそのまま使用するトリックに加えて、独自の検証ツールを標準の検証ツールと組み合わせることで、入力および送信イベントに対してプログラムですべての検証を実行できます。

タスクを解決するために、フォームのタスクを同時に実行する独自のコンポーネントを作成して、独自の入力要素をサポートする必要がありました。これにより、さまざまな検証と通知の動作を設定し、検証ツールを切断して、標準化された検証APIを使用できます。https://bitbucket.org/techminded/skinny-widgets/src/master/src/form/で確認でき

、この記事のサンプルコードはhttps://bitbucket.org/techminded/myformで確認できます

。 /



All Articles