validator4.js

更新日 2021-05-04 08:20:23
javascript

/**
 * @overview フォーム検証を装飾する
 * @usage1 object .validator() 初期設定
 * @usage2 boolean .validator('check') 検証&ポップアップ表示
 */
(function( $ ){
  // メソッド
  let methods = {
    // init
    init : function( options ) {
      // 引数のデフォルト値
      let defaults = {
        'text' : {
          'danger' : '必須項目です',
          'warning' : '形式が不正です',
        },
      }
      // 引数の受け入れ
      let settings = $.extend(defaults, options);
      // 自オブジェクト
      let $this = (this.filter("input,select,textarea").length)
        ? this.filter("input,select,textarea")
        : this.find("input,select,textarea");
      // 
      $this.attr("autocomplete", "off");
      // ロード時
      $this.each(function(i, o) {
        // フィードバックエリア生成
        let $div = $('<div />').addClass("invalid-feedback");
        $(this).closest("div").append($div);
        // 検証関数
        _checkValidity(this, settings);
      });
      
      // イベントハンドラ
      $this.on("blur change", function() {
        // 検証関数
        _checkValidity(this, settings);
      });
      
      // 返却
      return this;
    },
    
    // check
    check : function( ) {
      // 自オブジェクト
      let $this = this;
      // 検証&ポップアップ表示
      return $this[0].reportValidity();
    },

    // checkboxgroup
    checkboxgroup : function() {
      // 検証フラグ
      let valid = false;
      // 自オブジェクト
      let $this = (this.filter(":checkbox[required]").length)
        ? this.filter(":checkbox[required]")
        : this.find(":checkbox[required]");
      // 対象要素がない場合はtrueを返却
      if ($this.length < 1) {
        return true;
      }
      $this.each(function(i, o) {
        if ($(this).prop("checked")) {
          valid = true;
        }
      });
      if (valid === false) {
        $this[0].setCustomValidity("いずれかを選択してください");
        $this[0].reportValidity();
        return false;
      } else {
        $this[0].setCustomValidity("");
        return true;
      }
    },

  };
  
  // 検証関数
  const _checkValidity = function(self, settings) {
    // ラジオボタン
    if ($(self).attr("type") === "radio") {
      // 値なし
      if (self.validity.valueMissing) {
        // danger
        $("input[name='" + $(self).attr("name") + "']")
          .removeClass("is-valid is-invalid")
          .addClass("is-invalid");
        $("input[name='" + $(self).attr("name") + "']:last")
          .closest("div").find(".invalid-feedback")
          .text(settings.text.danger);
      }
      // 正常
      else {
        // success
        $("input[name='" + $(self).attr("name") + "']")
          .removeClass("is-valid is-invalid")
          .addClass("is-valid")
          .closest("div").find(".invalid-feedback")
          .text("");
      }
    }
    // チェックボックス
    else if ($(self).attr("type") === "checkbox") {
      // 値なし
      if (self.validity.valueMissing) {
        // danger
        $(self)
          .removeClass("is-valid is-invalid")
          .addClass("is-invalid")
          .closest("div").find(".invalid-feedback")
          .text(settings.text.danger);
      }
      // 正常
      else {
        // success
        $(self)
          .removeClass("is-valid is-invalid")
          .addClass("is-valid")
          .closest("div").find(".invalid-feedback")
          .text("");
      }
    }
    // それ以外
    else {
      // 値なし
      if (self.validity.valueMissing) {
        // danger
        $(self)
          .removeClass("is-valid is-invalid")
          .addClass("is-invalid")
          .closest("div").find(".invalid-feedback")
          .text(settings.text.danger);
      }
      // パターンミスマッチ
      else if (self.validity.patternMismatch) {
        // warning
        $(self)
          .removeClass("is-valid is-invalid")
          .addClass("is-invalid")
          .closest("div").find(".invalid-feedback")
          .text(settings.text.warning);
      }
      // タイプミスマッチ
      else if (self.validity.typeMismatch) {
        // warning
        $(self)
          .removeClass("is-valid is-invalid")
          .addClass("is-invalid")
          .closest("div").find(".invalid-feedback")
          .text(settings.text.warning);
      }
      // 正常
      else {
        // 値あり
        if ( $(self).val() ) {
          // success
          $(self)
            .removeClass("is-valid is-invalid")
            .addClass("is-valid")
            .closest("div").find(".invalid-feedback")
            .text("");
        }
        // 値なし
        else {
          // default
          $(self)
            .removeClass("is-valid is-invalid")
            .closest("div").find(".invalid-feedback")
            .text("");
        }
      }
    }
  }
  
  
  // プラグインメソッド
  $.fn.validator = function( method ) {
    // メソッド呼び出し部分
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }

  };

})( jQuery );