Skip to content
This page has been auto-translated and may contain errors.View in English

フォーム検証

docs.scrimba.com

フォームはユーザーから入力を収集し、ユーザーはフィールドを空白のままにしたり、メールアドレスを誤入力したり、数字が必要な場所に文字を入力したりします。そのようなデータがコードに到達するのは望ましくありません。送信前に、ブラウザは多くのことをチェックできますが、各フィールドが何を期待するかを説明した場合のみです。その説明はHTMLに直接書き込まれ、この章はそれをどのように書くかについてです。

必須フィールドと入力タイプ

追加できる最も簡単なチェックは、フィールドが満たされていることを述べることと、どの種類の値がそれに属するかを述べることです。

入力に**required**という単語を追加すると、ブラウザはそのフィールドに何かが入るまでフォームの送信を拒否します。これを起こすためにコードを書く必要はありません。属性が指示です。

html
<input type="text" name="full_name" required>

もう半分はtype属性です。これはブラウザに値の形状を伝え、ブラウザがそれをチェックします。type="email"を使用するとブラウザはメールアドレスのような値を確認します。type="number"を使用すると数字のみを受け入れます。日付用のタイプ、ウェブアドレス用のタイプなど、さらに多くのタイプがあります。

医者のオフィスのフォームのようなものだと考えてください。いくつかのボックスは「記入必須」と表示されており、日付のボックスには既に日、月、年のための小さなスロットがあります。紙は、あなたが何かを書く前に、どこに何が行くかを伝えています。

requiredは**ブール属性**です。その存在だけでルールをオンにし、値を取りません。requiredと標記されたコントロールは、空の間はフォーム送信をブロックします。

type属性は二重の役割を果たします。ブラウザが描画するコントロール(日付ピッカー、数値スピナー)を選択し、値に組み込みの制約を設定します:

  • type="email"@とドメイン形のテールが必要です。
  • type="url"は絶対ウェブアドレスとして解析されるものが必要です。
  • type="number"は数値入力のみを受け入れ、minmax、およびstepのロックを解除します。
  • type="tel"は値を制約しませんが、モバイルでは電話キーパッドをもたらします。

他の何かに到達する前に、特定のタイプに到達します。これは最も少ないコードで最もチェック機能です。また、タッチデバイスで表示されるキーボード改善されます。

requiredtypeは、プラットフォームが**制約検証**と呼ぶものの最初の2つのレイヤーです。これはマークアップで宣言するルールに対してコントロールの値をチェックするためのブラウザの組み込みシステムです。requiredは「値の欠落」ルールを設定します。typeはそのタイプに関連付けられた形式ルールを設定します。

typeに関する2つのプロダクション上の注意があります。まず、type="email"は完全なメール仕様に対して検証しません。ブラウザはわざと許容度の高いパターン(文字の実行、@、その後ドット区切りのドメイン)を使用します。より厳密なチェックは実際に配信可能なアドレスを拒否するためです。これは形状チェックとして扱い、アドレスが存在することの証拠ではありません。次に、未知またはサポートされていないtypetype="text"に戻るため、フィールドは古いブラウザで使用不可能になることはなく、追加のチェックを失うだけです。そのグレースフルフォールバックが、互換性表を手にせずに新しいタイプを採用できる理由です。

このタイプはまたオンスクリーンキーボードを駆動し、関連するinputmode属性(検証を変更せずに表示するキーボードレイアウトのヒント)を通じて、そのキーボードを独立して調整できます。タイプを正しくすることは、検証の決定と同じくらい、アクセシビリティと人間工学の決定です。

両方の属性を使用する小さなサインアップフォームは次のとおりです:

html
<form>
  <label>
    メールアドレス
    <input type="email" name="email" required>
  </label>
  <label>
    ウェブサイト
    <input type="url" name="website">
  </label>
  <button>サインアップ</button>
</form>

メールフィールドは入力される必要があり、メールのように見える必要があります。ウェブサイトフィールドはオプションですが、誰かが何かを入力した場合、ウェブアドレスのように見える必要があります。ブラウザはボタンが押された時点で両方をチェックします。

Juno必須フィールドと入力タイプ 2つの小さな単語がここで多くの仕事をします。フィールドにrequiredを置くと、ブラウザは空のものを通さないでしょう。emailnumberのようなtypeを設定すると、値が正しい形状であることをチェックします。フィールドに一致するタイプを選択すると、無料でチェック機能が得られます。
Juno必須フィールドと入力タイプrequiredはブール属性です。あるか、ないかのいずれかで、値は不要です。typeはコントロールを選択してフォーマットルールを設定するため、type="email"@とドメインを望みます。常に最も具体的なタイプから始めます。これは最も少ないマークアップで最もチェック機能であり、モバイルキーボードも改善されます。
Juno必須フィールドと入力タイプ これらは制約検証の最初の2つのレイヤーで、ブラウザの組み込みルールチェッカーです。覚える価値があります。type="email"は緩い形状チェックであり、アドレスが実際であることの証拠ではなく、サポートされていないタイプは静かにtextに戻って壊れるのではなく戻ります。タイプを選択することは、ユーザーが取得するオンスクリーンキーボードを設定するため、アクセシビリティの呼び出しでもあります。

制約属性

「満たされている」と「正しいタイプ」を超えて、多くの場合、制限が必要です。少なくともこの長さの値、それ以上の数値、特定の形式のコード。一握りの属性がこれをカバーしています。

フィールドが受け入れるもの、制限を設定できます。始めるのに役立つ2つ:

html
<input type="text" name="username" maxlength="20">
<input type="number" name="quantity" min="1" max="10">

maxlength="20"はフィールドが20文字を保持したら停止します。minmaxは許可される最小および最大数を設定します。ブラウザはユーザーをこれらの範囲内に保つため、自分自身でチェックする必要はありません。

制約属性の小さなセットがあり、それぞれ1つのルールにマップします:

  • minlength / maxlengthはテキスト値が持つ最小および最大文字数を設定します。
  • min / maxは数値と日付の最小値と最大値を設定します。
  • stepは数値の許可されたインクリメントを設定するため、step="5"は0、5、10を受け入れ、3を拒否します。
  • patternは、許可されたテキストの正確な形状を説明するための**正規表現**(コンパクト表記法)を保持し、値は完全に一致する必要があります。
html
<input type="text" name="username" minlength="3" maxlength="20" required>
<input type="number" name="quantity" min="1" max="10" step="1">
<input type="text" name="pin" pattern="[0-9]{4}" title="4桁">

patterntitleと組み合わせます。一部のブラウザはエラーメッセージでそのテキストを表示し、視力のあるユーザーにフィールドが期待するものを伝えます。CSSでは、:valid:invalidを使用して、現在その制約を通過しているかどうかに基づいてコントロールをスタイルできます。

各制約属性は、ブラウザがコントロールについて発生させることができる1つのフラグに対応し、JavaScriptから検証状態を読むと重要になります。min違反は「範囲下限」を発生させ、maxlength超過は「長すぎます」を発生させ、pattern不一致は「パターン不一致」を発生させます。属性は宣言です。フラグは結果がどのように報告されるかです。

人々を困惑させる2つの詳細があります。patternは暗黙的にアンカーされています。式は値全体に一致する必要があります。まるで開始から終了までをカバーするためにラップされているかのように、pattern="[0-9]{4}"は4桁正確に、「4桁を含む」ではなく、「4桁正確に」を意味します。そしてstepは基地(min、またはそれがない場合はゼロ)から浮動小数点演算を使用して測定されるため、step="0.1"は、バイナリが小数数をどのように表現するかのために通過すると予期する値を拒否する可能性があります。精度が重要な場合は、基数として明示的なminを設定します。

:valid:invalid疑似クラス(位置ではなく状態に基づいて要素と一致するCSSセレクタ)は有用ですが鈍いです。空のrequiredフィールドは最初の描画から:invalidに一致するため、赤でスタイルすることは、入力してから前にエラーでユーザーを迎えます。修正は:user-invalidで、その人がフィールドとやり取りした後にのみ一致し、到着時ではなく有用な場合にフィードバックが到着します。

混乱の大部分を保存するルール:patternは値の一部ではなく、値全体に一致する必要があります。

html
<input
  type="text"
  name="product_code"
  pattern="[A-Z]{2}-[0-9]{3}"
  title="2文字、ハイフン、3桁(例:AB-123)"
  required
>
Juno制約属性 フィールドが必須でタイプされたら、制限を追加できます。maxlengthは文字数を上限し、minmaxは数値を囲みます。ブラウザはユーザーをこれらの範囲内に自動的に保つため、書く必要があるチェック機能が多くあります。
Juno制約属性 セットは小さいです。テキスト用のminlength/maxlength、数値と日付用のmin/max、インクリメント用のstep、正確な形状用のpatternです。patterntitleを与えて、メッセージが何かを意味するようにします。そしてpatternは値全体に一致するため、[0-9]{4}は内部のどこかではなく、合計4桁です。
Juno制約属性 各属性は後で読むことができる1つの有効性フラグにマップするため、マークアップと報告行が並ぶ。2つの落とし穴:patternは終端から終端までアンカーされ、stepは基数から浮動小数点数学を使用するため、精度が重要な場合は明示的なminを設定します。:invalidではなく:user-invalidでスタイルするか、誰かが入力する前にタッチされていないフィールドを赤で描く。

ネイティブ検証フィードバック

ルールを宣言することは物語の半分です。もう半分は、値が何かを破った時にユーザーが見る内容です。

誰かが送信ボタンを押してフィールドが間違っている場合、ブラウザは送信を停止し、問題のある最初のフィールドの横に小さなメッセージを表示してから、カーソルをそこにジャンプさせます。このメッセージを構築する必要はありません。ブラウザはそれを書き、訪問者自身の言語で自動的に表示します。

したがって、requiredメールフィールドが空白のままだと、「このフィールドに記入してください」のようなメッセージが生成され、フォームは修正されるまで送信されません。

検証は送信時に起動します。ブラウザはコントロールを順番に調べ、最初の無効なコントロールを見つけ、それをフォーカスして、問題を説明する小さなメッセージバブルを表示します。すべて通過した場合、フォームは通常どおり送信されます。

CSSを通じてスタイル制御をいくつか取得します。:required:valid:invalid、および:in-rangeを使用してフィールドを視覚的にマークできます。簡単に再スタイルできないのはメッセージバブル自体で、その外観はブラウザのもので、あなたのものではありません。フォームのnovalidate属性を使用して、システム全体をオフに切り替えることもできます。これは、JavaScript全体を検証するつもりの場合に便利です。

css
input:user-invalid {
  border-color: #c0392b;
}
input:user-valid {
  border-color: #2d7a3f;
}

ネイティブフィードバックは便利でほぼ無料であり、出荷されたプロダクトでそれに依存する前に計画する価値がある制限が付属しています。

メッセージバブルは**一時的な**要素です。送信時に表示され、次のインタラクション時に消えて、選択またはスタイルできるドキュメントの一部ではありません。画面リーダーのサポートはブラウザ間で不均一であるため、バブルだけでは、見ることができない人にエラーを発表する信頼できる方法ではありません。そのテキストはまた、ページのlangではなく、ブラウザの言語にローカライズされるため、英語で書かれたフォームは、フランス語に設定されたブラウザを使用している訪問者に対してフランス語のエラーメッセージを表示する場合があります。これはユーザーにとって正しく、開発者にとって驚くべきことです。

送信せずに同じフローをトリガーできます:reportValidity()は必要に応じてチェックを実行してバブルを表示します。ただし、クイックプロトタイプを超えたものの場合、アクセス可能なパターンはネイティブバブル(novalidateを使用して)を抑制し、フィールドに関連付けられたページで独自のエラーテキストを描画することです。見えるようにしたり、スタイルしたり、確実に発表したりできるため。次のセクションはこれをカバーしています。

Junoネイティブ検証フィードバック ここでそれらすべての属性の見返りです。悪いフィールドで送信を押して、ブラウザが小さなメッセージをポップアップして、フィールドを指して、送信を拒否します。そのテキストを書いたことはありません。ブラウザはそれを訪問者の言語で行いました。多くのフォームの場合、これはあなたが必要なすべてのフィードバックです。
Junoネイティブ検証フィードバック チェックは送信時に実行されます。最初の不正なフィールドはフォーカスとメッセージバブルを取得し、フォームは通過するまで保持されます。:user-valid:user-invalidでフィールドをスタイルできますが、バブル自体はブラウザの設計です。JavaScript全体を処理する予定がある場合は、novalidateを使用して全体をオフにします。
Junoネイティブ検証フィードバック バブルは一時的で、スタイル変更不可能で、画面リーダーのサポートは不均一で、そのテキストはページの言語ではなく、ブラウザの言語に従います。プロトタイプに合い、プロダクションに薄い。アクセシビリティが重要な場合は、novalidateを追加し、見えるようにしたり、スタイルしたり、適切に発表したりできるように、ページで独自のエラーテキストを描画します。

JavaScriptがまだ必要な場合

ネイティブ検証は、1つのフィールドをその独自のルールに対してチェックします。実際のチェックの多くはその形状に適合しません。そこがJavaScriptが出番を迎える場所です。

ブラウザが自分自身でチェックできないことがあります。2つのパスワードフィールドが互いに一致しているかどうか。ユーザー名が既に他の誰かに採取されているかどうか。割引コードが本物かどうか。これらのいずれも1つのフィールドの形状についてではないため、属性はなく、チェックを行うために来るJavaScriptです。

これはHTMLの失敗ではありません。組み込みチェックはコードなしで一般的なケースを処理し、JavaScriptは残りを処理します。

ギャップは、複数のフィールドに依存するもの、またはページがまだ持っていない情報です。一般的な例は、2つのパスワードが一致することを確認しています。JavaScriptでそれらを比較し、setCustomValidityを使用してネイティブシステムに結果をフィードバックします。これは、コントロールにカスタムエラーメッセージを設定します(空の文字列は「これは有効です」を意味します):

html
<input type="password" id="password" name="password" required>
<input type="password" id="confirm" name="confirm" required>

比較自体は<script>で実行されます:

js
const password = document.querySelector("#password")
const confirm = document.querySelector("#confirm")

confirm.addEventListener("input", () => {
  // 空の文字列はエラーをクリアしてフィールドを有効にします
  const message = confirm.value === password.value ? "" : "パスワードが一致しません"
  confirm.setCustomValidity(message)
})

フィールドはネイティブ検証のような他の検証に参加し、パスワードが異なる場合、送信をブロックしてメッセージを表示します。ユーザー名の可用性など、サーバーが必要なチェックは同じ形状に従いますが、ネットワークリクエストが返った後にメッセージを設定します。

JavaScriptはフォームコントロールの検証性を読み取り設定するためにブラウザが公開するプロパティとメソッドのセット、制約検証API(セット)を通じてネイティブ検証に到達します。最も使用するピース:

  • setCustomValidity(message)はコントロールにカスタムエラー文字列を設定します。空でない文字列はそれを無効にしてメッセージになります。空の文字列はカスタムエラーをクリアします。
  • validityは読み取り専用ValidityStateオブジェクトです。可能な失敗ごとに1つのブール値(valueMissingtypeMismatchpatternMismatchrangeOverflowtooLongcustomErrorなど)、および全体的な結果用のvalid。フィールドが失敗した理由を見つけるため、その失敗だけではなく読みます。
  • checkValidity()は何も表示せずに真偽値を返し、reportValidity()は同じことをしてネイティブバブルを表示します。

アクセス可能なエラーの場合、色だけでは十分ではありません。赤いボーダーはスクリーンリーダーや、赤と緑を区別できない誰かに何も言いません。エラーテキストをフィールドに関連付けるため、支援技術がそれらを一緒に読みます。入力にaria-describedbyをエラー要素のidに設定します(これはスクリーンリーダーに「このテキストをフィールドの説明として読んでください」と伝えます)、フィールドが失敗している間にaria-invalid="true"を設定します(これはフィールドをエラー状態として発表します):

html
<input
  type="text"
  id="username"
  name="username"
  aria-describedby="username-error"
  aria-invalid="true"
  required
>
<p id="username-error" role="alert">そのユーザー名は既に採取されています。</p>

role="alert"はスクリーンリーダーが表示されるとすぐにメッセージを発表させます。アクセシビリティの章は、コントロールをそれらの説明に関連付けることについてより深く掘り下げています。

これはトレードオフを残します。ネイティブ検証はより少ないコード、プラットフォームとの一貫性、スクリプトが読む前に機能しますが、そのフィードバックはスタイルし、発表することが難しい。カスタム検証はより多くのコードと責任ですが、表現、タイミング、アクセシビリティに対する完全な制御を提供します。ほとんどのプロダクションフォームは両方を使用します。ネイティブ属性をベースラインとして、JavaScriptはレイヤー化され、チェックと属性が到達できないメッセージング属性のために。

どちらを選んでも、1つのルールは曲がりません。クライアント検証は利便性であり、保証ではありません。この章で説明されているすべては訪問者のブラウザで実行され、そこで誰でもそれをオフにしたり、ページを編集したり、フォームにすべて触れずにサーバーにリクエストを直接送信できます。サーバーは、ブラウザのチェックが起こったことがないかのように、受け取るすべての値を再検証する必要があります。ブラウザのチェックをユーザーに往復を節約する高速で親切な最初のパス、ブラウザのチェックをサーバーを実際にデータを保護するチェックとして扱います。

JunoJavaScriptがまだ必要な場合 組み込みチェックは一度に1つのフィールドをカバーするため、「これら2つのパスワードが一致するか」などのフィールドを比較する、または「このユーザー名は無料か」などのサーバーをチェックするには、JavaScriptが必要です。これは普通です。HTMLは毎日のケースを無料で処理し、JavaScriptはそれが自分自身で見ることができないケースをピックアップします。
JunoJavaScriptがまだ必要な場合 チェックが2つのフィールドにわたるか、サーバーが必要な場合、JavaScriptで計算し、setCustomValidityで結果を返してください。メッセージ文字列はフィールドを失敗させます。空の文字列をクリアします。フィールドはネイティブ検証のように参加します。パスワード一致とユーザー名の可用性は古典的な2つです。
JunoJavaScriptがまだ必要な場合 制約検証APIはあなたのフック:メッセージを設定するためのsetCustomValidity、フィールドが失敗した理由を読むためのvalidity、チェックを実行するためのcheckValidityreportValidity。アクセス可能なエラーの場合、テキストをaria-describedbyaria-invalidを使用してフィールドに結合し、色だけではなく。そして、オプションではないもの:ここのすべてのチェックはブラウザで実行されるため、サーバーはすべてを再検証する必要があります。