Bootstrapバリデーション機能の使い方

HTML5標準のバリデーション機能ではなく、Bootstrapのバリデーションを使う方法です。
<form novalidate>を指定し、独自のバリデーションを行います。

Bootstrap バリデーション機能のサンプル

モーダル上のフォームに対して、入力チェックを行うサンプルです。

<script type="text/javascript" language="JavaScript">
  $(function () {
    'use strict';

    const forms = document.querySelectorAll('.needs-validation');

    Array.prototype.slice.call(forms)
    .forEach(form => {
      form.addEventListener('submit', (event) => {
        if (!form.checkValidity()) {
          event.preventDefault();
          event.stopPropagation();
        }

        form.classList.add('was-validated');
      }, false);
    });
  });
</script>

<!-- モーダル. -->
<div class="modal fade" id="addUserModal" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-lg modal-dialog-centered">
    <div class="modal-content">
      <form action="/user/add" method="post" class="needs-validation" novalidate>
        <div class="modal-header">
          <h5 class="modal-title">ユーザー追加</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="mb-3 row">
            <label for="inputUserName" class="col-sm-3 col-form-label">ユーザー名</label>
            <div class="col-sm-9">
              <input type="text" id="inputUserName" name="username" class="form-control" required>
              <span class="invalid-feedback">項目を入力してください.</span>
            </div>
          </div>
          <div class="mb-3 row">
            <label for="inputPassword" class="col-sm-3 col-form-label">パスワード</label>
            <div class="col-sm-9">
              <input type="password" id="inputPassword" name="password" class="form-control" required>
              <span class="invalid-feedback">項目を入力してください.</span>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">キャンセル</button>
          <button type="submit" class="btn btn-primary">追加する</button>
        </div>
      </form>
    </div>
  </div>
</div>

scriptの解説

Validation(バリデーション)を行うformの取得

const forms = document.querySelectorAll('.needs-validation');

バリデーションが必要なフォームの一覧(CSSクラスneeds-validationを持つ要素)を取得します。formsは配列ではなくNodeListになります。
forEachでループさせることは可能です。

取得したNodeListを配列にする

Array.prototype.slice.call(forms)

slice()メソッドを利用して、NodeList - formsを配列に変換します。配列にすることで各フォーム毎に処理を行えます。

submitイベントでバリデーションを実行する

form.addEventListener('submit', (event) => { ... }, false);

バリデーションが必要なフォームの入力部品をsubmitイベントのイベントリスナーとして登録し、バリデーションを行います。

バリデーションを実行する

form.checkValidity();

バリデーション失敗時にsubmitイベントを停止させる

event.preventDefault();
event.stopPropagation();

バリデーション終了のCSSクラスを追加する

form.classList.add('was-validated');

フォームにwas-validatedを追加することで、invalid-feedbackクラスが表示されます。

画面イメージ

  • 通常時 Bootstrap validation
  • チェックNG Bootstrap validation

別の記述例

Bootstrap公式ドキュメントでは、NodeListを配列に変換していますが、そのまま使うことも可能です。

$(function () {
  'use strict';

  const forms = document.querySelectorAll('.needs-validation');
  forms.forEach(form => {
    form.addEventListener('submit', (event) => {
      if (!form.checkValidity()) {
        event.preventDefault();
        event.stopPropagation();
      }
      form.classList.add('was-validated');
    }, false);
  });
});

入力の一致確認

確認パスワードの一致確認など、特別なチェックを行いたい場合の実装方法。
oninputイベントで対象の2項目に入力されるたびにチェックを行います。setCustomValidity()が空文字にならなければ、バリデーションで失敗と判定されるので、チェックOKの場合は必ず空文字を設定します。

Bootstrapを使う場合

<script type="text/javascript" language="JavaScript">
  $(function () {
    'use strict';

    const forms = document.querySelectorAll('.needs-validation');
    forms.forEach(form => {
      form.addEventListener('submit', (event) => {
        if (!form.checkValidity()) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  });

  function checkPassword() {
    const inputPassword = document.getElementById('inputPassword').value
    const confirmPasswordText = document.getElementById('confirmPassword').value;

    if (!confirmPasswordText) {
      document.getElementById('confirmPassword').setCustomValidity('項目を入力してください');
      document.getElementById('confirmPasswordInvalidFeedback').innerHTML = '項目を入力してください.';
      return;
    }

    if (inputPassword !== confirmPasswordText) {
      document.getElementById('confirmPassword').setCustomValidity('パスワード不一致');
      document.getElementById('confirmPasswordInvalidFeedback').innerHTML = 'パスワード不一致.';
    } else {
      document.getElementById('confirmPassword').setCustomValidity('');
    }
  }
</script>

<!-- モーダル. -->
<div class="modal fade" id="addUserModal" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-lg modal-dialog-centered">
    <div class="modal-content">
      <form action="/user/add" method="post" class="needs-validation" novalidate>
        <div class="modal-header">
          <h5 class="modal-title">ユーザー追加</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="mb-3 row">
            <label for="inputUserName" class="col-sm-3 col-form-label">ユーザー名</label>
            <div class="col-sm-9">
              <input type="text" id="inputUserName" name="username" class="form-control" required>
              <span class="invalid-feedback">項目を入力してください.</span>
            </div>
          </div>
          <div class="mb-3 row">
            <label for="inputPassword" class="col-sm-3 col-form-label">パスワード</label>
            <div class="col-sm-9">
              <input type="password" id="inputPassword" name="password" class="form-control" required oninput="checkPassword()">
              <span class="invalid-feedback">項目を入力してください.</span>
            </div>
          </div>
          <div class="mb-3 row">
            <label for="confirmPassword" class="col-sm-3 col-form-label">パスワード(確認用)</label>
            <div class="col-sm-9">
              <input type="password" id="confirmPassword" class="form-control" required oninput="checkPassword()">
              <span id="confirmPasswordInvalidFeedback" class="invalid-feedback">項目を入力してください.</span>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">キャンセル</button>
          <button type="submit" class="btn btn-primary">追加する</button>
        </div>
      </form>
    </div>
  </div>
</div>

画面イメージ

  • 通常時 Bootstrap validation
  • 必須項目未入力 Bootstrap validation
  • 確認パスワード不一致 Bootstrap validation

HTML5標準のバリデーションを使う場合

<form novalidate>を指定せずに、HTML5標準のバリデーション機能を利用する場合です。

<script type="text/javascript" language="JavaScript">
  function checkPassword() {
    const inputPassword = document.getElementById('inputPassword').value
    const confirmPasswordText = document.getElementById('confirmPassword').value;
    if (inputPassword !== confirmPasswordText) {
      document.getElementById('confirmPassword').setCustomValidity('パスワード不一致');
    } else {
      document.getElementById('confirmPassword').setCustomValidity('');
    }
  }
</script>

<!-- モーダル. -->
<div class="modal fade" id="addUserModal" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-lg modal-dialog-centered">
    <div class="modal-content">
      <form action="/user/add" method="post">
        <div class="modal-header">
          <h5 class="modal-title">ユーザー追加</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <div class="mb-3 row">
            <label for="inputUserName" class="col-sm-3 col-form-label">ユーザー名</label>
            <div class="col-sm-9">
              <input type="text" id="inputUserName" name="username" class="form-control" required>
            </div>
          </div>
          <div class="mb-3 row">
            <label for="inputPassword" class="col-sm-3 col-form-label">パスワード</label>
            <div class="col-sm-9">
              <input type="password" id="inputPassword" name="password" class="form-control" required oninput="checkPassword()">
            </div>
          </div>
          <div class="mb-3 row">
            <label for="confirmPassword" class="col-sm-3 col-form-label">パスワード(確認用)</label>
            <div class="col-sm-9">
              <input type="password" id="confirmPassword" class="form-control" oninput="checkPassword()">
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">キャンセル</button>
          <button type="submit" class="btn btn-primary">追加する</button>
        </div>
      </form>
    </div>
  </div>
</div>

画面イメージ

  • 通常時 html5 validation
  • 必須項目未入力 html5 validation
  • 確認パスワード不一致 html5 validation
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です