Sunday, November 11, 2012

jQuery-validate error messages in Twitter bootstrap tooltips

At work, we're using the combination of ASP.NET MVC3, jQuery, jQuery-validate, knockout and Twitter Bootstrap on one of our projects. Having postponed looking at the aesthetics of the client-side validation for too long, we eventually found ourselves unsatisfied with the default error labels. Wanting to save on space, we're experimenting with the error messages being shown in a Twitter Bootstrap tooltip. After poking around for some while, I came up with something satisfactory.

In this example, I have a bootstrapped form that looks like this.
@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, new { @class = "form-horizontal"})) {
    <div class="control-group">
        <label class="control-label">Old password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.OldPassword)                            
        </div>       
    </div>
    <div class="control-group">
        <label class="control-label">New password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.NewPassword)                
        </div>
    </div>
    <div class="control-group">
        <label class="control-label">Confirm password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.ConfirmPassword)                
        </div>                            
    </div>  
    <div class="control-group">
        <div class="controls">
            <button type="submit" class="btn btn-primary">Change password</button>
        </div>
    </div>
}
To make the error messages show up in tooltips on the input controls, I eventually ended up with the snippet below.
$.validator.setDefaults({
    showErrors: function (errorMap, errorList) {
        this.defaultShowErrors();                            

        // destroy tooltips on valid elements                              
        $("." + this.settings.validClass)                    
            .tooltip("destroy");            

        // add/update tooltips 
        for (var i = 0; i < errorList.length; i++) {
            var error = errorList[i];
                         
            $("#" + error.element.id)
                .tooltip({ trigger: "focus" })
                .attr("data-original-title", error.message)                
        }
    }
});
I'm setting a custom showErrors function to extend the behaviour of the jQuery validator. I don't want to lose the default behaviour (highlighting etc), so I start with invoking the default showErrors function, to then destroy the tooltip on all valid input elements and to finally add or update the tooltip and its title on all invalid input elements. The errorList argument holds all the information I need for this; an array of invalid elements and their corresponding error messages.
[Object, Object]
> 0: Object
>> element: <input>
>> message: "The Current password field is required."
> 1: Object
>> element: <input>
>> message: "The New password field is required."
> length: 2
The end result looks like this.


19 comments:

  1. Great quick tutorial. Tnx for sharing

    ReplyDelete
  2. Can you post the complete .cshtml page source?

    ReplyDelete
    Replies
    1. There isn't much more to it. It's basically the standard MVC template converted to work with Bootstrap. Are there specific questions I can help you with?

      Delete
  3. This comment has been removed by the author.

    ReplyDelete
  4. works perfect, thnx!

    ReplyDelete
    Replies
    1. just for comment, when i display on a jquery ui dialog dont show the tooltip.

      Delete
    2. Must have something to do with the z-index. Make the one of the tooltip higher.

      Delete
  5. I have created a single javascript file that you reference after jquery.validation.js. Simple adding this reference will make your website (with no code change) validate with twitter bootstrap markup/css. Very unobtrusive and easy to use.

    http://pknopf.com/blog/twitter-bootstrap-clientside-validation-with-jquery-validation-js

    ReplyDelete
  6. Thanks for the wonderful article. Need some more help. In my case, error message also appear along with tooltip. How can I make error message not to appear inline with controls?

    ReplyDelete
    Replies
    1. Forgot to mention that my form is vertical. Wondering if it has anything to do with that.

      Delete
    2. You can hide the default jQuery-validate messages by overriding the css. Here is something relevant on SO http://stackoverflow.com/questions/13132381/jquery-validation-hide-error-messages-and-change-invalid-fields-background-colo

      Delete
    3. Thanks Jef. Another question - how about validation summary as true case? Currently those model validations dont show up :-(

      Delete
    4. You'll need to add some css for that (http://stackoverflow.com/questions/6899609/validationsummary-and-validationmessagefor-with-custom-css-shown-when-no-errors).

      Delete
  7. add this for hide default error label message YEEEP!!!

    errorPlacement: function(error, element) {},

    ReplyDelete
  8. how can i define error message Object? is it in jquery?

    ReplyDelete