人生シーケンスブレイク

シーケンスブレイク(Sequence breaking、シークエンスブレイクとも)とは、テレビゲームにおいて開発が想定している攻略ルートを逸脱し、ショートカットする行為のことである。

jQuery Validation Plugin のエラーを Bootstrap3 の popover に出力させる。

HTML5 Form Validationのブラウザごとの実装状況が異なることから、 jQuery Validation Plugin | Form validation with jQuery をまだ現役で利用しているケースも多いはず。
先日 jQuery Validation Plugin のエラーを Bootstrap3 の popover(tooltip) に組み込んでみたのでその方法を記録。

実装イメージ。

準備

こんな感じの構成とする

      <form>
        <div class="form-group">
          <label for="exampleInputEmail1">Email address</label>
          <input type="email" class="form-control" name="exampleInputEmail1" placeholder="Email">
        </div>
        <div class="form-group">
          <label for="exampleInputPassword1">Password</label>
          <input type="password" class="form-control" name="exampleInputPassword1" placeholder="Password">
        </div>
        <div class="form-group">
          <label for="exampleInputFile">File input</label>
          <input type="file" id="exampleInputFile">
          <p class="help-block">Example block-level help text here.</p>
        </div>
        <div class="checkbox">
          <label>
            <input type="checkbox"> Check me out
          </label>
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>

jQuery Validation Plugin の showErrors()メソッドを使う

showErrors()というメソッドがある。
これはエラー時の表示処理を制御するメソッドで、defaultでは以下のようなdefaultShowErrors()メソッドが実行される。

       defaultShowErrors: function() {
            var i, elements, error;
            for ( i = 0; this.errorList[ i ]; i++ ) {
                error = this.errorList[ i ];
                if ( this.settings.highlight ) {
                    this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
                }
                this.showLabel( error.element, error.message );
            }
            if ( this.errorList.length ) {
                this.toShow = this.toShow.add( this.containers );
            }
            if ( this.settings.success ) {
                for ( i = 0; this.successList[ i ]; i++ ) {
                    this.showLabel( this.successList[ i ] );
                }
            }
            if ( this.settings.unhighlight ) {
                for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
                    this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
                }
            }
            this.toHide = this.toHide.not( this.toShow );
            this.hideErrors();
            this.addWrapper( this.toShow ).show();
        },

端的に言うと、エラー箇所の次の位置にエラーメッセージを含むlabel要素をappendしている。
このshowErrorsメソッドは、以下のような記述でオーバーライド可能。 Validator.showErrors() | jQuery Validation Plugin

$("form").validate({
  rules: {
    exampleInputEmail1: {
      required: true
    },
    exampleInputPassword1: {
      required: true
    }
  },

  showErrors: function(errorMap, errorList) {
    // validationに引っかからなかった要素はpopover非表示にする
    $.each(this.successList, function(index, value) {
      $(value).popover('hide');
    });
    
    // validationに引っかかった要素はpopover表示する
    $.each(errorList, function(index, value) {
      var _popover = $(value.element).popover({
        trigger: 'manual',
        placement: 'bottom',
        content: value.message,
        template: "<div class='popover' role='tooltip'><div class='arrow'></div><h3 class='popover-title'></h3><div class='popover-content'></div></div>"
      });
      _popover.data('bs.popover').options.content = value.message; // popover要素のテキストを更新する
      $(value.element).popover('show');
    });
  }
});

上記を実装するとこんな感じになる。

エラーメッセージなので警告色に

.popover-validation などとclass名を追加して、css

.popover.popover-validation {
  background-color: #f9f2f4;
  color: #c7254e;
}
.popover.popover-validation > .arrow:after {
  border-bottom-color: #f9f2f4;
}

とするとさらにいい感じになった。

showErrors()処理を使いまわしたい

setDefaults()メソッドを利用しましょう。 jQuery.validator.setDefaults() | jQuery Validation Plugin

$.validator.setDefaults({
  // エラーメッセージのBootstrap3: popover表示
  showErrors: function(errorMap, errorList) {
       ...
    });
  }
});

messages: {} も纏めて jquery.validate.settings.js などとして置いとくと、サイト内で共通のエラーメッセージを使い回せます。

纏め

最終的な今回の成果物として、デモ用のリポジトリを用意したのでご参考にどうぞ。

github.com

参考: How to use Twitter Bootstrap popovers for jQuery validation notifications? - Stack Overflow

JavaScript 第6版

JavaScript 第6版