bootstrapValidator: How do you add and remove validators dynamically to an existing input field?

ovm picture ovm · Sep 3, 2014 · Viewed 13.3k times · Source

I have a dynamic form that is bound with knockout.js and validated by bootstrapValidator.

There is one input field that needs to be 'required-validated' dependent on the state of another control.

The input field:

<textarea id="inputReason" name="inputReason" rows="3" 
          class="form-control col-lg-8"
          data-bind="value: Reason" />

The relevant javascript part of the knockout-viewmodel:

self.SelectAbsenceType = function (absenceType) {
    self.SelectedID(absenceType.ID);

    if (self.SelectedAbsenceType().ReasonRequired) {
        $('#formCreate').bootstrapValidator('addField', 'inputReason', {
            validators: {
                notEmpty: {
                    message: 'Please enter a reason'
                }
            }
        });
    } else {
        $('#formCreate').bootstrapValidator('removeField', 'inputReason');
    }
}

The problem I'm facing is that a call to removeField of the bootstrapValidator instance doesnt seem to completely remove all registration infos since there is a javascript exception in the updateStatus method of the bootstrapValidator class that in fact should not be called at all since I have the removed the field before:

var that  = this,
    type  = fields.attr('type'),
    group = this.options.fields[field].group || this.options.group,
    total = ('radio' === type || 'checkbox' === type) ? 1 : fields.length;

The exception: Unable to get value of the property 'group': object is null or undefined

The variable field contains the value 'inputReason'.

So my Question is this (because the documentation of bootstrapValidators removeField is not entirely clear on this: How do I remove the dynamically added validation of the field inputReason completey?

(side note: can someone add the tag boostrapvalidator?)

Answer

ovm picture ovm · Sep 3, 2014

Ok, after some digging it seems that the bootstrapValidator Plugin simply doesnt yet support the removal of validators that are attached to an input field that is NOT to be removed in the same process. Thus the events that are attached to the input field that trigger the validation are not unregistered.

A temporary workaround is to destroy the bootstrapValidator instance, set the data-* attribute of the form to null and reinitialize the plugin. This code replaces the bootstrapValidator.removeField() call:

bootstrapValidator.destroy();

$('#formCreate').data('bootstrapValidator', null);

$('#formCreate').bootstrapValidator();

update

Another even better way to get this done is to use the enable/disable feature of bootstrapValidator:

bootstrapValidator
    .enableFieldValidators
     (
        'inputReason', 
        self.SelectedAbsenceType().ReasonRequired
     );

(thanks to @nghuuphuoc for pointing this out)