Search code examples
javascriptformvalidation.io

Add fields dynamically with alias


I am trying to add dynamically some fields to a form validated with fomavalidation.io v1.10.0 with validators using alias.

Here is the piece of code:

const $sp_param_delay_min = $('#sp_param_delay_min');
const param_delay_max = $('#sp_param_delay_max');

_fv.addField($sp_param_delay_min[0].name, {
  validators: {
    callback: {
      message: 'You must fill at least one of the two delay fields',
      callback: (input) => {
        let is_valid =
          input.value !== '' || $sp_param_delay_max.val() !== '';

        _fv.updateFieldStatus(
          $sp_param_delay_max[0].name,
          is_valid ? 'Valid' : 'Invalid',
          'callback'
        );
        return is_valid;
      }
    },
    lessThanMax: {
      alias: 'callback',
      message: 'The delay min must be smaller than the delay max',
      callback: (input) => {
        let is_valid =
          input.value === '' ||
          $sp_param_delay_max.val() === '' ||
          parseInt(input.value) < parseInt($sp_param_delay_max.val());

        return is_valid;
      }
    },
    integer: {
      message: 'The delay min must be an integer'
    },
    greaterThan: {
      min: 0,
      message: 'The delay min must be greater than 0',
      inclusive: false
    }
  }
});

_fv.addField($sp_param_delay_max[0].name, {
  validators: {
    callback: {
      message: 'You must fill at least one of the two delay fields',
      callback: (input) => {
        let is_valid =
          input.value !== '' || $sp_param_delay_min.val() !== '';

        _fv.updateFieldStatus(
          $sp_param_delay_min[0].name,
          is_valid ? 'Valid' : 'Invalid',
          'callback'
        );
        return is_valid;
      }
    },
    moreThanMin: {
      alias: 'callback',
      message: 'The delay max must be greater than the delay min',
      callback: (input) => {
        let is_valid =
          input.value === '' ||
          $sp_param_delay_min.val() === '' ||
          parseInt(input.value) > parseInt($sp_param_delay_min.val());

        return is_valid;
      }
    },
    integer: {
      message: 'The delay max must be an integer'
    },
    greaterThan: {
      min: 0,
      message: 'The delay max must be greater than 0',
      inclusive: false
    }
  }
});

The Alias plugin is registered when the _fv object is created:

const _fv = $modalForm.formValidation(
  {
    fields: {
      ...
    },
    plugins: {
      trigger: new FormValidation.plugins.Trigger({
        delay: {
          step_name: 0.5
        }
      }),
      bootstrap3: new FormValidation.plugins.Bootstrap3(),
      icon: new FormValidation.plugins.Icon({
        valid: 'fas fa-check',
        invalid: 'fas fa-times',
        validating: 'fas fa-refresh'
      }),
      sequence: new FormValidation.plugins.Sequence({
        enabled: true,
      }),
      alias: new FormValidation.plugins.Alias()
    }
  }
).data('formValidation');

All the validators are working well except for the lessThanMax and moreThanMin ones...


Solution

  • I have finally found a solution.

    I had basically to use the API function registerPlugin().

    So If I reedit the code above:

    const $sp_param_delay_min = $('#sp_param_delay_min');
    const param_delay_max = $('#sp_param_delay_max');
    
    _fv.addField($sp_param_delay_min[0].name, {
      validators: {
        callback: {
          message: 'You must fill at least one of the two delay fields',
          callback: (input) => {
            let is_valid =
              input.value !== '' || $sp_param_delay_max.val() !== '';
    
            _fv.updateFieldStatus(
              $sp_param_delay_max[0].name,
              is_valid ? 'Valid' : 'Invalid',
              'callback'
            );
            return is_valid;
          }
        },
        lessThanMax: {
          message: 'The delay min must be smaller than the delay max',
          callback: (input) => {
            let is_valid =
              input.value === '' ||
              $sp_param_delay_max.val() === '' ||
              parseInt(input.value) < parseInt($sp_param_delay_max.val());
    
            return is_valid;
          }
        },
        integer: {
          message: 'The delay min must be an integer'
        },
        greaterThan: {
          min: 0,
          message: 'The delay min must be greater than 0',
          inclusive: false
        }
      }
    });
    
    _fv.addField($sp_param_delay_max[0].name, {
      validators: {
        callback: {
          message: 'You must fill at least one of the two delay fields',
          callback: (input) => {
            let is_valid =
              input.value !== '' || $sp_param_delay_min.val() !== '';
    
            _fv.updateFieldStatus(
              $sp_param_delay_min[0].name,
              is_valid ? 'Valid' : 'Invalid',
              'callback'
            );
            return true;
          }
        },
        moreThanMin: {
          message: 'The delay max must be greater than the delay min',
          callback: (input) => {
            let is_valid =
              input.value === '' ||
              $sp_param_delay_min.val() === '' ||
              parseInt(input.value) > parseInt($sp_param_delay_min.val());
    
            return is_valid;
          }
        },
        integer: {
          message: 'The delay max must be an integer'
        },
        greaterThan: {
          min: 0,
          message: 'The delay max must be greater than 0',
          inclusive: false
        }
      }
    });
    
    _fv.registerPlugin(
      'Alias',
      new FormValidation.plugins.Alias({
        moreThanMin: 'callback',
        lessThanMax: 'callback'
      })
    );
    

    And remove the Alias plugin initialisation in the _fv instance:

    const _fv = $modalForm.formValidation(
      {
        fields: {
          ...
        },
        plugins: {
          trigger: new FormValidation.plugins.Trigger({
            delay: {
              step_name: 0.5
            }
          }),
          bootstrap3: new FormValidation.plugins.Bootstrap3(),
          icon: new FormValidation.plugins.Icon({
            valid: 'fas fa-check',
            invalid: 'fas fa-times',
            validating: 'fas fa-refresh'
          }),
          sequence: new FormValidation.plugins.Sequence({
            enabled: true,
          })
        }
      }
    ).data('formValidation');
    

    It is now working :-)