FormValidation v0.8.1 is released, supports Bootstrap 4 alpha 3

Showing valid message

Examples

The plugin only provides error message option which is shown when the field is invalid. Is it possible to add a valid message option shown if the field is valid?

The quick answer is YES. This example shows you how to implement this feature.

Assuming that our form has two text boxes which are username and password.

<form id="signupForm" method="post" class="form-horizontal">
    <div class="form-group">
        <label class="col-sm-3 control-label">Username</label>
        <div class="col-sm-5">
            <input type="text" class="form-control" name="username" />
        </div>
    </div>

    <div class="form-group">
        <label class="col-sm-3 control-label">Password</label>
        <div class="col-sm-5">
            <input type="password" class="form-control" name="password" />
        </div>
    </div>

    <div class="form-group">
        <div class="col-sm-5 col-sm-offset-3">
            <button type="submit" class="btn btn-default">Signup</button>
        </div>
    </div>
</form>

As usual, the plugin is called by following snippet code:

$(document).ready(function() {
    $('#signupForm').formValidation({
        icon: {
            ...
        },
        fields: {
            username: {
                validators: {
                    ...
                }
            },
            password: {
                validators: {
                    ...
                }
            }
        }
    });
});

The implementation idea consists of four steps as following.

Adding valid message option

I add an option named validMessage for each field. As the name suggests, the plugin will show the valid message when the field is valid.

$(document).ready(function() {
    $('#signupForm').formValidation({
        icon: {
            ...
        },
        fields: {
            username: {
                validMessage: 'The username looks great',
                validators: {
                    ...
                }
            },
            password: {
                validMessage: 'The password is good',
                validators: {
                    ...
                }
            }
        }
    });
});

We can get the option value later via the getOptions() method.

Creating an element that shows the invalid message

Basically, you can place the valid message anywhere you want as long as you can retrieve it later.

Behind the scenes, FormValidation places each error message in a span element. The field error messages are placed inside an element which can be retrieved by $field.data('bv.messages').

To make the example easily to follow, I simply create a span element right after each field for showing the valid message:

<form id="signupForm" method="post" class="form-horizontal">
    <div class="form-group">
        <label class="col-sm-3 control-label">Username</label>
        <div class="col-sm-5">
            <input type="text" class="form-control" name="username" />
            <span class="help-block validMessage"></span>
        </div>
    </div>

    <div class="form-group">
        <label class="col-sm-3 control-label">Password</label>
        <div class="col-sm-5">
            <input type="password" class="form-control" name="password" />
            <span class="help-block validMessage"></span>
        </div>
    </div>

    ...
</form>

In fact, the number of fields might be greater than two as in our example. Therefore, it is much better if these valid message elements are created dynamically. It's quite easy to do it by triggering the init.field.fv event:

$(document).ready(function() {
    $('#signupForm')
        .on('init.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element,      // Get the field element
                bv     = data.fv;           // FormValidation instance

            // Create a span element to show valid message
            // and place it right before the field
            var $span = $('<small/>')
                            .addClass('help-block validMessage')
                            .attr('data-field', field)
                            .insertAfter($field)
                            .hide();

            // Retrieve the valid message via getOptions()
            var message = bv.getOptions(field).validMessage;

            if (message) {
                $span.html(message);
            }
        })
        .formValidation({
            ...
        });
});
The init.field.fv event is triggered after the field is initialized by the plugin. In order to trigger the event, you must declare .on('init.field.fv') before calling formValidation(options).

In step 2 above, the custom option validMessage is determined by using the getOptions() method.

Showing the valid message when the field is valid

Triggering the success.field.fv event to do that:

$(document).ready(function() {
    $('#signupForm')
        .on('init.field.fv', function(e, data) {
            ...
        })
        .formValidation({
            ...
        })
        .on('success.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element;      // Get the field element

            // Retrieve the valid message element
            $field
                .next('.validMessage[data-field="' + field + '"]')
                .show();  // Show it
        });
});

Hiding the valid message when the field is invalid

Finally, being similar to the step 3, the valid message must be hidden when the field turns to be invalid. It can be done via the err.field.fv event:

$(document).ready(function() {
    $('#signupForm')
        .on('init.field.fv', function(e, data) {
            ...
        })
        .formValidation({
            ...
        })
        .on('success.field.fv', function(e, data) {
            ...
        })
        .on('err.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element;      // Get the field element

            // Hide the valid message element
            $field
                .next('.validMessage[data-field="' + field + '"]')
                .hide();
        });
});

Final result

Below is the final working example:

<form id="signupForm" method="post" class="form-horizontal">
    <div class="form-group">
        <label class="col-xs-3 control-label">Username</label>
        <div class="col-xs-5">
            <input type="text" class="form-control" name="username" />
        </div>
    </div>

    <div class="form-group">
        <label class="col-xs-3 control-label">Password</label>
        <div class="col-xs-5">
            <input type="password" class="form-control" name="password" />
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-5 col-xs-offset-3">
            <button type="submit" class="btn btn-default">Signup</button>
        </div>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#signupForm')
        .on('init.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element,      // Get the field element
                bv     = data.fv;           // FormValidation instance

            // Create a span element to show valid message
            // and place it right before the field
            var $span = $('<small/>')
                            .addClass('help-block validMessage')
                            .attr('data-field', field)
                            .insertAfter($field)
                            .hide();

            // Retrieve the valid message via getOptions()
            var message = bv.getOptions(field).validMessage;
            if (message) {
                $span.html(message);
            }
        })
        .formValidation({
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                username: {
                    validMessage: 'The username looks great',
                    validators: {
                        notEmpty: {
                            message: 'The username is required'
                        },
                        different: {
                            field: 'password',
                            message: 'The username cannot be same as password'
                        },
                        regexp: {
                            regexp: /^[a-zA-Z0-9]+$/i,
                            message: 'The username can only consist of alphabetical, number'
                        }
                    }
                },
                password: {
                    validMessage: 'The password is good',
                    validators: {
                        notEmpty: {
                            message: 'The password is required'
                        },
                        different: {
                            field: 'username',
                            message: 'The password cannot be same as username'
                        }
                    }
                }
            }
        })
        .on('success.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element;      // Get the field element

            // Show the valid message element
            $field.next('.validMessage[data-field="' + field + '"]').show();
        })
        .on('err.field.fv', function(e, data) {
            var field  = data.field,        // Get the field name
                $field = data.element;      // Get the field element

            // Show the valid message element
            $field.next('.validMessage[data-field="' + field + '"]').hide();
        });
});
</script>