MDNでフォームについて勉強してみた

## 勉強した記事

https://developer.mozilla.org/ja/docs/Learn/Forms


## 初めてのフォーム
### フォームとは
- ユーザーと ウェブサイトやアプリケーションとの対話の要となるもののひとつ
- フォームの規模が大きくなるとユーザの途中離脱が増えるので、必要な項目のみ設定するのが重要
### formタグ
- action属性でフォームの内容をどこに保存するか指定できる
- methodはgetかpostを設定する
### labelタグ
- labelタグのfor属性とinputタグのid属性でラベルとフォームコントロールを紐付けできる
### inputタグ
- type属性はユーザー操作に関わるので適切なものを選ぶ
- 空要素なので閉じタグは不要
### textAreaタグ
- inputタグと異なり、空要素ではないので閉じタグが必要
### buttonタグ
- type="submit"（デフォルト）で送信できる
### フォームコントロール
- name属性をつけることで名前/値のペアでデータを送信できる
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEZbgxB" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/ZEZbgxB">
  formの勉強</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

参考URL：https://developer.mozilla.org/ja/docs/Learn/Forms/Your_first_form

## フォームの構築方法
### fieldset/legend
- fieldsetとlegendを使うことで一連のフォームコントロール（例：ラジオボタン）をグループ化できる
- アクセシビリティ観点でも重要だが、乱用するのは良くない
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGJEbGE" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/bGJEbGE">
  フォームの構築方法-&lt;fieldset&gt;と&lt;legend&gt;</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### label
- labelタグの中にinputタグを含めることで紐づけられるが、この場合でもfor属性とid属性を設定する方が良い（暗黙的な関係を理解できない支援技術があるため）
- labelタグを使用することで、ラベルをクリックしてフォームコントロールをアクティブにできる
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GRLoKZK" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/GRLoKZK">
  フォームの構築方法-&lt;label&gt;</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 複数のラベルがある場合
- 1つのフォームコントロールに対して複数のラベルを設定したい場合は、label内にフォームコントロールと2つ目のラベルを入れ子にすると良い
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xxeZKdQ" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/xxeZKdQ">
  フォームの構築方法-ラベルが複数ある場合</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

- 入力必須項目の規則は最初に明示しておくのが良い
- 常にスクリーンリーダーで読み上げられるarea-labelに値を設定しておくと信頼性が高い

### アクティブラーニング: フォーム構造を構築する
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="NWmxKBg" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/NWmxKBg">
  フォームの構築方法-フォーム構造を構築する</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### スキルをテストする: フォームの構造1
コーディングしてみた結果
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="VwNeyeM" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/VwNeyeM">
  スキルをテストする: フォームの構造1</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

参考サイト：https://developer.mozilla.org/en-US/docs/Learn/Forms/Test_your_skills:_Form_structure

## 基本的なネイティブフォームコントロール
### テキスト入力フィールド
- readonly：ユーザーは入力値を変更できないが、データは送信される
- disabled：入力値が変更できず、データの送信も行われない
- placeholder：ホック巣の目的を簡単に説明するテキスト
#### 単一行のテキストフィールド
改行を含むテキストを入力した場合、データ送信前にブラウザが改行を取り除く
#### パスワードフィールド
- あくまでインターフェースとして記号に変換しているだけ
- 保護するにはjavascriptでエンコードするか、https通信が必要
#### hiddenコンテンツ
- ユーザーには見えないが他のデータと一緒に送信される
- タイムスタンプなどに使われることがある
- ユーザーには見えないので、意図的に編集したりフォーカスを受けたり、スクリーンリーダーに知らせることはない
### チェック可能項目: チェックボックスとラジオボタン
- 規定でチェック状態にするかどうかを示すためにchecked属性がある
- チェックされている値のみがデータとして送信され、チェックされていない場合はnameも含めて何も送信されない
- チェックされているが値がない場合は、nameがonという値で送信される
- ユーザビリティ/アクセシビリティ観点で、<fieldset>タグと<legend>タグを使用するのが良い
- <labal>タグ/<input>タグはそれぞれ独自のリスト項目に含める必要がある
#### チェックボックス
- 関連するチェックボックスには同じname属性を使用する
- オンとオフになるという性質があるため、トグルスイッチのように見えるボタンとして作成されることもある
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PogZxWm" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/PogZxWm">
  基本的なネイティブフォームコントロール-チェックボックス</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### ラジオボタン
- name属性の値が同じであれば、同じグループのボタンとなる
- グループ内のボタンは1つしかチェックできない
- 一度いずれかのボタンがチェックされると、チェックを外すことはできない
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvZMQJr" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/wvZMQJr">
  基本的なネイティブフォームコントロール-ラジオボタン</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 実際のボタン
- inputのtypeでsubmit/reset/buttonを指定することでボタンにできるが、buttonタグを使った方がスタイルしやすい
#### 画像ボタン
- input要素のtype属性をimageに設定することで作成できる
- 画像上でクリックしたいちのX座標とY座標を送信できる
### ファイルピッカー
- ファイルをサーバーに送信できる
- input要素のtype属性をfileに設定する
- accept属性を使用して、受け入れるファイルの種類を制限することができる
- 複数ファイルを選択できるようにしたい場合はmultiple属性を付加する
### スキルをテストする: 基本的なコントロール
#### 基本操作1
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYoJQWx" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/eYoJQWx">
  スキルをテストする: 基本的なコントロール-基本操作1</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### 基本操作2
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="oNObQwj" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/oNObQwj">
  スキルをテストする: 基本的なコントロール-基本操作2</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### 基本操作3
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExJPOvq" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/ExJPOvq">
  スキルをテストする: 基本的なコントロール-基本操作3</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## HTML5 の入力型
### メールアドレスフィールド
- type="email"で設定する
- メールアドレス以外のコンテンツの場合、ブラウザによってはフォーム送信時にエラーが表示される
#### クライアント側の検証
- サーバ送信前にブラウザ側でエラー検証される
- ただしセキュリティ対策はサーバ側でも行うべき
### 検索フィールド
- type="search"で設定する
- textフィールドとsearchフィールドは以下の点で見た目のスタイル設定が異なる
- searchフィールドの値は同一サイトの複数ページにまたがって自動保存されることがある
### 電話番号フィールド
- type="tel"で設定する
- ユーザーが入力した値に制約をつけない（文字が入っていることもありえる）
### URLフィールド
- type="url"で設定する
- http:のようなプロトコルがない場合や、URLの形式がよくない場合にエラーを報告
### 数値フィールド
- type="number"で設定する
- 数値を増減するためのスピナー形式のボタンがある
- min属性/max属性で最小値と最大値の制約をつけられる
- step属性で増減させる数値を設定できる
- 数値の範囲が大きい場合はtel型が良い選択肢となる場合がある
### スライダーコントロール
- type="range"で設定する
- テキストフィールドより不正確なので、正確な値が必ずしも重要でない数値の選択に使われる
- 現在の値をフィードバックするには<output>要素を導入する
### 日付と時刻ピッカー
#### datetime-local
- 特定のタイムゾーン情報のない日付と時刻を表示して選択する
#### month
- 年月を表示して選択する
#### time
- 時刻の値を表示して選択する
- 12時間のフォーマットで表示されるが、返り値は24時間フォーマット
#### week
- 本年の週の番号を表示して選択する
#### date/time 値の制限
- 日付と時間のコントロールは全てmin/max属性で制約をつけることができる
### 色選択コントロール
- type="color"で設定する
### スキルをテストする: HTML5 コントロール
#### HTMLコントロール1
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="yLreZGp" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/yLreZGp">
  スキルをテストする: HTML5 コントロール-HTMLコントロール1</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### HTMLコントロール2
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="KKYVJEy" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/KKYVJEy">
  スキルをテストする: HTML5 コントロール-HTMLコントロール2</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## その他のフォームコントロール
### 複数行のテキストフィールド
- <textarea>要素を利用する
- ドラッグハンドルが提供されており、テキストエリアサイズをユーザー側で変更できる
#### 複数行レンダリングの制御
- cols:幅（桁数）を指定できる
- rows:行数を指定できる
- wrap:どのようにテキストを折り返すかを指定できる
#### テキストエリアサイズの制御
- cssのresiveプロパティで制御される
### ドロップダウンコントロール
- 選択ボックスと自動保管ボックスという2つの形式のドロップダウンコンテンツがある
#### 選択ボックス
- 1つ以上の<option>要素子要素としてもつ<select>属性で作成される
- 必要に応じて、<option>要素のselected属性でデフォルト値を設定できる
- optgroupは視覚的に関連する値のグループを作成できる
#### 複数選択の選択ボックス
- <select>要素にmultiple属性を追加することで複数の値を選択できる
#### 自動補完ボックス
- <datalist>要素で、フォームウィジェット用の自動補完の提案値を提供できる
- id属性の指定が必要
### その他のフォーム機能
#### メーターとプログレスバー
- <progress>要素でmax属性を用いて指定した最大値まで時間と共に変化する値を表示できる
  - ダウンロードされたファイルの総数の割合や、アンケートで記入された質問の数など、進捗状況の報告に利用できる
- <meter>要素でメーターバーを実装できる
  - lowとhighで範囲を3つに分割する
  - optimum値はmeter要素の最適な値を定義する
### スキルをテストする: その他のコントロール
#### その他のコントロール 1
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="oNObRPO" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/oNObRPO">
  Untitled</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### その他のコントロール 2
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvZMbbg" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/wvZMbbg">
  スキルをテストする: その他のコントロール-その他のコントロール2</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### その他のコントロール 3
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBwbzEz" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/qBwbzEz">
  スキルをテストする: その他のコントロール-その他のコントロール3</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## ウェブフォームへのスタイル設定
### フォームコントロールへのスタイルの設定は難しい
- 以下の要素はほとんどスタイル設定ができず、cssの高度の知識やトリックが必要になる
  - チェックボックスとラジオボタン
  - <input type="search">
- 以下の要素はcssでスタイルを設定できない
  - <input type="color">
  - <input type="datetime-local>のような日時関連コントロール
  - <input type="range">
  - <input type="file>
  - ドロップダウンウィジェットの作成に含まれる要素、<select>,<option>,<optgroup>,<datalist>
  - <progress>と<meter>
## フォームへの高度なスタイル設定
### 見た目: OS レベルのスタイル制御
- appearance: none;を設定することでOSごとのスタイルをリセットできる
### スキルをテストする: 高度なスタイリング
#### 高度なフォーム スタイル 1
## UI擬似クラス
### 利用できる擬似クラスには何があるのか
- `:hover`:マウスポインターを当てたときだけ要素を選択
- `:focus`フォーカスされているとき（キーボードからタブで移動しているとき）のみ、要素を選択
- `:active`:その要素がアクティブ化されいてるとき（クリックされたとき、またはキーボード操作の場合はReturn/Enterキーが押されたとき）
- `:required`/`:optional`:必須または省略可能なフォームコントロールを対象
- `:valid`/`:invalid`、`read-only`/`:read-write`:有効または無効なフォームコントロール、および読み書き可能または読み取り専用のフォームコントロールを対象
- `:checked`/`:indeterminate`/`:dafault`：チェックされているか、不確定な状態か、ページを読み込んだときの規定の選択オプションが対象
### 入力が必須か否かによるスタイル設定
- `<input>`、`<select>`、`<textarea>`は`required`属性で必須かどうかを設定できる
- 必須の場合は`:required`、任意の場合は`:optional`の擬似クラスでスタイルを設定できる
- ただし、アクセシビリティ観点からデザインだけで差異をつけるのはよくない
  - アスタリスク（*）か「必須」ラベルを付与する方が良い
### 擬似クラスでコンテンツを生成する
- `::before`や`::after`という擬似要素と`content`プロパティを使用してコンテンツを表示できる
- DOMに追加されないので、スクリーンリーダーから見えない
- 必須ラベルも擬似クラスで使用するとスクリーンリーダーで二重にアナウンスされない
### データが妥当が否かでコントロールをスタイル設定する
- 請託制限を持つフォームコントロールはデータが有効か無効かの状態に基づいてスタイリングできる
#### :valid と :invalid
- 制約検証が行われないコントロールは常に有効=`:valid`と一致
- `required`が設定されているコントロールで、値がないものは`:invalid`および`:required`と一致
- `<input type="email">`や`<input type="url">`はパターンと一致しなければ`:invalid`と一致
  - ただし、空の場合は`:valid`になる
- `min`属性と`max`属性の範囲外にある場合は`:invalid`と一致するが、`:out-of-range`によっても一致させることができる
#### 範囲内と範囲外のデータ
- 入力された値が範囲外の場合に`:out-of-range`でスタイリングできる
### 有効/無効や読み取り専用/読み書き可能の入力をスタイル設定する
- `:enabled`と`:disabled`を使用して有効/無効のスタイリングができる
#### read-only と read-write
- `read-only`属性で読み取り専用の場合のスタイリングができる
### ラジオボタンとチェックボックスの状態 — チェック済み、既定、不定
- `:default`:ページ読み込み時に`checked`属性が付与されているコントロールに一致
  - チェックが外された以降も一致する
- `:indeterminate`:チェックも解除もされていない状態に一致
#### :default と :indeterminate
- `:default`擬似クラスはユーザーが選択をリセットしたい場合に備えて、規定値が何かを思い出させるのに有用
- `:indeterminate`に概要するのは以下の通り
  - `<input/radio>`で同じnameグループの全てのラジオボタンのチェックが外れている状態
  - `<input/checkbox>`でindetarminateプロパティがJSによってtrueに設定された場合
  - `<progress>`の要素に値がない場合
### その他の擬似クラス
- `:focus-within`はフォーカスを保有する要素に一致
- `:focus-visible`はキーボード操作によってフォーカスを受けたとき
  - タッチやマウスなど他のフォーカスと異なるスタイルを使用したいときに有用
- `:placeholder-shown`:プレースホルダーを表示している場合に一致
## クライアント側のフォーム検証
- クライアント側で検証するとユーザーがすぐに修正できる
- セキュリティ対策にはならないため、サーバ側でセキュリティ択策が必要
### フォーム検証とは何か
- アプリケーションに設定された制約に合っているかチェックする
- ブラウザで行われる検証をクライアント側の検証、サーバ側で行われるものをサーバ側の検証と呼ぶ
- フォームを検証する理由は以下の3つ
  - 正しいデータを正しい書式で入力してほしい
  - ユーザのデータを保護したい
  - 自分達を守りたい
### 様々な種類のフォーム検証
- 組み込みフォーム検証:HTMLフォーム検証の機能を使用する
  - Javascript検証ほどカスタマイズできない
- Javascript検証:カスタマイズ可能だが、全て作成するかライブラリーを使う必要がある
### 組み込みフォーム検証の利用
- 機能は以下の通り
    - `required`:フォームフィールドに入力する必要があるかどうかを指定
    - `minlength`と`maxlength`:テキストデータの最小・最大長を指定する
    - `min`と`max`:数値入力型の最小値、最大値を指定
    - `type`;データを数字にするか、メールアドレスにするか、その他のプリセットされた特定の方にするかを指定
    - `pattern`:データが指定された正規表現に一致するかどうかを指定
- 要素が妥当な場合
    - 要素がcssの`:valid`擬似クラスに一致する
    - ユーザーがデータを送信しようとすると、ブラウザーは止めるものが他になければ、フォームを送信する
- 要素が不正な場合
    - 要素がCSSの`:invalid`擬似クラスに一致し、エラーによっては他のUI擬似クラスに一致することもある
    - ユーザーがデータを送信しようとすると、ブラウザはフォームをブロックしてエラーメッセージを表示する
### 入力要素の制約検証
#### required属性
- required属性を付与してsubmitするとデフォルトのエラーメッセージが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982124/7706ea01-926f-66f0-8383-207a6b2331ba.png)
#### 正規表現での検証
- pattern属性で指定した値以外を入力してsubmitするとエラーが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982124/5fe5bf84-68a4-0d00-6a24-0ece34883e33.png)
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYoZZYv" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/eYoZZYv">
  入力要素の制約の検証-簡単な最初のファイル</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### 入力欄の長さの制約
- `<input>`または`<textarea>`によって作成したテキストフィールドで文字数を制限したいときには`minlength`属性と`maxlength`属性が使用できる
- JSと`maxlength`属性で入力文字数をユーザーにフィードバックし、指定サイズ以下でコンテンツを編集できるようにすることが可能
#### 入力欄の値に制約を加える
- 数値フィールドの場合は`min`属性と`max`属性で入力に制限を加えられる
### JavaScript を使用したフォーム検証
#### 制約検証 API
- 多くのブラウザが制約検証APIに対応している
    - `HTMLButtonElement`（`<button>`要素を表現）
    - `HTMLFieldSetElement`（`<fieldset>`要素を表現）
    - `HTMLInputElement`（`<input>`要素を表現）
    - `HTMLOutputElement`（`<output>`要素を表現）
    - `HTMLSelectElement`（`<select>`要素を表現）
    - `HTMLTextAreaElement`（`<textarea>`要素を表現）
- 上記の要素で利用できるプロパティ
    - `validationMessage`:
        - コントロールが満たさない検証制約を記述したローカライズされたメッセージを返す
        - コントロールが制約検証の候補ではない場合、または要素の値が制約を満たしている場合は空の文字列を返す
    - `validity`:要素の検証状態を説明する`ValidityState`オブジェクト
    - `willValidate`:フォームが送信されるときに要素が検証される場合は`true`を、そうでない場合は`false`を返す
- 制約検証APIでは上の要素や`form`要素に対して以下のメソッドを利用できる
    - `checkValidity()`:要素の値で妥当性の問題がない場合はtrueを返し、そうでない場合は`false`を返す。要素が不正の場合は`invalid`イベントを発生させる
    - `reportValidity()`:イベントを使用して、無効なフィールドを報告する
        - `onSubmit`イベントハンドラーでは`preventDefault()`と組み合わせて使用すると有益
    - `setCustomValudity(message)`:要素に独自のエラーメッセージを追加する
##### 独自のエラーメッセージを実装する
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="mdgrYOx" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/mdgrYOx">
  JavaScript を使用したフォーム検証-独自のエラーメッセージを実装する</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##### より詳細な例
- `novalidate`属性を使用することで、ブラウザの自動検証を無効にできる
    - 自身で確認を行って、フォーム状態に応じたスタイル設定ができる
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="RwOGmLy" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/RwOGmLy">
  JavaScript を使用したフォーム検証-より詳細な例</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### 組み込み API を使用しないフォーム検証
- 制約検証APIを使用できない場合は以下の観点を考慮する必要がある
    - どのような検証を実施すべきか
    - フォームが妥当でない場合に何をすべきか
    - ユーザが不正なデータを修正することをどのように支援できるか
### スキルをテストする: フォームの検証
#### フォーム検証 1
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="WNWGqWO" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/WNWGqWO">
  スキルをテストする: フォームの検証-フォーム検証 1</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### フォーム検証 3
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYvRKvo" data-user="msuzuna" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/msuzuna/pen/LYvRKvo">
  スキルをテストする: フォームの検証-フォーム検証 2</a> by msuzuna (<a href="https://codepen.io/msuzuna">@msuzuna</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## フォームデータの送信
### クライアント側:データ送信方法の定義
#### action属性
- どこにデータを総員するか定義する
#### method属性
- どのようにデータを送信するかを定義する
##### GETメソッド
- サーバに対して指定したリソースを返すよう求める
##### POSTメソッド
- HTTPリクエストの本文で提供したデータを考慮したレスポンスの要求を送信するためのメソッド