html5+bootstrap4+JavaScriptでフォームバリデーションを実装する

更新日 2021-04-13 08:57:32
html5

HTML


    <form id="form">
      <!-- 番号 -->
      <div class="form-group" style="float:left">
        <label>番号:</label>
        <input class="form-control" type="text" required pattern="\d*" placeholder="半角数字">
        <div class="badge"></div>
      </div>
      <!-- 番号 -->
      <div class="form-group" style="float:left">
        <label>番号:</label>
        <input class="form-control" type="text" required pattern="\d*" placeholder="半角数字">
        <div class="badge"></div>
      </div>
      <!-- 番号 -->
      <div class="form-group" style="float:left">
        <label>番号:</label>
        <input class="form-control" type="text" pattern="\d*" placeholder="半角数字">
        <div class="badge"></div>
      </div>
      
      <!-- 日付 -->
      <div class="form-group" style="float:left">
       <label>日付:</label>
       <div class="form-group">
        <input class="form-control" type="date" style="display:inline-block">
        <label style="display:inline-block">~</label>
        <input class="form-control" type="date" style="display:inline-block">
       </div>
      </div>

      <!-- ボタン -->
      <div style="clear:both">
        <button type="button" id="btn" class="btn btn-info btn-sm">submit</button>
      </div>
    </form>

スタイルシート


/* インプット要素 */
input {
  /* 幅 */
  width: 110px !important;
  /* フォントサイズ */
  font-size: 12px !important;
  /* マージン */
  margin: 2px;
}
/* インプット要素(日付) */
input[type="date"] {
  /* フォントサイズ */
  font-size: 11px !important;
}
/* セレクト要素 */
select {
  /* 幅 */
  width: 110px !important;
  /* フォントサイズ */
  font-size: 12px !important;
  /* マージン */
  margin: 2px;
}
/*
 * bootstrap上書き
 */
/* フォームコントロール */
.form-control {
  height: inherit; /* 継承で無効化 */
  padding-left: inherit; /* 継承で無効化 */
  padding-right: inherit; /* 継承で無効化 */
}
/* フォームグループ */
.form-group {
  margin-bottom: inherit;
}

/* ラベル */
label {
  font-size:75%;
  padding: 0;
  margin: 0;
}

スクリプト


      const BADGE_DANGER_TEXT = "必須";
      const BADGE_WARNING_TEXT = "!";
      
      $(function() {
        ////////////////////////////
        //ロード時のラベル制御
        ////////////////////////////
        $("input:required").css("border-color", "red")
          .closest("div").find(".badge").addClass("badge-danger").text(BADGE_DANGER_TEXT);
        
        ////////////////////////////
        // フォーカスアウト時のラベル制御
        ////////////////////////////
        $(document).on("blur", "input", function() {
          // 値なし
          if (this.validity.valueMissing) {
            $(this).css("border-color", "red");
            $(this).closest("div").find(".badge")
              .removeClass("badge-danger badge-warning")
              .addClass("badge-danger")
              .text(BADGE_DANGER_TEXT);
          }
          // タイプミスマッチ
          else if (this.validity.typeMismatch) {
            $(this).css("border-color", "orange");
            $(this).closest("div").find(".badge")
              .removeClass("badge-danger badge-warning")
              .addClass("badge-warning")
              .text(BADGE_WARNING_TEXT);
          }
          // パターンミスマッチ
          else if (this.validity.patternMismatch) {
            $(this).css("border-color", "orange");
            $(this).closest("div").find(".badge")
              .removeClass("badge-danger badge-warning")
              .addClass("badge-warning")
              .text(BADGE_WARNING_TEXT);
          }
          // 正常
          else {
            $(this).css("border-color", "#ced4da");
            $(this).closest("div").find(".badge")
              .removeClass("badge-danger badge-warning")
              .text("");
          }
        });
        
        ////////////////////////////
        // 送信ボタン押下時のバリデーション発火
        ////////////////////////////
        $(document).on("click", "#btn", function() {
          // デフォルト発火
          //document.forms[0].reportValidity();
          
          // カスタム発火
          $("input").each(function(i, o) {
            // これがないとカスタムメッセージ設定後ずっとcustomError=trueになってしまう
            o.setCustomValidity("");
            // エラーの場合
            if (o.validity.valid === false) {
              // カスタムメッセージ
              o.setCustomValidity("えらー");
              // 発火
              o.reportValidity();
              // ループブレイク
              return false;
            }
          });
        });
      });