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

Conditional validation

Examples

There is a common case that a field validator rules depend on additional conditions. For example, when you stop using a software or an online service, you might be asked for the reason.

You can pick one from the given list, or choose a kind of "Other" checkbox. In the case that checkbox is selected, you have to indicate the specific reason. The reason is only required if you don't choose given one.

This example suggests two approaches that you can use for dealing with these kind of conditional validation.

Using callback validator

The first solution is to use the callback validator.

The callback function simply ignores validation logic and returns true if the conditions don't happen. Otherwise, perform your specific logic to check the field validity.

One more thing, even when the field validation is ignored, the plugin still adds the success class to the container as well as shows the tick icon.

In this case, you can trigger the event to mark the field as ignored. This trick is described in the Hiding success class example.

The ignoring validation example introduces a simpler way to handle this
<form id="surveyForm" method="post">
    <div class="form-group">
        <label class="control-label">How do you know about us?</label>
        <div class="radio">
            <label><input type="radio" name="channel" value="google" /> Google</label>
        </div>
        <div class="radio">
            <label><input type="radio" name="channel" value="github" /> Github</label>
        </div>
        <div class="radio">
            <label><input type="radio" name="channel" value="twitter" /> Twitter</label>
        </div>
        <div class="radio">
            <label><input type="radio" name="channel" value="facebook" /> Facebook</label>
        </div>
        <div class="radio">
            <label><input type="radio" name="channel" value="developers" /> Developers</label>
        </div>
        <div class="radio">
            <label><input type="radio" name="channel" value="other" /> Other</label>
        </div>
    </div>

    <div class="form-group">
        <label class="control-label">Please specify it:</label>
        <input type="text" class="form-control" name="otherChannel" />
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-default">Submit</button>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#surveyForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                channel: {
                    validators: {
                        notEmpty: {
                            message: 'Please select a channel'
                        }
                    }
                },
                otherChannel: {
                    validators: {
                        callback: {
                            message: 'Please specific the channel',
                            callback: function(value, validator, $field) {
                                var channel = $('#surveyForm').find('[name="channel"]:checked').val();
                                return (channel !== 'other') ? true : (value !== '');
                            }
                        }
                    }
                }
            }
        })
        .on('change', '[name="channel"]', function(e) {
            $('#surveyForm').formValidation('revalidateField', 'otherChannel');
        })
        .on('success.field.fv', function(e, data) {
            if (data.field === 'otherChannel') {
                var channel = $('#surveyForm').find('[name="channel"]:checked').val();
                // User choose given channel
                if (channel !== 'other') {
                    // Remove the success class from the container
                    data.element.closest('.form-group').removeClass('has-success');

                    // Hide the tick icon
                    data.element.data('fv.icon').hide();
                }
            }
        });
});
</script>

Enabling validators when meeting conditions

The second solution uses the enabled option and enableFieldValidators() method.

Initially, the field validators are disabled by setting enabled: false:

$('#profileForm').formValidation({
    fields: {
        driverLicense: {
            // Disable validators
            enabled: false,
            validators: {
                ...
            }
        }
    }
});

Later, when conditions happen, these validators can be turned on (off) by calling the enableFieldValidators() method:

$('#profileForm').formValidation('enableFieldValidators', 'driverLicense', true/false);

// Or the same way
$('#profileForm').data('formValidation').enableFieldValidators('driverLicense', true/false);
<form id="profileForm" method="post">
    <p>Please provide one of these information:</p>

    <div class="form-group">
        <label class="control-label">Social Security Number</label>
        <input type="text" class="form-control" name="ssn" />
    </div>

    <div class="form-group text-center">&mdash; Or &mdash;</div>

    <div class="form-group">
        <label class="control-label">Driver's License Number</label>
        <input type="text" class="form-control" name="driverLicense" />
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-default">Submit</button>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#profileForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                ssn: {
                    validators: {
                        notEmpty: {
                            message: 'Please provide the Social Security number'
                        },
                        regexp: {
                            regexp: /^(?!(000|666|9))\d{3}(?!00)\d{2}(?!0000)\d{4}$/,
                            message: 'The format of your SSN is invalid. It should be XXXXXXXXX with no dashes'
                        }
                    }
                },
                driverLicense: {
                    // Disable validators
                    enabled: false,
                    validators: {
                        notEmpty: {
                            message: 'Or the Drivers License number'
                        },
                        stringLength: {
                            min: 8,
                            max: 20,
                            message: 'The Drivers License number must be more than 8 and less than 20 characters long'
                        }
                    }
                }
            }
        })
        .on('keyup', '[name="ssn"], [name="driverLicense"]', function(e) {
            var driverLicense = $('#profileForm').find('[name="driverLicense"]').val(),
                ssn           = $('#profileForm').find('[name="ssn"]').val(),
                fv            = $('#profileForm').data('formValidation');

            switch ($(this).attr('name')) {
                // User is focusing the ssn field
                case 'ssn':
                    fv.enableFieldValidators('driverLicense', ssn === '').revalidateField('driverLicense');

                    if (ssn && fv.getOptions('ssn', null, 'enabled') === false) {
                        fv.enableFieldValidators('ssn', true).revalidateField('ssn');
                    } else if (ssn === '' && driverLicense !== '') {
                        fv.enableFieldValidators('ssn', false).revalidateField('ssn');
                    }
                    break;

                // User is focusing the drivers license field
                case 'driverLicense':
                    if (driverLicense === '') {
                        fv.enableFieldValidators('ssn', true).revalidateField('ssn');
                    } else if (ssn === '') {
                        fv.enableFieldValidators('ssn', false).revalidateField('ssn');
                    }

                    if (driverLicense && ssn === '' && fv.getOptions('driverLicense', null, 'enabled') === false) {
                        fv.enableFieldValidators('driverLicense', true).revalidateField('driverLicense');
                    }
                    break;

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

Related examples