やりたいこと
ライブラリを使わず、生の JavaScript と HTML のみで Form Validation を実現する。
なんで?
React.js や Vue.js を導入途中のプロジェクトでは、jQuery などのライブラリを使う意味が薄れていく。
そのときに生JSだけで書くこともあるかなーと思い、サンプルコードを書いてみた。
(実用性があるかは不明)
完成品
Form Validation Sample - CodePen
https://codepen.io/ezawa800/pen/EJVwQL?editors=1010
やり方
1. HTML標準の Data Form Validation を利用する
詳細は フォームデータの検証 - Web 開発を学ぶ | MDN を参照してください。
<div class="form-area">
<h1 class="form-title">1. Use default validMessage</h1>
<form id="sample-form1" name="sample-form1" method="POST" action="">
<label>Your ID</label>
<input type="text"
id="sample-text-input1"
pattern="^[a-zA-Z0-9-_]+$"
title="半角英数字とハイフン(-)、アンダーライン(_)で入力してください。"
maxlength="20" required
/>
<input type="submit" />
<div class="input-note">半角英数字とハイフン(-)、アンダーライン(_)を使って、20文字以内で入力してください。</div>
</form>
</div>
必須入力
required
属性を利用する。
<input type="text" required />
送信ボタンをクリックすると以下のようなエラーになって、送信を中止する。
パターンの制限
pattern
属性を利用する。
<input type="text" pattern="^[a-zA-Z0-9-_]+$" title="半角英数字とハイフン(-)、アンダーライン(_)で入力してください。" />
送信ボタンをクリックすると以下のようなエラーになって、送信を中止する。
そのままだと「指定されている形式で入力してください。」とだけ表示されるが、title
属性を追加すると任意のメッセージを追加できる。
文字数制限
maxlength
属性を利用する。
<input type="text" maxlength="20" />
指定した文字数以上は入力できなくなる。
2. エラーメッセージをカスタマイズする
ここまでだと HTML のみで実現できているので JS の出番がないが、バリデーションエラーがある場合は「送信」ボタンを押す前の教えてほしいケースを想定して、以下の2パターンでエラーメッセージを表示させてみた。
2−1. 標準のエラーメッセージを任意の場所に表示する
<div class="form-area">
<h1 class="form-title">1. Use default validMessage</h1>
<form id="sample-form1" name="sample-form1" method="POST" action="">
<label>Your ID</label>
<input type="text"
id="sample-text-input1"
pattern="^[a-zA-Z0-9-_]+$"
title="半角英数字とハイフン(-)、アンダーライン(_)で入力してください。"
maxlength="20" required
/>
<input type="submit" />
<div id="sample-input-error1" class="error-text"></div>
<div class="input-note">半角英数字とハイフン(-)、アンダーライン(_)を使って、20文字以内で入力してください。</div>
</form>
</div>
document.addEventListener("DOMContentLoaded", function(evt) {
// 1. Use default validMessage
document.querySelector('#sample-text-input1').addEventListener('input', function(event) {
var validMessage = this.validationMessage;
if (validMessage) {
document.querySelector('#sample-input-error1').innerHTML = validMessage;
} else {
document.querySelector('#sample-input-error1').innerHTML = '';
}
});
});
バリデーションエラーがある場合は、対象のinput
に validationMessage
の値がセットされる。
それをそのまま使ってエラーメッセージを表示したいのが上記のサンプル。
コード量が少なくて済む一方で、最低限の情報しか表示されないのが適さないケースもあるかもしれない。
2−1. カスタムエラーメッセージを任意の場所に表示する
<div class="form-area">
<h1 class="form-title">2. Use custom validation message</h1>
<form id="sample-form2" name="sample-form2" method="POST" action="">
<label>Your ID</label>
<input type="text"
id="sample-text-input2"
pattern="^[a-zA-Z0-9-_]+$"
title="半角英数字とハイフン(-)、アンダーライン(_)で入力してください。"
maxlength="20" required
/>
<input type="submit" />
<div id="sample-input-error2" class="error-text"></div>
<div class="input-note">
半角英数字とハイフン(-)、アンダーライン(_)を使って、20文字以内で入力してください。
</div>
</form>
</div>
document.addEventListener("DOMContentLoaded", function(evt) {
// 2. Use custom validation message
document.querySelector('#sample-text-input2').addEventListener('input', function(event) {
var sampleInput = event.target,
errorBox = document.querySelector('#sample-input-error2');
if (sampleInput.checkValidity()) {
errorBox.innerHTML = '';
return;
}
var regex = new RegExp(sampleInput.getAttribute('pattern'));
if (sampleInput.value === "") {
errorBox.innerHTML = 'IDは必須です。';
} else if (!regex.test(sampleInput.value)) {
errorBox.innerHTML = '使用できない文字が含まれています。';
} else {
errorBox.innerHTML = '何かが間違っています。';
}
});
});
checkValidity
メソッドを使って、バリデーションの結果を取得し、その結果に応じて自分でエラーメッセージ表示処理を実装したパターン。
細やかなメッセージや挙動の調整ができる一方で、ちょっとコードが多いので共通化などの工夫が必要。
3. エラーになっている入力欄のスタイル変更
input {
&:invalid {
border: 2px solid red;
&:focus {
outline-color: rgba(255, 0, 0, .5);
}
}
}
:invalid
を使うと、バリデーションエラーが発生している入力欄のスタイルを調整できる。
※上部の入力欄はエラー、下部はエラーでかつフォーカスが当たっている。
まとめ
基本的にはライブラリを使った方が便利なことが多く、React.js や Vue.js を使う場合も生JSで書くことは少ないです。
ただ、移行期間中など何かしらの理由で生JSで書くケースもなくはないと思ったので、試しにちょっとしたサンプルを書いてみました。