LoginSignup
23
19

More than 5 years have passed since last update.

ライブラリなしで Form Validation を実装してみる

Last updated at Posted at 2019-04-15

やりたいこと

ライブラリを使わず、生の JavaScript と HTML のみで Form Validation を実現する。

こんな感じ ↓
スクリーンショット 2019-04-15 14.02.08.png

なんで?

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 を参照してください。

sample1.html
<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 />

送信ボタンをクリックすると以下のようなエラーになって、送信を中止する。
スクリーンショット 2019-04-15 13.22.46.png

パターンの制限

pattern 属性を利用する。

<input type="text" pattern="^[a-zA-Z0-9-_]+$" title="半角英数字とハイフン(-)、アンダーライン(_)で入力してください。" />

送信ボタンをクリックすると以下のようなエラーになって、送信を中止する。
スクリーンショット 2019-04-15 13.22.15.png

そのままだと「指定されている形式で入力してください。」とだけ表示されるが、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 = '';
    }
  });
});

バリデーションエラーがある場合は、対象のinputvalidationMessage の値がセットされる。
それをそのまま使ってエラーメッセージを表示したいのが上記のサンプル。

スクリーンショット 2019-04-15 13.42.08.png

コード量が少なくて済む一方で、最低限の情報しか表示されないのが適さないケースもあるかもしれない。

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 メソッドを使って、バリデーションの結果を取得し、その結果に応じて自分でエラーメッセージ表示処理を実装したパターン。

細やかなメッセージや挙動の調整ができる一方で、ちょっとコードが多いので共通化などの工夫が必要。

スクリーンショット 2019-04-15 13.47.05.png

3. エラーになっている入力欄のスタイル変更

input {
  &:invalid {
    border: 2px solid red;

    &:focus {
      outline-color: rgba(255, 0, 0, .5);
    }
  }
}

:invalid を使うと、バリデーションエラーが発生している入力欄のスタイルを調整できる。

スクリーンショット 2019-04-15 13.49.47.png

※上部の入力欄はエラー、下部はエラーでかつフォーカスが当たっている。

まとめ

基本的にはライブラリを使った方が便利なことが多く、React.js や Vue.js を使う場合も生JSで書くことは少ないです。
ただ、移行期間中など何かしらの理由で生JSで書くケースもなくはないと思ったので、試しにちょっとしたサンプルを書いてみました。

23
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
19