Over-ride the default error messages for jQuery Validate

If you’re using the jQuery Validate plugin and are constantly customizing the error messages, here’s a way you can do it all at once. Insert this code anytime after you’ve included the validate plugin.

jQuery.extend(jQuery.validator.messages, {
    required: "This field is required.",
    remote: "Please fix this field.",
    email: "Please enter a valid email address.",
    url: "Please enter a valid URL.",
    date: "Please enter a valid date.",
    dateISO: "Please enter a valid date (ISO).",
    number: "Please enter a valid number.",
    digits: "Please enter only digits.",
    creditcard: "Please enter a valid credit card number.",
    equalTo: "Please enter the same value again.",
    accept: "Please enter a value with a valid extension.",
    maxlength: jQuery.validator.format("Please enter no more than {0} characters."),
    minlength: jQuery.validator.format("Please enter at least {0} characters."),
    rangelength: jQuery.validator.format("Please enter a value between {0} and {1} characters long."),
    range: jQuery.validator.format("Please enter a value between {0} and {1}."),
    max: jQuery.validator.format("Please enter a value less than or equal to {0}."),
    min: jQuery.validator.format("Please enter a value greater than or equal to {0}.")
});

The various ways to declare your jQuery Validate rules

The following are all acceptable methods for declaring validation rules for the jQuery Validation plugin.

1) Declared within `.validate()`

Use this when you’re trying to keep your JavaScript separate from your HTML markup.

$(document).ready(function() {
        
    $('#myform').validate({
        rules: {
            fieldName: {
                required: true
            }
        }
    });
        
});

DEMO: http://jsfiddle.net/uTt2X/2/

NOTE: If your field `name` contains special characters such as brackets or dots, you must enclose the `name` in quotes

$(document).ready(function() {
        
    $('#myform').validate({
        rules: {
            "field.Name[234]": {
                required: true
            }
        }
    });
        
});

—–

2) Declared by `class`:

Only use this when your rules can be declared by a boolean `true` as you cannot pass any parameters.

<input name="fieldName" class="required" />

DEMO: http://jsfiddle.net/uTt2X/1/

—–

3) Declared by HTML5 validation attributes:

Use this if you already have HTML 5 validation attributes within your form. Only use this when your rules can be declared with HTML 5 validation attributes. Not all rules can be declared in this fashion.

<input name="fieldName" required="required" />

DEMO: http://jsfiddle.net/uTt2X/

—–

4) Declared using the `.rules()` method:

You must use this method if you’re dynamically creating form elements.

$('input[name="fieldName"]').rules('add', {
    required: true
});

DEMO: http://jsfiddle.net/uTt2X/3/

However, as per the documentation, this method only applies to the first matched element. The solution is then to wrap it within a jQuery `.each()` for assigning rules to many inputs at once.

$('.myclass').each(function() {
    $(this).rules('add', {
        required: true
    });
});

DEMO: http://jsfiddle.net/uTt2X/8/

—–

5) By assigning one or more rules to your own `class` using the `.addClassRules()` method:

Use this for assigning rules to fields by their class or for creating an arbitrary `class` representing the rule. Great for creating “compound” rules. Compound rules are rules that are composed of two or more standard rules, like `required` and `email`.

$.validator.addClassRules("myClass", {
    required: true,
    email: true 
});

Then apply to your HTML:

<input name="fieldName" class="myClass" />

DEMO: http://jsfiddle.net/uTt2X/4/

How to properly initialize the jQuery Validate plugin

Based on time spent at Stack Overflow, there seems to be a popular misconception that the `.validate()` method is how you would directly “validate” or test validity when you submit the form.  This leads to all kinds of clever over-thinking… like wrapping `.validate()` inside of `click` and `submit` handlers,  which then leads to all kinds of problems like having to click twice before validation messages appear or a form submission with no validation at all. This is because the `.validate()` method is only used for initialization of the plugin and can only be called once on DOM ready (or anytime after the form’s markup is created). Any/all subsequent calls to `.validate()` are always ignored.

The plugin works simply and it automatically captures the click of the submit button to prevent a form submission until certain validation rules are satisfied.  I mean, that’s the whole point of the plugin… if you had to create your own `click` handlers and test things manually before submitting, then you might as well not have the plugin at all.

To properly initialize this plugin, all you need to do is call the `.validate()` method within the DOM ready event handler.  This is where you would declare rules, options, or over-ride any callback functions.

$(document).ready(function() { // <- ensure DOM is ready

    $('#myform').validate({
        // your rules, options and callback functions
    });

});

Once properly initialized as above, the plugin will automatically perform validation upon various event triggers such as on `keyup` during data entry, on `focusout` of the field, and on `click` of the submit button, not to mention the events that trigger validation of the `select`, `radio` and `checkbox` elements. It’s only after all validation rules are satisfied that the form will be allowed to submit.

To programmatically check validation you would use the `.valid()` method on the entire form or a single element. For example, let’s say you want to use a link (an anchor element), `<a>`, in place of the `type=”submit”` input/button. This code is only used for illustration as the most semantically correct way to do this is to use a `type=”submit”` `<input>` or `<button>` element.

$('#myLink').on('click', function(e) {
    e.preventDefault();     // <- block the '<a>' default behavior, history, page jump on click, etc.
    $('#myform').valid(); {  // <- triggers validation test of whole form, similar to the test on a submit button click.
});

Bottom line, the `.validate()` method, most typically, only goes inside the DOM ready event handler function to be called once on page load. It only has one purpose, to initialize the plugin on your form and to declare any plugin options during that initialization.

jQuery Validate plugin requires a name attribute

Remember that no matter how you declare your rules when using jQuery Validate, even if you target by `id` and declare with the `.rules(‘add’)` method, you must absolutely have a `name` attribute on any form element you wish to validate.

<input name=”firstName” type=”text” …

See the Markup recommendations section of the Reference docs page:

“The name attribute is ‘required’ for input elements, the validation plugin doesn’t work without it.”

Why? The `name` attribute is how the jQuery Validate plugin keeps track of the inputs internally. Even though the documentation doesn’t specify it, it only stands to reason that if this is how the plugin is keeping track of everything, you must make sure each `name` is unique.

Integrate Tooltipster with jQuery Validate

Prerequisites:

Tooltipster Plugin version 2.1 or 3.0 (The raw code for version 2.1 can be found inside the first jsFiddle below.)
jQuery Validate Plugin

First, initialize the Tooltipster plugin (with any options) on all specific `form` elements that will display errors:

$(document).ready(function () {

        // initialize tooltipster on form input elements
        $('#myform input[type="text"]').tooltipster({ 
            trigger: 'custom', // default is 'hover' which is no good here
            onlyOne: false,    // allow multiple tips to be open at a time
            position: 'right'  // display the tips to the right of the element
        });
    
});

Second, use Tooltipster’s advanced options along with the `success:` and `errorPlacement:` callback functions built into the Validate plugin to automatically show and hide the tooltips as follows:

$(document).ready(function () {
    
        // initialize validate plugin on the form
        $('#myform').validate({
            // any other options & rules,
            errorPlacement: function (error, element) {
                $(element).tooltipster('update', $(error).text());
                $(element).tooltipster('show');
            },
            success: function (label, element) {
                $(element).tooltipster('hide');
            }
        });
    
});

Working Demo: jsfiddle.net/2DUX2

Note that this code example takes advantage of the new Tooltipster API features released in version 2.1 on 2/12/13

For Tooltipster version 3.0

The latest version of Tooltipster, version 3.0, is supposed to be working more correctly than version 2.1.

That’s fine, except that an animation flicker is now occurring on every single keystroke even when no content has changed. I suppose we could disable the default `onkeyup` option in jQuery Validate, but when multiple rules are used, the user would not be aware of his data entry violation until after leaving the field or clicking the submit button.

The workaround is to set the `updateAnimation` option to `false`.

$(document).ready(function () {

        // initialize tooltipster on form input elements
        $('#myform input[type="text"]').tooltipster({ 
            trigger: 'custom',     // default is 'hover' which is no good here
            onlyOne: false,        // allow multiple tips to be open at a time
            position: 'right',     // display the tips to the right of the element
            updateAnimation: false // stops the flicker on every keyup
        });
    
});

Demo: jsfiddle.net/2DUX2/2/

I’ve made a suggestion to the developer to simply check the new incoming content against the existing content and only run the animation when they’re different. I can see other practical applications for this… any situation where the same content is sent repeatedly but yet we still want an animation to occur when/if it changes. I’ll update this posting as the situation warrants.

UPDATE:

The Tooltipster developer made the following suggestion to preserve the message update animation in version 3.0, which works very nicely. From within the jQuery Validate plugin’s `errorPlacement` callback function, this simple code makes sure the error message is not blank and has changed before calling Tooltipster’s `show` method. This has the added benefit of greatly reducing the number of calls to Tooltipster.

$(document).ready(function () {
    
        // initialize validate plugin on the form
        $('#myform').validate({
            // any other options & rules,
            errorPlacement: function (error, element) {
                var lastError = $(element).data('lastError'), // get the last message if one exists
                    newError = $(error).text();               // set the current message
            
                $(element).data('lastError', newError);  // set "lastError" to the current message for the next time 'errorPlacement' is called
      
                if(newError !== '' && newError !== lastError){  // make sure the message is not blank and not equal to the last message before allowing the Tooltip to update itself
                    $(element).tooltipster('content', newError); // insert content into tooltip
                    $(element).tooltipster('show');              // show the tooltip
                }
            },
            success: function (label, element) {
                $(element).tooltipster('hide');  // hide tooltip when field passes validation
            }
        });
    
});

Demo: jsfiddle.net/2DUX2/3/