Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Using the jQuery Unobtrusive Validator with Twitter Bootstrap Tooltips

5.00/5 (26 votes)
21 Jul 2014CPOL3 min read 77.1K   2K  
jQuery unobtrusive validation plugin with Twitter Bootstrap 3 showing error messages as tooltips

Introduction

When using JQuery unobtrusive validation, the error message is shown by creating a span which displaces the position of the existing controls. If you have, for example, a horizontal form on top of other controls, then this behavior might not be working for you since it will break the page layout. It was the case for me and as such, I decided to change the default behavior of the JQuery unobtrusive validation library and instead of using a span to show the error message, I decided to use a tooltip. I was also using Twitter Bootstrap so integrating with it was the next step.

Background

I started looking for a library which is doing that, but while there are libraries which do something similar, I haven’t found one doing exactly what I wanted. My starting point was the nugget package library with id jquery.validate.unobtrusive.bootstrap which is an extension of jQuery Validate Unobtrusive for Bootstrap 3. There are a few articles describing how to show a Bootstrap tooltip as the validation message, but I have found none which also changes the style of the tooltip to something more appropriate for an error message. So I decided to write one of my own - jquery.validate.unobtrusive.bootstrap.tooltip.js.

Using the Code

Besides adding this library as a reference, you also have to add jQuery, jQuery validate and jQuery unobtrusive validation. I have registered the following script bundle:

JavaScript
bundles.Add(new ScriptBundle("~/bundles/validate").Include(
    "~/Scripts/jquery.validate.js",
    "~/Scripts/jquery.validate.unobtrusive.js",
    "~/Scripts/own/jquery.validate.unobtrusive.bootstrap.tooltip.js")); 

The page must also include bootstrap.css and boostrap.js. In addition, a stylesheet containing the tooltip customization classes which are included later on in this article has to be referenced.

The first required step was to change the showErrors function. This is the last method on the validator before the methods which create the span are called. It is done on the document load:

JavaScript
$(function () {
    $('form').each(function () {
        var validator = $(this).data('validator');
        validator.settings.showErrors = onValidated;
    });
}); 

The onValidated function is iterating through all the controls with errors and it shows the error message as a tooltip. In the case a control is no longer in error state, it is added to success collection. The method iterates over the controls with no errors and it destroys the tooltips for them, as it can be seen below. The listing contains the whole JavaScript library:

JavaScript
(function ($) {
    var classes = { groupIdentifier: ".form-group", 
                    error: 'has-error', success: null };//success: 'has-success' 
    function updateClasses(inputElement, toAdd, toRemove) {
        var group = inputElement.closest(classes.groupIdentifier);
        if (group.length > 0) {
            group.addClass(toAdd).removeClass(toRemove);
        }
    }
    function onError(inputElement, message) {
        updateClasses(inputElement, classes.error, classes.success);

        var options = { html: true, title: 
                      '<div class="tooltip-alert alert-danger">' + message + '</div>' };
        inputElement.tooltip("destroy")
            .addClass("error")
            .tooltip(options);
    }
    function onSuccess(inputElement) {
        updateClasses(inputElement, classes.success, classes.error);
        inputElement.tooltip("destroy");
    }

    function onValidated(errorMap, errorList) {
        $.each(errorList, function () {
            onError($(this.element), this.message);
        });

        if (this.settings.success) {
            $.each(this.successList, function () {
                onSuccess($(this));
            });
        }
    }

    $(function () {
        $('form').each(function () {
            var validator = $(this).data('validator');
            validator.settings.showErrors = onValidated;
        });
    });
}(jQuery)); 

While initially I considered setting the form-group as successfully validated, I decided that the normal appearance is more appropriate. If one wants to show it as successfully validated, though, this can be done by assigning to the success class the has-success bootstrap class.

To make the tooltip look appropriate as an error validation message, I had to make the content of the tooltip HTML and to include in it a div with class class="tooltip-alert alert-danger" containing the error message. The classes added to change the tooltip look are:

CSS
.tooltip-inner {
    max-width: 300px;
    padding: 0;
}
.tooltip-alert{
    padding: 8px 10px;
    font-weight: bolder;
    color: #A94442;
} 

The ASP.NET MVC view has a form which contains no validation message:

HTML
<form class="form-horizontal" role="form" onsubmit="return false;">
    <div class="form-group col-sm-3">
        @Html.LabelFor(model => model.From, new { @class = "control-label col-sm-2" })
        <div class="col-sm-10">
            @Html.TextBoxFor(m => m.From, new { type = "date", @class = "form-control" })
        </div>
    </div>
    
    <div class="form-group col-sm-3">
        @Html.LabelFor(model => model.To, new { @class = "control-label col-sm-1" })
        <div class="col-sm-10">
            @Html.TextBoxFor(m => m.To, new { type = "date", @class = "form-control" })
        </div>
    </div>
    <div class="form-group col-sm-5">
        @Html.LabelFor(model => model.Accounts, new { @class = "control-label col-sm-3" })
        <div class="col-sm-9">
            @Html.DropDownList("Accounts", Model.Accounts, new { @class = "form-control" })
        </div>
    </div>
    <div class="col-sm-1">
        <button type="submit" class="btn btn-default">Show</button>
    </div>
</form> 

The end result is the one from the image below:

form

Points of Interest

The interesting part of this code was not changing the jQuery unobtrusive validation library itself but extending it. Having a background in C# and server side development, this proved to be more easy to do than I was expecting.

History

  • 6th April, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)