JavaScript requiredでフォーム必須入力を完全マスター!動的バリデーションの実装方法
こんにちは、とまだです。
フォームを作っていて、「この項目を必須にしたいけど、条件によって必須かどうか変えたい」と悩んだことはありませんか?
私も最初は、HTMLのrequired
属性とJavaScriptをどう組み合わせればいいのか、本当に迷いました。
今回は、JavaScriptでrequired属性を自在に操る方法を、実例を交えながら徹底解説します。動的なフォームバリデーションが、思っているより簡単に実装できることをお伝えしますね。
JavaScript requiredとは?フォーム入力の必須制御を理解する
HTMLのrequired属性:まずは基本を押さえよう
JavaScriptでrequiredを操作する前に、HTMLの基本を確認しましょう。
required属性は、フォームの入力欄を必須項目にするHTML5の属性です。
<input type="text" name="username" required>
このように書くだけで、ブラウザが自動的に「この項目は必須ですよ」とチェックしてくれます。
身近な例で言うと、レストランの予約フォームを思い浮かべてください。
名前と電話番号は必須だけど、特別な要望は任意。これをHTMLで表現すると、このようになります。
<form>
<input type="text" name="name" placeholder="お名前" required>
<input type="tel" name="phone" placeholder="電話番号" required>
<textarea name="request" placeholder="ご要望(任意)"></textarea>
<button type="submit">予約する</button>
</form>
requiredが付いている項目を空のまま送信しようとすると、ブラウザがエラーメッセージを表示してくれます。
なぜJavaScriptでrequiredを操作する必要があるのか
「HTMLだけでできるなら、なぜJavaScriptが必要なの?」
そう思いますよね。
実は、実際のWebサービスでは状況に応じて必須項目が変わることがよくあるんです。
例えば、こんなケース:
配送先の選択
- 「自宅に配送」を選んだら、住所入力は不要
- 「別の住所に配送」を選んだら、住所入力が必須
会員登録フォーム
- 「法人」を選んだら、会社名が必須
- 「個人」を選んだら、会社名は不要
このような動的な制御は、HTMLだけでは実現できません。
JavaScriptの出番というわけです。
requiredエラーの仕組みと表示タイミング
required属性によるエラーチェックは、フォーム送信時に行われます。
エラーが発生すると、このようになります。
- フォームの送信がキャンセルされる
- 最初のエラー項目にフォーカスが移動
- エラーメッセージがポップアップ表示
ただし、このデフォルトの動作には制限があります。
- エラーメッセージのデザインを変更できない
- 表示位置を調整できない
- 複数のエラーを同時に表示できない
だからこそ、JavaScriptでカスタマイズする価値があるんです。
JavaScriptでrequired属性を動的に追加・削除する基本テクニック
setAttribute()メソッドでrequiredを追加する方法
では、実際にJavaScriptでrequired属性を操作してみましょう。
最も基本的な方法はsetAttribute()
メソッドです。
// 要素を取得
const emailInput = document.getElementById('email');
// required属性を追加
emailInput.setAttribute('required', '');
ポイントは、required属性の値は空文字列でOKということ。
HTMLの論理属性(boolean attribute)は、存在するだけで「true」を意味するんです。
removeAttribute()でrequiredを削除する実装例
required属性を削除する時はremoveAttribute()
を使います。
// required属性を削除
emailInput.removeAttribute('required');
実践的な例を見てみましょう:
<label>
<input type="checkbox" id="newsletter">
ニュースレターを購読する
</label>
<input type="email" id="email" placeholder="メールアドレス">
<script>
const checkbox = document.getElementById('newsletter');
const emailInput = document.getElementById('email');
checkbox.addEventListener('change', function() {
if (this.checked) {
// チェックされたらメールアドレスを必須に
emailInput.setAttribute('required', '');
} else {
// チェックを外したら必須を解除
emailInput.removeAttribute('required');
}
});
</script>
プロパティを使った簡潔な書き方
実は、もっと簡単な方法があります。
required
プロパティを直接操作する方法です:
// required属性を追加
emailInput.required = true;
// required属性を削除
emailInput.required = false;
先ほどの例を書き直すと:
checkbox.addEventListener('change', function() {
emailInput.required = this.checked;
});
たった1行で済みました!
どちらの方法を使うかは好みですが、私はプロパティを使う方法をおすすめします。
コードが短くて読みやすいからです。
実践的なJavaScript required活用パターン5選
パターン1:チェックボックスに連動した必須項目制御
よくある「その他」欄の実装を見てみましょう。
<form id="surveyForm">
<p>好きなプログラミング言語は?</p>
<label><input type="radio" name="lang" value="js"> JavaScript</label>
<label><input type="radio" name="lang" value="python"> Python</label>
<label><input type="radio" name="lang" value="other"> その他</label>
<input type="text" id="otherLang" placeholder="言語名を入力" style="display: none;">
<button type="submit">送信</button>
</form>
<script>
const radioButtons = document.querySelectorAll('input[name="lang"]');
const otherInput = document.getElementById('otherLang');
radioButtons.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'other') {
otherInput.style.display = 'block';
otherInput.required = true;
} else {
otherInput.style.display = 'none';
otherInput.required = false;
otherInput.value = ''; // 値もクリア
}
});
});
</script>
パターン2:選択値によって変わる必須フィールド
会員種別によって必須項目が変わるフォームです:
<form>
<select id="memberType">
<option value="">会員種別を選択</option>
<option value="personal">個人会員</option>
<option value="corporate">法人会員</option>
</select>
<div id="personalFields" style="display: none;">
<input type="text" id="fullName" placeholder="氏名">
</div>
<div id="corporateFields" style="display: none;">
<input type="text" id="companyName" placeholder="会社名">
<input type="text" id="department" placeholder="部署名">
</div>
</form>
<script>
const memberType = document.getElementById('memberType');
const personalFields = document.getElementById('personalFields');
const corporateFields = document.getElementById('corporateFields');
memberType.addEventListener('change', function() {
// 全てのフィールドを一旦非表示&必須解除
personalFields.style.display = 'none';
corporateFields.style.display = 'none';
document.getElementById('fullName').required = false;
document.getElementById('companyName').required = false;
document.getElementById('department').required = false;
// 選択に応じて表示&必須設定
if (this.value === 'personal') {
personalFields.style.display = 'block';
document.getElementById('fullName').required = true;
} else if (this.value === 'corporate') {
corporateFields.style.display = 'block';
document.getElementById('companyName').required = true;
document.getElementById('department').required = true;
}
});
</script>
パターン3:複数条件を組み合わせた高度な制御
パスワードの確認フィールドを例に、複雑な条件を実装してみます:
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirmPassword');
const showPassword = document.getElementById('showPassword');
// パスワードが入力されたら確認も必須に
password.addEventListener('input', function() {
confirmPassword.required = this.value.length > 0;
});
// パスワード表示時は確認不要
showPassword.addEventListener('change', function() {
if (this.checked) {
confirmPassword.required = false;
confirmPassword.style.display = 'none';
} else {
confirmPassword.style.display = 'block';
confirmPassword.required = password.value.length > 0;
}
});
パターン4:エラーメッセージのカスタマイズ
デフォルトのエラーメッセージを変更する方法です:
const phoneInput = document.getElementById('phone');
phoneInput.addEventListener('invalid', function(e) {
e.preventDefault(); // デフォルトの動作を停止
if (this.validity.valueMissing) {
this.setCustomValidity('電話番号は必須項目です');
} else if (this.validity.patternMismatch) {
this.setCustomValidity('正しい電話番号の形式で入力してください');
}
});
// 入力時にカスタムメッセージをリセット
phoneInput.addEventListener('input', function() {
this.setCustomValidity('');
});
パターン5:フォーム全体のバリデーション管理
最後に、フォーム全体を管理する実装パターンです:
class FormValidator {
constructor(formId) {
this.form = document.getElementById(formId);
this.rules = new Map();
}
// ルールを追加
addRule(fieldId, condition) {
this.rules.set(fieldId, condition);
}
// 全てのルールを評価
validate() {
this.rules.forEach((condition, fieldId) => {
const field = document.getElementById(fieldId);
field.required = condition();
});
}
}
// 使用例
const validator = new FormValidator('myForm');
validator.addRule('email', () => {
return document.getElementById('subscribe').checked;
});
validator.addRule('phone', () => {
return document.getElementById('contactMethod').value === 'phone';
});
// 何かが変更されたら再評価
document.getElementById('myForm').addEventListener('change', () => {
validator.validate();
});
よくあるエラーと解決方法
「required属性が効かない」問題の原因と対策
required属性を設定したのに効かない...よくある原因はこれらです:
1. フォーム要素の外にある
<!-- ❌ ダメな例 -->
<input type="text" required>
<button onclick="submit()">送信</button>
<!-- ✅ 良い例 -->
<form>
<input type="text" required>
<button type="submit">送信</button>
</form>
2. novalidate属性が設定されている
<!-- novalidateがあるとバリデーションが無効に -->
<form novalidate>
<input type="text" required> <!-- 効かない! -->
</form>
3. JavaScriptでpreventDefault()している
// submitイベントを止めるとバリデーションも止まる
form.addEventListener('submit', (e) => {
e.preventDefault(); // これがあるとrequiredチェックされない
});
タイミングの問題:DOMContentLoadedの重要性
要素が存在する前にJavaScriptが実行されるとエラーになります:
// ❌ ダメな例
const input = document.getElementById('myInput');
input.required = true; // エラー:inputがnull
// ✅ 良い例
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('myInput');
input.required = true; // OK!
});
ブラウザ互換性とポリフィルの考え方
required属性は主要ブラウザで広くサポートされていますが、古いブラウザでは使えません。
対策として、JavaScriptでフォールバック処理を実装できます:
// required属性がサポートされているかチェック
if (!('required' in document.createElement('input'))) {
// サポートされていない場合の代替処理
document.getElementById('myForm').addEventListener('submit', (e) => {
const inputs = e.target.querySelectorAll('[required]');
for (let input of inputs) {
if (!input.value.trim()) {
e.preventDefault();
alert(input.placeholder + 'は必須項目です');
input.focus();
return;
}
}
});
}
まとめ:JavaScript requiredで作る使いやすいフォーム
JavaScriptでrequired属性を操作する方法、いかがでしたか?
重要なポイントをまとめると:
- 基本は
element.required = true/false
で簡単に制御 - チェックボックスやセレクトボックスと連動させて動的に変更
- エラーメッセージもカスタマイズ可能
- フォーム要素内で使うことを忘れずに
最初は複雑に感じるかもしれませんが、一つずつ試していけば必ず理解できます。
もっと体系的にJavaScriptを学びたい方は、JavaScript学習完全ガイドもぜひご覧ください。
フォームは、ユーザーとWebサイトをつなぐ大切な接点です。
required属性を上手に使って、ユーザーに優しいフォームを作っていきましょう!
著者について

とまだ
フルスタックエンジニア
Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。
著者の詳細を見る →