Comment utiliser les popovers Twitter Bootstrap pour les notifications de validation jQuery?

Je peux faire apparaître les popovers en utilisant le bootstrap assez facilement, et je peux aussi faire des validations en utilisant le plugin de validation jQuery standard ou le moteur de validation jQuery , mais je n’arrive pas à comprendre comment les utiliser l’un dans l’autre.

Je pense que ce dont j’ai besoin, c’est d’un hook appelé par le validateur lorsqu’il veut afficher une notification, lui donner une fermeture qui transmet le message et l’élément cible à un popover. Cela semble être une sorte d’dependency injection.

Tout cela est bien en théorie, mais je ne peux pas comprendre où se trouve ce crochet, ou même s’il existe dans l’un ou l’autre des moteurs de validation. Ils semblent tous deux vouloir prendre la responsabilité d’afficher des notifications avec toutes sortes d’options de placement, de wrappers, de styles lorsque tout ce que je recherche est le ou les types d’erreur (je n’ai même pas besoin de texte de message) à. J’ai trouvé des hooks pour la forme entière, pas les notifications individuelles.

Je préfère de beaucoup les systèmes de validation qui utilisent des classes pour définir des règles, car elles jouent bien avec les formes créées dynamicment.

Quelqu’un at-il une solution ou une meilleure idée?

Jetez un coup d’œil aux options de highlight et showErrors options showErrors jQuery Validator , celles-ci vous permettront d’ showErrors vos propres erreurs d’erreur qui déclenchent les popovers Bootstrap.

Ceci est un exemple pratique:

 $('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); } }); 

entrer la description de l'image ici

Il n’utilise pas vraiment de pop-ups bootstrap, mais il a l’air vraiment sympa et est facile à réaliser.

METTRE À JOUR

Donc, pour avoir la validation popover, vous pouvez utiliser ce code:

 $("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({ sortinggger: "manual", placement: "top", content: value.message, template: "

" }); // 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"); }); } });

Vous obtenez quelque chose comme ça:

entrer la description de l'image ici

Découvrez le jsFiddle .

Chris Fulstow avait tout à fait raison, mais ça m’a pris encore du temps, alors voici le code complet:

Cela montre le popover en cas d’erreur et masque les étiquettes d’erreur par défaut:

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

Cela met en place le popover. La seule chose dont vous avez besoin est un déclencheur: ‘manual’

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

Les atsortingbuts de titre et de contenu transmis au popover ne fonctionnaient pas, alors je les ai spécifiés en ligne dans l’entrée #password avec data-content = ‘Minimum 5 caractères’ et data-original-title = ‘Mot de passe invalide’. Vous avez également besoin de rel = ‘popover’ dans votre formulaire.

Cela fonctionne, mais le popover scintille lors de la sélection. Une idée de comment résoudre ce problème?

Voici une suite à l’excellente suggestion de Varun Singh qui empêche le problème de “scintillement” de la validation en essayant constamment de “montrer” même si le popup est déjà présent. J’ai simplement ajouté un tableau des états d’erreur pour capturer les éléments présentant des erreurs et ceux qui ne le sont pas. Fonctionne comme un charme!

 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, sortinggger: 'manual' }); $('#Login_password').popover({ placement: 'right', offset: 20, sortinggger: 'manual' }); 

Cette extension jQuery pour jQuery Validation Plugin (testée avec la version 1.9.0) fera l’affaire.

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

Cela ajoute également dans certains messages d’erreur Rails-esk.

Je préfère changer le CSS du bootstrap. Juste ajouté les classes de jQuery valider au bon endroit. erreur de validation de champ et erreur de validation d’entrée

  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; } 

Voici comment je l’ai fait avec Bootstrap 2.x et jQuery Validate 1.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'); }}); 

S’il vous plaît jeter un oeil à ce qui suit:
https://gist.github.com/3030983
Je pense que c’est le plus simple de tous.

MODIFIER

Code de lien:

 $('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({ sortinggger: 'manual', placement: 'top', content: value.message, template: '

' }); _popover.data('popover').options.content = value.message; $(value.element).popover('show'); }); } });

Merci beaucoup pour la direction! Voici ma version pour Bootstrap mais avec les info-bulles. À mon avis, c’est plus élégant que les popovers. Je sais que la question concernait les popovers, alors ne votez pas pour cette raison. Peut-être que quelqu’un l’aimera de cette façon. J’adore quand je cherche quelque chose et j’ai trouvé de nouvelles idées sur Stackoverflow. Remarque: aucun marquage sur le formulaire n’est nécessaire.

  $('#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', sortinggger: 'manual', delay: { show: 500, hide: 5000 } }).tooltip('show'); }); } }); 

Voilà comment je l’ai fait arriver. Mais cela implique de faire 2 changements au script de validation (j’ai obtenu le code pour le bootstrap 1.4 et je l’ai modifié – http://mihirchitnis.net/2012/01/customizing-error-messages-using-jquery-validate-plugin- pour-twitter-bootstrap / )

Mon appel pour valider:

  $("#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); } } }); 

Ensuite, vous devez changer 2 choses dans jquery.validate.js
1. appliquer ce correctif – https://github.com/bsrykt/jquery-validation/commit/6c3f53ee00d8862bd4ee89bb627de5a53a7ed20a
2. Après la ligne 647 (dans la fonction showLabel, créez une partie d’étiquette) après la ligne .addClass(this.settings.errorClass) ajoutez la ligne: .addClass("help-inline")
Quelqu’un peut peut-être trouver un moyen d’appliquer le second correctif dans la fonction de validation, mais je n’ai pas trouvé le moyen, car showLabel est appelé after mettre en évidence.

C’est ce que j’ai mis dans ma validation pour me conformer aux directives de Twitter Bootstrap. Le message de validation d’erreur est placé dans un et nous souhaitons mettre en évidence le conteneur externe comme une error ou un 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'); } 

Voici une mise à jour de l’excellente réponse de Kenny Meyer ci-dessus . Il y avait quelques problèmes qui l’empêchaient de fonctionner pour moi, que j’ai résolu dans cet extrait:

 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({ sortinggger: "manual", placement: "top", content: function(){ //use a function to assign the error message to content return error.message }, template: '

' }); //bs.popover must be used, not just popover ele.data("bs.popover").options.content = error.message; return $(error.element).popover("show"); }); }

Vous ne savez pas si cela est pertinent pour la discussion car l’affiche originale demandait des crochets pour afficher / masquer les pop-ups bootstrap.

Je cherchais une validation simple et les popovers n’avaient pas d’importance. Une publication associée et la première dans les résultats de recherche Google ont déjà été marquées en double de cette question. Il était donc logique de mentionner cet excellent jqValidation JS de @ ReactiveRaven, appelé jqBootstrapValidation, qui se marie bien avec Twitter Bootstrap. L’installation ne prend que quelques minutes. Téléchargez ici .

J’espère que cela ajoute de la valeur.

Evitez d’avoir besoin d’énumérer les popovers explicites en utilisant une carte de hachage pour stocker les identifiants des éléments et créer des popovers à la volée (approches de mashup Jeffrey Gilbert et Kenny Meyer).

Voici ma prise, qui corrige le problème de scintillement mentionné par d’autres, mais contrairement à la réponse de @Jeffrey Gilbert, n’utilise pas de liste ( errorStates ) mais utilise plutôt une carte d’ erreur. Cartes de hachage FTW. Je pense que je me souviens avoir lu quelque part que chaque problème dans CS peut être résolu avec une carte de hachage 🙂

 var err_map = new Object(); // <--- nb $("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: "

" }); _popover.data("popover").options.content = value.message; err_map[value.element.id] = _popover; return err_map[value.element.id].popover("show"); } }); } });

Merci à tous ceux qui ont posté des idées à ce sujet.

Checkout ceci: https://github.com/mingliangfeng/jquery.validate.bootstrap.popover

Il montre comment utiliser css Bootstrap popover, au lieu de JS. La méthode popup JS provoquera un problème de clignotement.

Si vous utilisez le code Kenny Meyer ci-dessus pour les fenêtres pop-up, sachez que les règles qui vérifient le contenu d’un champ, mais qui ne sont pas obligatoires, comme une URL valide, ne feront pas disparaître le popup. Voir ci-dessous pour la solution. Si quelqu’un a une meilleure solution, merci de poster.

 onkeyup: function(element, event) { if($(element).valid()) { return $(element).popover("hide"); } }