フォームとバリデーション
この章で得られるスキル:
- ✅ バリデーションの必要性を説明できる
- ✅
required属性で必須入力を指定できる - ✅
minlength/maxlengthで文字数制限を指定できる - ✅
min/maxで数値範囲を指定できる - ✅
pattern属性で正規表現バリデーションを指定できる - ✅
placeholder属性で入力例を表示できる
Step 0: まず体験してみよう
説明の前に、まず バリデーションがないと何が困るのか を体験しよう。
シナリオ:会員登録フォーム
以下のような会員登録フォームがあるとする。
バリデーションがない場合の問題:
- 空欄で送信できる
- ユーザー名を入力せずに登録できてしまう
- 不正なメールアドレスを入力できる
- 「abc」だけでも登録できてしまう
- 短すぎるパスワードを設定できる
- 「1」のような1文字のパスワードでも登録できてしまう
やってみよう:バリデーションなしのフォームを試す
以下のフォームで、何も入力せずに「登録」ボタンを押してみよう。空欄のまま送信できてしまう。
なぜバリデーションが必要なのか?
バリデーションがないと、空欄や不正なデータが送信されてしまう。サーバー側でエラーになるか、データベースに不正なデータが保存されてしまう。
やってみよう:バリデーションありのフォームを試す
次に、バリデーションを追加したフォームを試そう。空欄で送信しようとすると、エラーメッセージが表示される。
Step 1: バリデーションとは何か
バリデーション とは、入力されたデータが 正しい形式かどうかを確認 することである。
バリデーションを行うことで:
- 不正なデータの送信を防ぐ
- 空欄、形式違いのデータを受け付けない
- ユーザーに正しい入力方法を伝える
- エラーメッセージで何が間違っているかを示す
- セキュリティを向上させる
- 悪意のあるデータの入力を防ぐ
クライアント側(HTML5)とサーバー側(Springなど)の両方でバリデーションを行うのが基本である。
HTML5のバリデーション機能
HTML5では、属性を追加するだけで、ブラウザが自動的にバリデーションを行ってくれる。
Step 2: required(必須入力)
required属性 を付けると、その入力欄が 必須 になる。
<label for="username">ユーザー名:</label>
<input type="text" id="username" name="username" required>
- 空欄のまま送信しようとすると、エラーメッセージが表示される
- 「このフィールドを入力してください」のようなメッセージ
やってみよう:required属性を試す
以下のフォームで、ユーザー名を空欄のまま送信してみよう。エラーメッセージが表示される。
なぜrequiredが必要なのか?
必須項目を明示することで、ユーザーが入力漏れに気づきやすくなる。サーバー側でも必須チェックをするが、クライアント側で先にチェックすることでユーザー体験が向上する。
チェックボックスでrequiredを使う
<label>
<input type="checkbox" name="agree" required>
利用規約に同意する
</label>
- チェックしないと送信できない
Step 3: minlength/maxlength(文字数制限)
minlength(最小文字数)
<label for="password">パスワード(8文字以上):</label>
<input type="password" id="password" name="password" minlength="8">
- 8文字未満の場合、エラーメッセージが表示される
やってみよう:minlengthを試す
以下のパスワード入力欄に、8文字未満のパスワードを入力して送信してみよう。エラーメッセージが表示される。
なぜminlengthが必要なのか?
パスワードが短すぎると、セキュリティが低下する。8文字以上などの最小文字数を設定することで、安全なパスワードを強制できる。
maxlength(最大文字数)
<label for="nickname">ニックネーム(20文字以内):</label>
<input type="text" id="nickname" name="nickname" maxlength="20">
- 20文字を超えて入力できない(入力が制限される)
やってみよう:maxlengthを試す
以下のニックネーム入力欄に、20文字以上入力しようとしてみよう。20文字を超えて入力できないことを確認しよう。
なぜmaxlengthを使うのか?
データベースに保存できる文字数には上限がある。また、長すぎる入力を防ぐことで、ユーザーインターフェースが崩れることを防げる。
両方を組み合わせる
<input type="password" minlength="8" maxlength="20" required>
- 8文字以上20文字以内のパスワード
maxlengthは 入力を制限 するが、minlengthは エラーを表示 する。
maxlength="20":20文字を超えて入力できないminlength="8":8文字未満で送信しようとするとエラー
Step 4: min/max(数値範囲)
数値の範囲を指定
<label for="age">年齢(0〜120):</label>
<input type="number" id="age" name="age" min="0" max="120" required>
- 0未満または120を超える数値を入力すると、エラーメッセージが表示される
やってみよう:min/maxを試す
以下の年齢入力欄に、0未満や120を超える数値を入力して送信してみよう。エラーメッセージが表示される。
なぜmin/maxが必要なのか?
年齢や個数など、妥当な範囲が決まっている数値には、min/maxを設定することで不正な入力を防げる。
日付の範囲を指定
<label for="birthday">生年月日:</label>
<input type="date" id="birthday" name="birthday" min="1900-01-01" max="2024-12-31">
やってみよう:日付の範囲を試す
以下の日付入力欄で、1900年1月1日から2024年12月31日の範囲内の日付を選んでみよう。
Step 5: pattern(正規表現)
pattern属性 で、正規表現を使った複雑なバリデーションができる。
電話番号の形式チェック
<label for="phone">電話番号(ハイフンなし):</label>
<input type="tel" id="phone" name="phone" pattern="[0-9]{10,11}" required>
[0-9]{10,11}:0〜9の数字が10〜11桁
やってみよう:電話番号のpatternを試す
以下の電話番号入力欄に、10桁または11桁の数字を入力してみよう。それ以外の形式では送信できない。
なぜpatternが必要なのか?
電話番号や郵便番号など、特定の形式が決まっている入力には、正規表現で厳密にチェックすることで不正な入力を防げる。
ユーザー名の形式チェック
<label for="username">ユーザー名(半角英数字のみ):</label>
<input type="text" id="username" name="username" pattern="[a-zA-Z0-9]+" required>
[a-zA-Z0-9]+:半角英数字が1文字以上
やってみよう:ユーザー名のpatternを試す
以下のユーザー名入力欄に、半角英数字以外の文字(ひらがな、記号など)を入力して送信してみよう。エラーが表示される。
なぜ半角英数字のみに制限するのか?
ユーザー名がURLの一部になる場合、全角文字や記号が含まれるとエラーになることがある。半角英数字のみに制限することで、安全にシステムに登録できる。
よく使う正規表現パターン
| 用途 | パターン |
|---|---|
| 半角数字のみ | [0-9]+ |
| 半角英字のみ | [a-zA-Z]+ |
| 半角英数字のみ | [a-zA-Z0-9]+ |
| 電話番号(10-11桁) | [0-9]{10,11} |
| 郵便番号(ハイフンあり) | [0-9]{3}-[0-9]{4} |
正規表現は複雑なので、最初は コピー&ペースト で使って構わない。
必要に応じて、正規表現の詳しい使い方を学ぶと良い。
Step 6: placeholder(入力例の表示)
placeholder属性 で、入力欄に ヒント を表示できる。
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email" placeholder="例:taro@example.com">
- 入力欄が空の状態でヒントが表示される
- ユーザーが入力を始めると、ヒントが消える
やってみよう:placeholderを確認する
以下の入力欄で、placeholderのヒントが表示されることを確認しよう。入力を始めるとヒントが消える。
なぜplaceholderが有用なのか?
placeholderを使うことで、ユーザーがどのような形式で入力すれば良いかが一目でわかる。入力ミスを減らし、ユーザー体験が向上する。
使用例
<input type="text" name="name" placeholder="山田太郎">
<input type="tel" name="phone" placeholder="09012345678">
<input type="date" name="birthday" placeholder="1990-01-01">
placeholderは あくまでヒント である。
必須事項や重要な説明は、<label>やテキストで明示すること。placeholderだけに頼らない。
Step 7: HTML5のバリデーションメッセージ
ブラウザが自動的に表示するエラーメッセージは、カスタマイズできる。
title属性でヒントを追加
<input type="password"
name="password"
minlength="8"
pattern="[a-zA-Z0-9]+"
title="8文字以上の半角英数字で入力してください"
required>
title属性に説明を書くと、エラー時に表示される
やってみよう:title属性を確認する
以下のパスワード入力欄に、不正な値を入力して送信してみよう。title属性に設定したメッセージが表示される。
なぜtitle属性を使うのか?
デフォルトのエラーメッセージだけでは、ユーザーに何が間違っているか伝わりにくい。title属性で具体的な説明を加えることで、ユーザーが正しく入力できるようになる。
JavaScriptでカスタムメッセージ(参考)
const input = document.getElementById('password');
input.setCustomValidity('パスワードは8文字以上で入力してください');
(JavaScriptは本教材の範囲外だが、可能性として知っておくと良い)
演習
この章で学んだ内容を確認するため、以下の演習問題に取り組んでください。
演習問題は、docs/src/questions/frontend/form_validation/フォルダにあります:
- k1.mdx: バリデーションの必要性を説明できる
- w1.mdx: required属性で必須入力を指定できる
- w2.mdx: minlength/maxlengthで文字数制限を指定できる
- w3.mdx: min/maxで数値範囲を指定できる
- w4.mdx: pattern属性で正規表現バリデーションを指定できる
- w5.mdx: placeholder属性で入力例を表示できる
まとめ
この章では、 フォームとバリデーション について学んだ。
🎯 達成できたこと
- ✅ バリデーションの必要性(不正なデータを防ぐ)を理解した
- ✅ required属性で必須入力を指定できるようになった
- ✅ minlength/maxlengthで文字数制限を指定できるようになった
- ✅ min/maxで数値範囲を指定できるようになった
- ✅ pattern属性で正規表現バリデーションを指定できるようになった
- ✅ placeholder属性で入力例を表示できるようになった
📚 学んだ内容
- HTML5のバリデーション属性を使うと、ブラウザが自動でチェックしてくれる
- クライアント側とサーバー側の両方でバリデーションを行うのが基本
requiredで必須、minlength/maxlengthで文字数、min/maxで数値範囲を指定patternで正規表現を使った複雑なバリデーションができるplaceholderは入力のヒントを表示する
🚀 次のステップ
次の章では、 Bootstrap入門 について学ぶ。 CSSフレームワークを使って、効率的に見栄えの良いデザインを作成する。
💡 よくある質問
Q1: HTML5のバリデーションだけで十分か?
A: 十分ではない。サーバー側でも必ずバリデーションを行うべきである。
理由:
- HTML5のバリデーションは、ブラウザの機能を無効にすれば回避できる
- 悪意のあるユーザーが、直接サーバーにデータを送信することもできる
ベストプラクティス:
- クライアント側(HTML5):ユーザーに即座にフィードバックを提供
- サーバー側(Spring):最終的な安全確認
両方を組み合わせることが重要である。
Q2: requiredとplaceholderを同時に使える?
A: できる:
<input type="text" name="name" placeholder="例:山田太郎" required>
placeholderはヒント、requiredは必須チェックである。
Q3: 正規表現が難しくてわからない
A: 最初は コピー&ペースト で使って構わない。
よく使うパターンを覚えておいて、必要に応じて調整すれば良い。
参考サイト:
- Regex101(正規表現のテストツール)
- MDN Web Docs(正規表現の説明)
Q4: エラーメッセージを日本語にできないのか?
A: ブラウザのデフォルトメッセージは、ブラウザの言語設定に依存する。
カスタマイズする場合は、JavaScriptを使う必要がある:
input.addEventListener('invalid', function() {
this.setCustomValidity('このフィールドは必須です');
});
Q5: type="email"だけで十分では?
A: type="email"は基本的なチェックのみである。
より厳密なチェックが必要な場合は、pattern属性を追加する:
<input type="email"
name="email"
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
required>
Q6: バリデーションをスキップする方法は?
A: <form>タグにnovalidate属性を付ける:
<form action="/submit" method="POST" novalidate>
<!-- バリデーションがスキップされる -->
</form>
ただし、通常は使うべきではない。開発中のテスト用である。
Q7: type="number"でminとmaxを指定したのに、手入力で範囲外の値を入力できてしまう
A: これは仕様である。
min/maxは 送信時にチェック されるが、 入力時には制限されない。
送信しようとすると、エラーメッセージが表示される。