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

Using Google material icons

Examples

FormValidation will show a feedback icon when a field is being validated, invalid or valid. The icons can be set by the icon option:

icon: {
    valid: null,        // The CSS classes of valid icon
    invalid: null,      // The CSS classes of invalid icon
    validating: null    // The CSS classes of validating icon
}

By using this option, it's easy to use the icons provided by different icon sets such as

This example shows how to use the Google material design icons.

It's up to you to choose suitable icons from Google material design icons for the feedback icons. The following table is just an example of three icons taken from the set:

Field status Icon
Valid
<i class="material-icons">check</i>
Invalid
<i class="material-icons">clear</i>
Being validated
<i class="material-icons">graphic_eq</i>

As you see, each Google material design icon uses pre-defined content instead of a different CSS class. Meanwhile, the icon option only accepts CSS classes that are added to the icon based on the field validity.

The next section introduces two approaches to solve this problem.

Defining icon content by CSS

By using the :after CSS selector, we can indicated content of icons as following:

.material-icons.valid-icon:after {
    // The content of valid icon is 'check'
    content: 'check';
    font-size: 15px;
}
.material-icons.invalid-icon:after {
    // The content of invalid icon is 'clear'
    content: 'clear';
    font-size: 15px;
}
.material-icons.validating-icon:after {
    content: 'graphic_eq';
    font-size: 15px;
}

Lastly, you just set the icons for each status of field:

$('#googleIconsForm').formValidation({
    framework: 'bootstrap',
    icon: {
        valid: 'material-icons valid-icon',
        invalid: 'material-icons invalid-icon',
        validating: 'material-icons validating-icon'
    }
    ...
});
<!-- Include Google material icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<style>
.material-icons.valid-icon:after {
    content: 'check';
    font-size: 15px;
}
.material-icons.invalid-icon:after {
    content: 'clear';
    font-size: 15px;
}
.material-icons.validating-icon:after {
    content: 'graphic_eq';
    font-size: 15px;
}
</style>

<form id="googleIconsForm" class="form-horizontal">
    <div class="form-group">
        <label class="col-xs-3 control-label">Full name</label>
        <div class="col-xs-4">
            <input type="text" class="form-control" name="firstName" placeholder="First name" />
        </div>
        <div class="col-xs-4">
            <input type="text" class="form-control" name="lastName" placeholder="Last name" />
        </div>
    </div>

    <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">Email address</label>
        <div class="col-xs-5">
            <input type="text" class="form-control" name="email" />
        </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">
        <label class="col-xs-3 control-label">Gender</label>
        <div class="col-xs-6">
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="male" /> Male
                </label>
            </div>
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="female" /> Female
                </label>
            </div>
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="other" /> Other
                </label>
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-6 col-xs-offset-3">
            <div class="checkbox">
                <label>
                    <input type="checkbox" name="agree" value="agree" /> Agree with the terms and conditions
                </label>
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-9 col-xs-offset-3">
            <button type="submit" class="btn btn-primary" name="signup" value="Sign up">Submit</button>
        </div>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#googleIconsForm').formValidation({
        framework: 'bootstrap',
        icon: {
            valid: 'material-icons valid-icon',
            invalid: 'material-icons invalid-icon',
            validating: 'material-icons validating-icon'
        },
        fields: {
            firstName: {
                row: '.col-xs-4',
                validators: {
                    notEmpty: {
                        message: 'The first name is required'
                    }
                }
            },
            lastName: {
                row: '.col-xs-4',
                validators: {
                    notEmpty: {
                        message: 'The last name is required'
                    }
                }
            },
            username: {
                validators: {
                    notEmpty: {
                        message: 'The username is required'
                    },
                    stringLength: {
                        min: 6,
                        max: 30,
                        message: 'The username must be more than 6 and less than 30 characters long'
                    },
                    regexp: {
                        regexp: /^[a-zA-Z0-9_\.]+$/,
                        message: 'The username can only consist of alphabetical, number, dot and underscore'
                    }
                }
            },
            email: {
                validators: {
                    notEmpty: {
                        message: 'The email address is required'
                    },
                    emailAddress: {
                        message: 'The input is not a valid email address'
                    }
                }
            },
            password: {
                validators: {
                    notEmpty: {
                        message: 'The password is required'
                    },
                    different: {
                        field: 'username',
                        message: 'The password cannot be the same as username'
                    }
                }
            },
            gender: {
                validators: {
                    notEmpty: {
                        message: 'The gender is required'
                    }
                }
            },
            agree: {
                validators: {
                    notEmpty: {
                        message: 'You must agree with the terms and conditions'
                    }
                }
            }
        }
    });
});
</script>

Triggering the event

In this approach, we set the same material-icons class for all icons:

$('#googleIconsForm').formValidation({
    icon: {
        valid: 'material-icons',
        invalid: 'material-icons',
        validating: 'material-icons'
    },
    ...
});

In order to update the content of icon based on the field validity status, we can handle the status.field.fv event that is triggered whenever the field status is updated:

$('#googleIconsForm')
    .formValidation({
        icon: {
            valid: 'material-icons',
            invalid: 'material-icons',
            validating: 'material-icons'
        },
        ...
    })
    .on('status.field.fv', function(e, data) {
        var $element = data.element,                // Get the field element
            $icon    = $element.data('fv.icon');    // The feedback icon associates with the field

        switch (data.status) {
            case 'VALID':
                $icon.html('check');
                break;
            case 'INVALID':
                $icon.html('clear');
                break;
            case 'VALIDATING':
                $icon.html('graphic_eq');
                break;
            case 'NOT_VALIDATED':
            default:
                $icon.html('');
                break;
        }
    });
});
Tip: For a given field, we can retrieve the icon element via $field.data('fv.icon') as seen in the sample code above
<!-- Include Google material icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<style>
.material-icons {
    font-size: 15px;
    line-height: 34px;
}
</style>

<form id="googleIconsForm" class="form-horizontal">
    <div class="form-group">
        <label class="col-xs-3 control-label">Full name</label>
        <div class="col-xs-4">
            <input type="text" class="form-control" name="firstName" placeholder="First name" />
        </div>
        <div class="col-xs-4">
            <input type="text" class="form-control" name="lastName" placeholder="Last name" />
        </div>
    </div>

    <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">Email address</label>
        <div class="col-xs-5">
            <input type="text" class="form-control" name="email" />
        </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">
        <label class="col-xs-3 control-label">Gender</label>
        <div class="col-xs-6">
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="male" /> Male
                </label>
            </div>
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="female" /> Female
                </label>
            </div>
            <div class="radio">
                <label>
                    <input type="radio" name="gender" value="other" /> Other
                </label>
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-6 col-xs-offset-3">
            <div class="checkbox">
                <label>
                    <input type="checkbox" name="agree" value="agree" /> Agree with the terms and conditions
                </label>
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-9 col-xs-offset-3">
            <button type="submit" class="btn btn-primary" name="signup" value="Sign up">Submit</button>
        </div>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#googleIconsForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'material-icons',
                invalid: 'material-icons',
                validating: 'material-icons'
            },
            fields: {
                firstName: {
                    row: '.col-xs-4',
                    validators: {
                        notEmpty: {
                            message: 'The first name is required'
                        }
                    }
                },
                lastName: {
                    row: '.col-xs-4',
                    validators: {
                        notEmpty: {
                            message: 'The last name is required'
                        }
                    }
                },
                username: {
                    validators: {
                        notEmpty: {
                            message: 'The username is required'
                        },
                        stringLength: {
                            min: 6,
                            max: 30,
                            message: 'The username must be more than 6 and less than 30 characters long'
                        },
                        regexp: {
                            regexp: /^[a-zA-Z0-9_\.]+$/,
                            message: 'The username can only consist of alphabetical, number, dot and underscore'
                        }
                    }
                },
                email: {
                    validators: {
                        notEmpty: {
                            message: 'The email address is required'
                        },
                        emailAddress: {
                            message: 'The input is not a valid email address'
                        }
                    }
                },
                password: {
                    validators: {
                        notEmpty: {
                            message: 'The password is required'
                        },
                        different: {
                            field: 'username',
                            message: 'The password cannot be the same as username'
                        }
                    }
                },
                gender: {
                    validators: {
                        notEmpty: {
                            message: 'The gender is required'
                        }
                    }
                },
                agree: {
                    validators: {
                        notEmpty: {
                            message: 'You must agree with the terms and conditions'
                        }
                    }
                }
            }
        })
        .on('status.field.fv', function(e, data) {
            var $element = data.element,                // Get the field element
                $icon    = $element.data('fv.icon');    // The feedback icon associates with the field

            switch (data.status) {
                case 'VALID':
                    $icon.html('check');
                    break;
                case 'INVALID':
                    $icon.html('clear');
                    break;
                case 'VALIDATING':
                    $icon.html('graphic_eq');
                    break;
                case 'NOT_VALIDATED':
                default:
                    $icon.html('');
                    break;
            }
        });
});
</script>

Related example