programer.tips, another cool thing from @nghuuphuoc!

Playing with Bootstrap Tabs

Examples

Improve it on Github

The following example shows that the plugin works perfectly with Bootstrap Tabs.

By default, the fields in inactive tabs will not be validated because they are not visible. In order to validate them, we need to use the excluded option:

excluded: [':disabled']

Assume that you want to add an icon to tab to indicate the valid or invalid tab. A tab is called valid if all fields inside it are valid. Otherwise, if there is at least one invalid field inside tab, the tab is invalid.

Firstly, we need to prepare the icon placed at the tab title:

<ul class="nav nav-tabs">
    <li class="active"><a href="#info-tab" data-toggle="tab">Tab title <i class="fa"></i></a></li>
    <li><a href="#address-tab" data-toggle="tab">Tab title <i class="fa"></i></a></li>
</ul>

Lastly, add success/error class to icon when the field is valid/invalid by triggering the error.field.bv and success.field.bv events:

$(document).ready(function() {
    $('#accountForm')
        .bootstrapValidator({
            excluded: [':disabled'],
            ...
        })

        // Called when a field is invalid
        .on('error.field.bv', function(e, data) {
            // data.element --> The field element

            var $tabPane = data.element.parents('.tab-pane'),
                tabId    = $tabPane.attr('id');

            $('a[href="#' + tabId + '"][data-toggle="tab"]')
                .parent()
                .find('i')
                .removeClass('fa-check')
                .addClass('fa-times');
        })

        // Called when a field is valid
        .on('success.field.bv', function(e, data) {
            // data.bv      --> The BootstrapValidator instance
            // data.element --> The field element

            var $tabPane = data.element.parents('.tab-pane'),
                tabId    = $tabPane.attr('id'),
                $icon    = $('a[href="#' + tabId + '"][data-toggle="tab"]')
                            .parent()
                            .find('i')
                            .removeClass('fa-check fa-times');

            // Check if the submit button is clicked
            if (data.bv.getSubmitButton()) {
                // Check if all fields in tab are valid
                var isValidTab = data.bv.isValidContainer($tabPane);
                $icon.addClass(isValidTab ? 'fa-check' : 'fa-times');
            }
        });
});
<ul class="nav nav-tabs">
    <li class="active"><a href="#info-tab" data-toggle="tab">Information <i class="fa"></i></a></li>
    <li><a href="#address-tab" data-toggle="tab">Address <i class="fa"></i></a></li>
</ul>

<form id="accountForm" method="post" class="form-horizontal">
    <div class="tab-content">
        <div class="tab-pane active" id="info-tab">
            <div class="form-group">
                <label class="col-sm-3 control-label">Full name</label>
                <div class="col-sm-5">
                    <input type="text" class="form-control" name="fullName" />
                </div>
            </div>
            
            <div class="form-group">
                <label class="col-sm-3 control-label">Company</label>
                <div class="col-sm-5">
                    <input type="text" class="form-control" name="company" />
                </div>
            </div>
            
            <div class="form-group">
                <label class="col-sm-3 control-label">Job title</label>
                <div class="col-sm-5">
                    <input type="text" class="form-control" name="jobTitle" />
                </div>
            </div>
        </div>
        
        <div class="tab-pane" id="address-tab">
            <div class="form-group">
                <label class="col-sm-3 control-label">Address</label>
                <div class="col-sm-5">
                    <input type="text" class="form-control" name="address" />
                </div>
            </div>
            
            <div class="form-group">
                <label class="col-sm-3 control-label">City</label>
                <div class="col-sm-5">
                    <input type="text" class="form-control" name="city" />
                </div>
            </div>
            
            <div class="form-group">
                <label class="col-sm-3 control-label">Country</label>
                <div class="col-sm-5">
                    <select class="form-control" name="country">
                        <option value="">Select a country</option>
                        <option value="FR">France</option>
                        <option value="DE">Germany</option>
                        <option value="IT">Italy</option>
                        <option value="JP">Japan</option>
                        <option value="RU">Russian</option>
                        <option value="US">United State</option>
                        <option value="GB">United Kingdom</option>
                        <option value="other">Other</option>
                    </select>
                </div>
            </div>
        </div>
    </div>
    
    <div style="margin: 15px">
        <div class="form-group">
            <div class="col-sm-5 col-sm-offset-3">
                <button type="submit" class="btn btn-default">Validate</button>
            </div>
        </div>
    </div>
</form>
$(document).ready(function() {
    $('#accountForm')
        .bootstrapValidator({
            // Only disabled elements are excluded
            // The invisible elements belonging to inactive tabs must be validated
            excluded: [':disabled'],
            feedbackIcons: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                fullName: {
                    validators: {
                        notEmpty: {
                            message: 'The full name is required'
                        }
                    }
                },
                company: {
                    validators: {
                        notEmpty: {
                            message: 'The company name is required'
                        }
                    }
                },
                address: {
                    validators: {
                        notEmpty: {
                            message: 'The address is required'
                        }
                    }
                },
                city: {
                    validators: {
                        notEmpty: {
                            message: 'The city is required'
                        }
                    }
                }
            }
        })
        // Called when a field is invalid
        .on('error.field.bv', function(e, data) {
            // data.element --> The field element

            var $tabPane = data.element.parents('.tab-pane'),
                tabId    = $tabPane.attr('id');

            $('a[href="#' + tabId + '"][data-toggle="tab"]')
                .parent()
                .find('i')
                .removeClass('fa-check')
                .addClass('fa-times');
        })
        // Called when a field is valid
        .on('success.field.bv', function(e, data) {
            // data.bv      --> The BootstrapValidator instance
            // data.element --> The field element

            var $tabPane = data.element.parents('.tab-pane'),
                tabId    = $tabPane.attr('id'),
                $icon    = $('a[href="#' + tabId + '"][data-toggle="tab"]')
                            .parent()
                            .find('i')
                            .removeClass('fa-check fa-times');

            // Check if the submit button is clicked
            if (data.bv.getSubmitButton()) {
                // Check if all fields in tab are valid
                var isValidTab = data.bv.isValidContainer($tabPane);
                $icon.addClass(isValidTab ? 'fa-check' : 'fa-times');
            }
        });
});