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

Using data returned by validator

Examples

In general, most of validators return true if the field is valid or false otherwise.

Validator Returned value
callback validator
function(value, validator, $field) {
    return true;    // or false
}
remote validator

The remote URL has to return an encoded JSON of array containing the valid key:

{ "valid": true or false }
Your own validator
FormValidation.Validator.validatorName = {
    validate: function(validator, $field, options) {
        return true;    // or false;
    }
};

What if you want to attach more data to the returned value and reuse it later? Fortunately, in addition to the boolean value indicating the field validity, it's easy to include more data to the returned value of validators as following:

Validator Returned value
callback validator
function(value, validator, $field) {
    return {
        valid: true,    // or false
        key: 'value of key',
        anotherKey: 'value of key'
    };
}
remote validator

The remote URL has to return an encoded JSON of array containing the valid and other keys:

{
    "valid": true,      // or false,
    "key": "value of key",
    "anotherKey": "value of key"
}
Your own validator
FormValidation.Validator.validatorName = {
    validate: function(validator, $field, options) {
        return {
            valid: true,    // or false
            key: 'value of key',
            anotherKey: 'value of key'
        };
    }
};

Then you can get the returned value when triggering the validator events:

$(form)
    .formValidation(options)

    // This event is triggered when the field doesn't pass any validator
    .on('err.validator.fv', function(e, data) {
        // data.field     --> The field name
        // data.element   --> The field element
        // data.validator --> The validator name
        // data.result    --> The data returned by the validator

        // Do something ...
    })

    // This event is triggered when the field passes any validator
    .on('success.validator.fv', function(e, data) {
        // e, data parameters are the same as
        // in the err.validator.fv event above

        // Do something ...
    });

In the next section, I will demonstrate how to use this approach in some examples.

Password strength meter

The following example shows how strong a password is. We define various rules to define a strong password. Each rule provides a score for the password if it passes the rule.

When user change the password, we loop over the rules and calculate the score. Finally, based on the score, we display the password strength which can be one of the following levels:

  • Very weak, if the score is less than 0
  • Weak, if the score is between 0 and 2
  • Medium, if the score is between 2 and 4
  • Strong, if the score is greater than 4

To archive this, we use the callback validator to calculate the password score. And then trigger the success.validator.fv event to get the score, and show up the level. Looking at the code will give you the implementation details.

The rules and their scores in this example are simple as for demonstrating purpose only. In fact, it's up to you to define more rules and strength levels
<style type="text/css">
.password-meter {
    margin-top: 5px;
}
</style>

<form id="securePasswordForm" class="form-horizontal">
    <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="pwd" />

            <div class="progress password-meter" id="passwordMeter">
                <div class="progress-bar"></div>
            </div>
        </div>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#securePasswordForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                pwd: {
                    validators: {
                        notEmpty: {
                            message: 'The password is required and cannot be empty'
                        },
                        callback: {
                            callback: function(value, validator, $field) {
                                var score = 0;

                                if (value === '') {
                                    return {
                                        valid: true,
                                        score: null
                                    };
                                }

                                // Check the password strength
                                score += ((value.length >= 8) ? 1 : -1);

                                // The password contains uppercase character
                                if (/[A-Z]/.test(value)) {
                                    score += 1;
                                }

                                // The password contains uppercase character
                                if (/[a-z]/.test(value)) {
                                    score += 1;
                                }

                                // The password contains number
                                if (/[0-9]/.test(value)) {
                                    score += 1;
                                }

                                // The password contains special characters
                                if (/[!#$%&^~*_]/.test(value)) {
                                    score += 1;
                                }

                                return {
                                    valid: true,
                                    score: score    // We will get the score later
                                };
                            }
                        }
                    }
                }
            }
        })
        .on('success.validator.fv', function(e, data) {
            // The password passes the callback validator
            if (data.field === 'pwd' && data.validator === 'callback') {
                // Get the score
                var score = data.result.score,
                    $bar  = $('#passwordMeter').find('.progress-bar');

                switch (true) {
                    case (score === null):
                        $bar.html('').css('width', '0%').removeClass().addClass('progress-bar');
                        break;

                    case (score <= 0):
                        $bar.html('Very weak').css('width', '25%').removeClass().addClass('progress-bar progress-bar-danger');
                        break;

                    case (score > 0 && score <= 2):
                        $bar.html('Weak').css('width', '50%').removeClass().addClass('progress-bar progress-bar-warning');
                        break;

                    case (score > 2 && score <= 4):
                        $bar.html('Medium').css('width', '75%').removeClass().addClass('progress-bar progress-bar-info');
                        break;

                    case (score > 4):
                        $bar.html('Strong').css('width', '100%').removeClass().addClass('progress-bar progress-bar-success');
                        break;

                    default:
                        break;
                }
            }
        });
});
</script>

Suggesting new username

In a form for signing up new account, we often use the remote validator to check if the username is available or not.

We can query against the database to check the availability of username which is similar to the given one. And then suggest them to user if they are not taken.

For instance, the remote URL might suggests a list of available username with the full responses as below:

{
    "valid": "false",
    "suggestions": ["username1", "username2", "username3"]
}

The following form shows how this approach works in action:

For testing purpose, the back-end used in the example always responses the same list of available username
<form id="signupForm" 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>
</form>

<script>
$(document).ready(function() {
    $('#signupForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                username: {
                    validators: {
                        notEmpty: {
                            message: 'The username is required and cannot be empty'
                        },
                        remote: {
                            message: 'The username is not available',
                            url: '/examples/using-data-returned-validator/remote/response.json'
                        }
                    }
                }
            }
        })
        .on('err.validator.fv', function(e, data) {
            if (data.field === 'username' && data.validator === 'remote') {
                var suggestions = data.result.suggestions;
                // Update the message
                suggestions
                    ? data.fv.updateMessage('username', 'remote', 'Not available. You might choose other one: ' + suggestions.join(', '))
                    : data.fv.updateMessage('username', 'remote', 'The username is not available');
            }
        });
});
</script>

Related examples