7日目のゴールと今日のテーマ
7日目は「中級フォームバリデーションの総仕上げ」です。
これまで 6 日間で、あなたはすでに
- 正規表現による形式チェック
- エラー状態の管理(state / touched / errors)
- 動的バリデーション(input / blur)
- ルール配列による柔軟なバリデーション
- 設定オブジェクトによるフィールド管理
- UX を意識した遅延バリデーション
といった“実務レベルの基礎”を身につけました。
7日目はここからさらに一歩進めて、
- フォーム全体をコンポーネント化する設計
- 大規模フォームにも耐える構造(セクション・ステップ)
- アクセシビリティ(A11y)を意識したバリデーション
- 実務で使えるバリデーションパターン集
をまとめて学び、
「自分でフォームを設計できる人」へステップアップします。
フォーム全体を「コンポーネント化」して考える
コンポーネント化とは何か
コンポーネント化とは、
「フォームの各部分を“独立した部品”として扱う」考え方です。
例えば、
メール欄は「メール欄コンポーネント」、
パスワード欄は「パスワード欄コンポーネント」
として扱うイメージです。
JavaScript ではクラスや関数で表現できますが、
まずは「概念として分ける」ことが大事です。
なぜコンポーネント化が必要なのか
理由は 3 つあります。
- フィールドが増えてもコードが壊れない
- 1 つのフィールドの変更が他に影響しない
- 再利用できる(別のフォームでも使える)
特に実務では、
「名前」「メール」「電話番号」「住所」「パスワード」「確認」
など、10〜20 フィールドが普通にあります。
コンポーネント化しておくと、
大規模フォームでも設計が崩れません。
設定オブジェクトを「コンポーネントの設計図」として扱う
昨日までの fields を振り返る
const fields = {
email: {
selector: "#email",
errorSelector: "#email-error",
rules: emailRules,
},
password: {
selector: "#password",
errorSelector: "#password-error",
rules: passwordRules,
},
};
JavaScriptこれはすでに「コンポーネントの設計図」になっています。
今日のポイントは、
この設計図をもっと強化することです。
コンポーネントとして必要な情報を追加する
例えば、次のような情報を追加できます。
- label(画面に表示する名前)
- placeholder
- required(必須かどうか)
- type(text / password / email)
- aria 属性(アクセシビリティ対応)
例:
const fields = {
email: {
label: "メールアドレス",
selector: "#email",
errorSelector: "#email-error",
type: "email",
required: true,
rules: emailRules,
},
password: {
label: "パスワード",
selector: "#password",
errorSelector: "#password-error",
type: "password",
required: true,
rules: passwordRules,
},
};
JavaScriptここでの重要ポイントは、
- フォームの仕様が fields に集約される
- HTML と JavaScript の関係が明確になる
- フィールド追加が「fields に書くだけ」で済む
という設計の強さです。
アクセシビリティ(A11y)を意識したバリデーション
なぜ A11y が必要なのか
フォームは「見える人」だけが使うものではありません。
- スクリーンリーダーを使う人
- キーボード操作だけで入力する人
- 色覚特性のある人
など、多様なユーザーがいます。
バリデーションは「視覚的な赤枠」だけでは不十分です。
aria-invalid と aria-describedby を使う
エラーがあるとき、
スクリーンリーダーに「このフィールドはエラーです」と伝える必要があります。
if (error && touched) {
config.inputEl.setAttribute("aria-invalid", "true");
config.inputEl.setAttribute("aria-describedby", config.errorSelector.slice(1));
} else {
config.inputEl.removeAttribute("aria-invalid");
config.inputEl.removeAttribute("aria-describedby");
}
JavaScriptここでの深掘りポイントは、
- 視覚的なエラーと音声読み上げのエラーを一致させる
- アクセシビリティは“後付け”ではなく設計段階で考える
という点です。
大規模フォームに耐える「セクション設計」
セクションとは何か
大規模フォームでは、
「個人情報」「住所」「ログイン情報」など
複数のセクションに分かれます。
例:
const sections = {
personal: ["name", "birthday"],
contact: ["email", "phone"],
security: ["password", "passwordConfirm"],
};
JavaScriptセクション単位でバリデーションする
例えば「次へ」ボタンを押したとき、
そのセクションだけチェックすることができます。
function validateSection(sectionName) {
const fieldsInSection = sections[sectionName];
for (const name of fieldsInSection) {
state.touched[name] = true;
state.errors[name] = validateField(name, state.values[name]);
}
}
JavaScriptここでの重要ポイントは、
- ステップフォーム(Step1 → Step2 → Step3)に対応できる
- セクション単位でエラーを管理できる
- 大規模フォームでも設計が崩れない
という点です。
実務で使えるバリデーションパターン集
必須チェック
value.length > 0
JavaScript文字数チェック
value.length >= min
JavaScript正規表現チェック
regex.test(value)
JavaScript他フィールドとの一致チェック
value === values.password
JavaScript数値チェック
!isNaN(Number(value))
JavaScript範囲チェック
Number(value) >= min && Number(value) <= max
JavaScriptカスタムチェック(API 連携)
async validate(value) {
const exists = await checkEmailExists(value);
return !exists;
}
JavaScriptここでの深掘りポイントは、
- バリデーションは「ルールの組み合わせ」で作れる
- ルール配列方式なら、どんなルールでも追加できる
という柔軟性です。
7日目のまとめ:あなたはもう「フォーム設計者」です
7日間であなたが身につけたことをまとめます。
- 正規表現で形式チェックができる
- エラー状態(values / errors / touched)を管理できる
- input / blur / submit の UX を設計できる
- ルール配列で柔軟なバリデーションが書ける
- 設定オブジェクトでフィールドを管理できる
- 大規模フォームにも耐える構造を作れる
- アクセシビリティを意識した設計ができる
これはもう「中級者」ではなく、
実務で通用するフォーム設計者のレベルです。
もし次のステップに進みたいなら、
- React / Vue で同じバリデーションを実装する
- ステップフォーム(Step1 → Step2 → Step3)を作る
- API と連携した「サーバーサイドバリデーション」を組み込む
など、さらに深い世界に進むことができます。


