jQuery検証通知にTwitterBootstrapポップオーバーを使用する方法は?


84

ブートストラップを使用してポップオーバーを簡単に表示できます。また、標準のjQuery検証プラグインまたはjQuery検証エンジンを使用して検証を行うこともできますが、一方を他方にフィー​​ドする方法がわかりません。

必要なのは、通知を表示したいときにバリデーターによって呼び出されるフックであり、メッセージとターゲット要素をポップオーバーに渡すクロージャーを与えることだと思います。これは一種の依存性注入のようです。

理論的にはすべて素晴らしいですが、そのフックがどこにあるのか、またはいずれかの検証エンジンにフックが存在する場合でも、私にはわかりません。どちらも、エラータイプ(必ずしもメッセージテキストは必要ありません)とそれに関連する要素だけが必要な場合に、配置、ラッパー、スタイルに関するあらゆる種類の精巧なオプションを使用して通知を表示する責任を負うことを意図しているようです。に。個々の通知ではなく、フォーム全体のフックを見つけました。

動的に作成されたフォームとうまく連携するため、クラスを使用してルールを定義する検証システムの方がはるかに好きです。

誰かが解決策やより良いアイデアを持っていますか?

回答:


21

highlightおよびjQueryValidatorshowErrors オプションを見てください。これらを使用すると、Bootstrapポップオーバーをトリガーする独自のカスタムエラーハイライトをフックできます。


それは素晴らしいです、ありがとう。ハイライトとアンハイライトは私が探していたものです。
シンクロ

80

これは実践的な例です。

$('form').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass, validClass) { 
        $(element).parents("div[class='clearfix']").addClass(errorClass).removeClass(validClass); 
    }, 
    unhighlight: function (element, errorClass, validClass) { 
        $(element).parents(".error").removeClass(errorClass).addClass(validClass); 
    }
});

ここに画像の説明を入力してください

ブートストラップポップオーバーは実際には使用しませんが、見た目はとても良く、簡単に実現できます。

更新

したがって、ポップオーバーの検証を行うには、次のコードを使用できます。

$("form").validate({
  rules : {
    test : {
      minlength: 3 ,
      required: true
    }
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      return $(value).popover("hide");
    });
    return $.each(errorList, function(index, value) {
      var _popover;
      _popover = $(value.element).popover({
        trigger: "manual",
        placement: "top",
        content: value.message,
        template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
      });
      // Bootstrap 3.x :      
      //_popover.data("bs.popover").options.content = value.message;
      // Bootstrap 2.x :
      _popover.data("popover").options.content = value.message;
      return $(value.element).popover("show");
    });
  }
});

あなたはこのようなものを手に入れます:

ここに画像の説明を入力してください

jsFiddleをチェックしてください


3
これは私が探していた方向にあるので、賛成しました。:-)バリアントについては私の答えを参照してください。
namin 2012年

多段形式の場合の
対処

4
Bootstrapの最新バージョンでは、.data( "popover")キーがなくなったことに注意してください。おそらく衝突を避けるために、彼らはキーを「bs.popover」に変更しました。未定義のエラーが発生した理由を理解するのに少し時間がかかりました。したがって、_popover.data( "bs.popover")。options.content = value.message;を使用する必要があります上記のコードで。
davidethell

必須フィールド以外のエラータイプにポップアップを表示するにはどうすればよいですか。特定のルールでのみエラーを表示するようにカスタマイズするにはどうすればよいですか。
アルジュン

実際には、jsFiddleでも簡単に確認できる小さな問題があります。フィールドが不要で、いくつかのルールが破られている場合、ポップオーバーは表示されますが、フィールドを空にして別のフィールドにフォーカスすると、ポップオーバーはまだそこにあります。successListの最初のループが呼び出されることはないため、ポップオーバーが「表示」状態になった後、「非表示」状態になることはありません。それについて何かできることはありますか?
g4bri3l 2014

9

Chris Fulstowはそれを正しく理解していましたが、それでもしばらく時間がかかったので、完全なコードを次に示します。

これにより、エラー時のポップオーバーが表示され、デフォルトのエラーラベルが非表示になります。

$('#login').validate({
  highlight: function(element, errClass) {
    $(element).popover('show');
  },
  unhighlight: function(element, errClass) {
    $(element).popover('hide');
  },
  errorPlacement: function(err, element) {
    err.hide();
  }
}).form();

これにより、ポップオーバーが設定されます。これから必要なのはトリガーだけです:「手動」

$('#password').popover({
  placement: 'below',
  offset: 20,
  trigger: 'manual'
});

ポップオーバーに渡されたタイトルとコンテンツの属性が機能していなかったため、#password入力でdata-content = '最小5文字'およびdata-original-title = '無効なパスワード'を使用してインラインで指定しました。フォームにはrel = 'popover'も必要です。

これは機能しますが、選択を解除するとポップオーバーがちらつきます。それを修正する方法はありますか?


6

これは、ポップアップがすでに存在している場合でも、検証の「ちらつき」の問題が常に「表示」しようとするのを防ぐ、VarunSinghからの優れた提案のフォローアップです。エラー状態配列を追加して、エラーが表示されている要素と表示されていない要素をキャプチャしました。チャームのように機能します!

var errorStates = [];

$('#LoginForm').validate({
    errorClass:'error',
    validClass:'success',
    errorElement:'span',
    highlight: function (element, errorClass) {
        if($.inArray(element, errorStates) == -1){
            errorStates[errorStates.length] = element;
            $(element).popover('show');
        }
    }, 
    unhighlight: function (element, errorClass, validClass) {
        if($.inArray(element, errorStates) != -1){
            this.errorStates = $.grep(errorStates, function(value) {
              return value != errorStates;
            });
            $(element).popover('hide');
        }
    },
    errorPlacement: function(err, element) {
        err.hide();
    }
});

$('#Login_unique_identifier').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

$('#Login_password').popover({
    placement: 'right',
    offset: 20,
    trigger: 'manual'
});

これは私のために働いたこのページの唯一の答えでした。残念ながら、これ以上投票されていません。
alastairs 2013

1
これはpopover、検証するすべてのフィールドに対して明示的に定義する必要があるという意味ではありませんか?もしそうなら、それはナッツです。
g33kz0r 2013年

ほとんどのユースケースでは、これは完全に受け入れられると思います。より最適なソリューションがある場合は、自由に追加してください:)
Jeffrey Gilbert

5

jQuery検証プラグイン(バージョン1.9.0でテスト済み)用のこのjQuery拡張機能でうまくいきます。

https://github.com/tonycoco/rails_template/blob/master/files/assets/javascripts/jquery.validate.bootstrap.js

これにより、Rails-eskのエラーメッセージも追加されます。


これは素晴らしい。とても役に立ちました。今... TOS]チェックボックスに適切なメッセージを取得する方法を見つけ出すする
TIG

3

ブートストラップのCSSを変更することを好みます。jQueryvalidateのクラスを適切な場所に追加しました。field-validation-errorおよびinput-validation-error

    form .clearfix.error > label, form .clearfix.error .help-block, form .clearfix.error .help-inline, .field-validation-error {
  color: #b94a48;
}
form .clearfix.error input, form .clearfix.error textarea, .input-validation-error {
  color: #b94a48;
  border-color: #ee5f5b;
}
form .clearfix.error input:focus, form .clearfix.error textarea:focus, .input-validation-error:focus {
  border-color: #e9322d;
  -webkit-box-shadow: 0 0 6px #f8b9b7;
  -moz-box-shadow: 0 0 6px #f8b9b7;
  box-shadow: 0 0 6px #f8b9b7;
}

このアプローチは私にとって最適に見えます:)。これは私が考えていたものでもあります
フレッシュブラッド2012年

3

これは、Bootstrap2.xとjQueryValidate1.9でそれを行った方法です。

$('#form-register').validate({ errorElement: 'span', errorClass:'help-inline', highlight:    function (element, errorClass) {
        $(element).parent().parent().addClass('error');
    }, unhighlight: function (element, errorClass) {
        $(element).parent().parent().removeClass('error');
    }});

3

以下をご覧ください:
- https://gist.github.com/3030983
これが最も簡単だと思います。

編集

リンクからのコード:

$('form').validate({
    rules: {
        numero: {
            required: true
        },
        descricao: {
            minlength: 3,
            email: true,
            required: true
        }
    },

    showErrors: function (errorMap, errorList) {

        $.each(this.successList, function (index, value) {
            $(value).popover('hide');
        });


        $.each(errorList, function (index, value) {

            console.log(value.message);

            var _popover = $(value.element).popover({
                trigger: 'manual',
                placement: 'top',
                content: value.message,
                template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            _popover.data('popover').options.content = value.message;

            $(value.element).popover('show');

        });

    }

});

頭を上げてくれてありがとう!Bootstrapについては、ツールチップを使用して私のバージョンを確認してください。私の意見では、それはポップオーバーよりもエレガントです。
エイドリアンP.

3

頭を上げてくれてありがとう!これが私のバージョンのBootstrapですが、ツールチップが付いています。私の意見では、それはポップオーバーよりもエレガントです。質問はポップオーバーに関するものだったので、この理由で投票しないでください。多分誰かがこのようにそれを好きになるでしょう。何かを探していて、Stackoverflowで新しいアイデアを見つけたときが大好きです。注:フォームにマークアップする必要はありません。

    $('#LoginForm').validate({
        rules: {
            password: {
                required: true,
                minlength: 6
            },

            email_address: {
                required: true,
                email: true
            }
        },
        messages: {
            password: {
                required: "Password is required",
                minlength: "Minimum length is 6 characters"
            },
            email_address: {
                required: "Email address is required",
                email: "Email address is not valid"
            }
        },  
        submitHandler: function(form) {
            form.submit();
        },

        showErrors: function (errorMap, errorList) {

            $.each(this.successList, function (index, value) {
                $('#'+value.id+'').tooltip('destroy');
            });


            $.each(errorList, function (index, value) {

                $('#'+value.element.id+'').attr('title',value.message).tooltip({
                    placement: 'bottom',
                    trigger: 'manual',
                    delay: { show: 500, hide: 5000 }
                }).tooltip('show');

            });

        }

    }); 

1
私はあなたのアプローチを使おうとしましたが、私はエラーになり始めていました。問題は、Jquery UIを使用すると、両方がツールチップを使用するために競合が発生することです。そのための解決策があることは知っていますが、他のユーザーにそれを知らせたいだけです。
リチャードペレス

+1 for jQuery UIのヘッドアップ!ツールチップJS関数が含まれないように、カスタムダウンロード(jQueryUIまたはBootstrap)を構成する必要があります。そうしなかった場合、ツールチップとの競合になります。
エイドリアンP.

ちょっとそこに私は正規表現であなたのコードを使おうとしていました、そしてたまたまstackoverflow.com/questions/16087351/…でエラーがありました。あなたはあなたが助けることができると思いますか?:)
psharma 2013

@psharmaブートストラップやツールチップとは何の関係もありません。あなたのエラーはあなたがあなたの質問に対する答えを得たときのあなたのルール宣言です。エラーメッセージは次のように述べています:用語は未定義です!
エイドリアンP.

どういうわけか、これは私のために働いた唯一の解決策です。ありがとう!
suchanoob 2016

2

これが私がそれを実現させた方法です。ただし、検証スクリプトに2つの変更を加える必要があります(ここでブートストラップ1.4のコードを取得し、それを変更しました--http://mihirchitnis.net/2012/01/customizing-error-messages-using-jquery-validate-plugin- for-twitter-bootstrap /

検証するための私の呼び出し:

    $("#loginForm").validate({
  errorClass: "control-group error",
  validClass: "control-group success",
  errorElement: "span", // class='help-inline'
  highlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    } else {
        $(element).parent("div").parent("div").removeClass(validClass).addClass(errorClass);
    }
  },
  unhighlight: function(element, errorClass, validClass) {
    if (element.type === 'radio') {
        this.findByName(element.name).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    } else {
        $(element).parent("div").parent("div").removeClass(errorClass).addClass(validClass);
    }
  }
});

次に、jquery.validate.jsの2つの変更を行う必要があります。1
。この修正を適用します-https ://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. 647行目(showLabel関数でラベル部分を作成)の後)行の.addClass(this.settings.errorClass)追加後:.addClass("help-inline")
誰かがvalidate関数で2番目の修正を適用する方法を見つけることができるかもしれませんが、showLabelが強調表示の後に呼び出されるため、私は方法を見つけられませんでした。


2

これは、TwitterBootstrapガイドラインに準拠するために検証に入れたものです。エラー検証メッセージがに入れられ<span class=help-inline>、外側のコンテナをerrorまたはsuccess:として強調表示します。

errorClass:'help-inline',
errorElement:'span',
highlight: function (element, errorClass, validClass) {
$(element).parents("div.clearfix").addClass('error').removeClass('success');
},
unhighlight: function (element, errorClass, validClass) {
$(element).parents(".error").removeClass('error').addClass('success');
}

2

上記のKennyMeyerの優れた回答の更新です。このスニペットで対処した、それが機能しない原因となる問題がいくつかありました。

showErrors: function (errorMap, errorList) {
        $.each(this.successList, function (index, element) {
            return $(element).popover("destroy");
        });

        $.each(errorList, function (index, error) {
            var ele = $(error.element); //Instead of referencing the popover directly, I use the element that is the target for the popover

            ele.popover({
                    trigger: "manual",
                    placement: "top",
                    content: function(){ //use a function to assign the error message to content
                        return error.message
                    },
                    template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><div class="popover-content"><p></p></div></div></div>'
            });

            //bs.popover must be used, not just popover
            ele.data("bs.popover").options.content = error.message;

            return $(error.element).popover("show");
        });
    }

イニシアチブをありがとう。私が見ることができるように、コードは大きく変更されました:-)
Kenny Meyer

1

元の投稿者がブートストラップポップオーバーを表示/非表示にするフックを要求したため、これがディスカッションに関連するかどうかはわかりません。

私は簡単な検証を探していましたが、ポップオーバーは問題ではありませんでした。関連のポストとGoogle検索結果の最初には、すでにこの質問の重複マークされています。したがって、TwitterBootstrapとうまく調和するこの優れた@ReactiveRavenのjqValidationJS(jqBootstrapValidationと適切に呼ばれる)に言及することは理にかなっています。セットアップには数分しかかかりません。ここからダウンロード

これが付加価値をもたらすことを願っています。


1

tl; dr、ハッシュマップを使用して要素のIDを格納し、オンザフライでポップオーバーを作成することで、明示的なポップオーバーを列挙する必要をなくします(マッシュアップのJeffreyGilbertとKennyMeyerのアプローチ)。

これは、他の人が言及したちらつきの問題を修正する私の見解ですが、@ Jeffrey Gilbertの回答とは異なり、リスト(errorStates)を使用せず、エラーマップを使用します。ハッシュマップFTW。CSのすべての問題はハッシュマップで解決できることをどこかで読んだことを覚えていると思います:)

var err_map = new Object();     // <--- n.b.
$("form#set_draws").validate({
  rules: {
    myinput: { required: true, number: true },
  },
  showErrors: function(errorMap, errorList) {
    $.each(this.successList, function(index, value) {
      if (value.id in err_map)
      {
        var k = err_map[value.id];
        delete err_map[value.id]; // so validation can transition between valid/invalid states
        k.popover("hide");
      }
    });
    return $.each(errorList, function(index, value) {
      var element = $(value.element);
      if( ! (value.element.id in err_map) ) {
        var _popover = element.popover({
          trigger: "manual",
                 placement: "top",
                 content: value.message,
                 template: "<div class=\"popover\"><div class=\"arrow\"></div><div class=\"popover-inner\"><div class=\"popover-content\"><p></p></div></div></div>"
        });
        _popover.data("popover").options.content = value.message;
          err_map[value.element.id] = _popover;
        return err_map[value.element.id].popover("show");
      }
    });
  }
});

これについてアイデアを投稿してくれた他のすべての人に感謝します。



0

ポップアップに上記のKennyMeyerコードを使用する場合、フィールドのコンテンツをチェックするが、有効なURLなどの必須ではないルールにより、フィールドをクリアしてもポップアップが消えないことに注意してください。解決策については、以下のonkeyupを参照してください。誰かがより良い解決策を持っているなら、投稿してください。

onkeyup: function(element, event) {
            if($(element).valid())  {
                return $(element).popover("hide");
            }
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.