Documentation v4.0.0

Overview

Validation is a wrapper around FormValidation that provides form validation with Metronic-styled error messages, submit button indicators, and field-level validation controls. The parent element of each validated field must have the fv-row CSS class.

Import

import {components} from 'metronic-extension';
const {Validation} = components;

Constructor

new Validation(form, fields, enableSubmitTrigger?, enableSequence?, shouldFocus?)
Parameter Type Default Description
form string | HTMLFormElement - CSS selector string or HTMLFormElement.
fields FieldsOptions - Field validation rules.
enableSubmitTrigger boolean true If true, validation runs when the submit button is pressed.
enableSequence boolean true If true, stops validation after the first failure.
shouldFocus boolean true If true, focuses the first invalid field.

Properties

Property Type Description
form HTMLFormElement The form element.
submit HTMLButtonElement | null The submit button element (auto-detected from form).
fv FormValidation.core.Core The underlying FormValidation instance.

Methods

Method Return Description
validate() Promise<boolean> Validates all fields. Returns true if valid.
validateField(field) Promise<boolean> Validates a single field by name attribute.
onValid(handler) Validation Callback when the entire form is valid.
onInvalid(handler) Validation Callback when the form is invalid.
onFieldValid(handler) Validation Callback when a field becomes valid. Receives the field name.
onFieldInvalid(handler) Validation Callback when a field becomes invalid. Receives the field name.
onIndicator() Validation Enables the submit button loading indicator during validation.
offIndicator() Validation Disables the submit button loading indicator.
setError(field, validator) Validation Manually sets a field as invalid for a given validator.
enableValidator(field, validator?) Validation Enables a validator for a field.
disableValidator(field, validator?) Validation Disables a validator for a field.
resetField(field, reset?) Validation Resets a field's validation state. Pass true to clear value.
resetForm(reset?) Validation Resets all fields' validation state.
addField(field, validators) Validation Dynamically adds a field with validators.
removeField(field) Validation Removes a field from validation.
removeAllField() void Removes all fields from validation.
getFields() FieldsOptions Returns the current field validation options.
addRule(validator, func) Validation Registers a custom validation rule.
destroy() void Destroys the validation instance.

Basic Example

A form with required, length, and email validators. Press Submit to trigger validation. The submit button shows a loading indicator on success.
<form id="myForm">
  <div class="fv-row mb-7">
    <label class="fs-6 fw-semibold form-label mb-2 required">Name</label>
    <input type="text" name="name" class="form-control form-control-solid">
  </div>
  <div class="fv-row mb-7">
    <label class="fs-6 fw-semibold form-label mb-2 required">Email</label>
    <input type="text" name="email" class="form-control form-control-solid">
  </div>
  <div class="fv-row mb-7">
    <label class="fs-6 fw-semibold form-label mb-2 required">Password</label>
    <input type="password" name="password" class="form-control form-control-solid">
  </div>
  <button type="submit" class="btn btn-primary">
    <span class="indicator-label">Submit</span>
    <span class="indicator-progress">Please wait...
      <span class="spinner-border spinner-border-sm align-middle ms-2"></span>
    </span>
  </button>
</form>
import {components} from 'metronic-extension';
const {Validation} = components;

const validation = new Validation('#myForm', {
  name: {
    validators: {
      notEmpty: {message: 'Name is required'},
      stringLength: {min: 2, max: 50, message: 'Name must be 2-50 characters'},
    },
  },
  email: {
    validators: {
      notEmpty: {message: 'Email is required'},
      emailAddress: {message: 'Invalid email address'},
    },
  },
  password: {
    validators: {
      notEmpty: {message: 'Password is required'},
      stringLength: {min: 8, message: 'Password must be at least 8 characters'},
    },
  },
});

validation.onValid(async () => {
  validation.onIndicator();
  // Simulate async save
  await new Promise(r => setTimeout(r, 1500));
  validation.offIndicator();
  alert('Form is valid!');
});

validation.onInvalid(() => {
  console.log('Form has errors');
});

Custom Validator Example

Use addRule() to register a custom validation function, then reference it by name in the field validators.
<form id="myForm">
  <div class="fv-row mb-7">
    <label class="fs-6 fw-semibold form-label mb-2 required">Age</label>
    <input type="text" name="age" class="form-control form-control-solid">
  </div>
  <div class="fv-row mb-7">
    <label class="fs-6 fw-semibold form-label mb-2 required">Invitation Code</label>
    <input type="text" name="code" class="form-control form-control-solid">
  </div>
  <button type="submit" class="btn btn-primary">
    <span class="indicator-label">Submit</span>
    <span class="indicator-progress">Please wait...
      <span class="spinner-border spinner-border-sm align-middle ms-2"></span>
    </span>
  </button>
</form>
import {components} from 'metronic-extension';
const {Validation} = components;

const validation = new Validation('#myForm', {
  age: {
    validators: {
      notEmpty: {message: 'Age is required'},
      isAdult: {message: 'Age must be between 18 and 99'},
    },
  },
  code: {
    validators: {
      notEmpty: {message: 'Invitation code is required'},
      hasPrefix: {message: 'Code must start with "INV-"', prefix: 'INV-'},
    },
  },
});

// Custom rule: check if value is a number between 18-99
validation.addRule('isAdult', function() {
  return {
    validate: function(input) {
      var val = parseInt(input.value, 10);
      return {valid: !isNaN(val) && val >= 18 && val <= 99};
    },
  };
});

// Custom rule with options: check if value starts with a given prefix
validation.addRule('hasPrefix', function() {
  return {
    validate: function(input) {
      var prefix = input.options.prefix || '';
      return {valid: input.value.indexOf(prefix) === 0};
    },
  };
});