How to use Twitter Bootstrap popovers for jQuery validation notifications?

83,086

Solution 1

Take a look at the highlight and showErrors jQuery Validator options, these will let you hook in your own custom error highlights that trigger Bootstrap popovers.

Solution 2

This is a hands-on example:

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

enter image description here

It doesn't really use bootstrap popovers, but it looks really nice and is easy to achieve.

UPDATE

So, to have popover validation you can use this 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({
        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");
    });
  }
});

You get something like this:

enter image description here

Check out the jsFiddle.

Solution 3

Chris Fulstow had it right, but it still took me a while, so heres the complete code:

This shows the popover on error, and hides the default error labels:

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

This sets up the popover. The only thing you need from this is trigger: 'manual'

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

The title and content attributes passed in to popover weren't working, so I specified them inline in my #password input with data-content='Minimum 5 characters' and data-original-title='Invalid Password'. You also need rel='popover' in your form.

This works, but the popover flickers upon unselecting. Any idea how to fix that?

Solution 4

Here's a follow up to the excellent suggestion from Varun Singh which prevents the "flicker" issue of the validation constantly trying to "show" even though the popup is already present. I've simply added an error states array to capture which elements are showing errors and which aren't. Works like a charm!

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

Solution 5

This jQuery extension for jQuery Validation Plugin (tested with version 1.9.0) will do the trick.

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

This also adds in some Rails-esk error messaging.

Share:
83,086

Related videos on Youtube

Synchro
Author by

Synchro

Skier, Biker, PHP coder, Email wiz, Sysadmin, DBA, Privacy nut, Pentester, Speaker, Baker, Daddy

Updated on August 02, 2020

Comments

  • Synchro
    Synchro almost 4 years

    I can make popovers appear using bootstrap easily enough, and I can also do validations using the standard jQuery validation plugin or the jQuery validation engine, but I can't figure out how to feed one into the other.

    I think what I need is some hook which is called by the validator when it wants to display a notification, give it a closure that passes the message and the target element to a popover. This seems like a kind of dependency injection.

    All nice in theory, but I just can't figure out where that hook is, or even if one exists in either validation engine. They both seem intent on taking responsibility for displaying notifications with all kinds of elaborate options for placement, wrappers, styles when all I'm after is the error type(s) (I don't necessarily even need message text) and element it relates to. I've found hooks for the entire form, not the individual notifications.

    I much prefer validation systems that use classes to define rules, as they play nicely with dynamically created forms.

    Anyone have a solution or a better idea?

  • Synchro
    Synchro over 12 years
    That's great, thanks. highlight and unhighlight are what I was looking for.
  • namin
    namin over 12 years
    Upvoted because this is in the direction of what I was looking for. :-) See my answer for a variant.
  • Freshblood
    Freshblood about 12 years
    This approach looks best for me :) . This is also what i was thinking
  • tig
    tig about 12 years
    This is great. Super helpful. Now to figure out how to get an appropriate message for a TOS checkbox...
  • alastairs
    alastairs over 11 years
    This was the only answer on this page that worked for me. Shame it's not been voted up more.
  • Adrian P.
    Adrian P. over 11 years
    Many thanks for the heads up! See down my version for Bootstrap but with Tooltips. In my opinion it's more elegant than popovers.
  • Richard Pérez
    Richard Pérez over 11 years
    I tried to use your approach, but I was starting to get and error. ant he problem is if you use Jquery UI you will get conflict because both use tooltip. I know there is a solution for that, but just want let others users to know that.
  • Adrian P.
    Adrian P. over 11 years
    +1 For jQuery UI heads up! You'll have to configure your custom download (jQueryUI or Bootstrap) to NOT include Tooltip JS functions. It will be a conflict anyway for any tooltip if you failed to do so.
  • Tachyons
    Tachyons over 11 years
    What to do if it is a multistage form
  • psharma
    psharma about 11 years
    hey there I was trying to use your code with regex and happen to have an error at stackoverflow.com/questions/16087351/… . Do you think you can help? :)
  • Adrian P.
    Adrian P. about 11 years
    @psharma Nothing to do with bootstrap or tooltip. Your error is your rule declaration as you got an answer on your question. the error message said: terms is undefined!
  • Admin
    Admin about 11 years
    Doesn't this mean you need to define an explicit popover for every single field you want to validate? If so that's nuts.
  • davidethell
    davidethell almost 11 years
    Just a quick note that with the latest version of Bootstrap there is not longer a .data("popover") key. Perhaps to avoid collision they have changed the key to "bs.popover". Took me a while to figure out why I was getting an undefined error. So now you'll need to use _popover.data("bs.popover").options.content = value.message; in the code above.
  • arjun
    arjun over 10 years
    How can i display popup on other error type other than required fields. I mean to say how can i customize it to display error only on specific rules.
  • Jeffrey Gilbert
    Jeffrey Gilbert over 10 years
    For most use cases, I would expect this is perfectly acceptable. If you have a more optimal solution, feel free to add it :)
  • G4bri3l
    G4bri3l about 10 years
    There's actually a little problem you can easily check out in the jsFiddle as well. If the field is not required and some rule is broken, the popover shows up BUT if I empty the field and focus on another field, the popover is still there. The first loop on the successList is never called, so the popover is never in a "hide" state after it gets in a "show" state. Is there anything we can do about it ?
  • suchanoob
    suchanoob almost 8 years
    For some reason, this is the only solution that worked for me. Thanks!
  • Kenny Meyer
    Kenny Meyer about 6 years
    Thank you for the initiative. The code has changed a lot as I can see :-)