Skip to main content

API Reference

Core Classes​

Veli / FormValidator​

Main validation class for forms.

const validator = new Veli(formElement, language?);

Parameters:

  • formElement (HTMLFormElement) — The form to validate
  • language (string, optional) — 'en' or 'fr' (default: 'en')

Methods:

  • validate() → { status: boolean; values: Record<string, any> } - Validates the entire form and returns the validation result
  • validateEach() → validates each field on change

Validation Response Object:

When validate() is called, it returns an object with the following structure:

interface ValidationResponse {
status: boolean; // true if all validations pass, false if any field fails
values: Record<string, string | string[]>; // Object containing all form field values
}

Response Values:

  • status: true if all fields pass validation, false otherwise
  • values: Object with field names as keys and their values:
    • Text/email/password/tel/number fields: value is a string
    • Checkbox fields: value is the checkedValue or unCheckedValue string
    • Grouped checkboxes: value is an array of selected checkedValue strings

Example Response:

// Single fields
{
status: true,
values: {
fullname: "John Doe",
email: "[email protected]",
phone: "237679587645",
age: "25",
terms: "true", // from checkbox
newsletter: "subscribed" // custom checkbox value
}
}

// With grouped checkboxes
{
status: true,
values: {
fullname: "Jane Smith",
interests: ["sports", "music", "art"], // grouped checkboxes - array of selected values
terms: "true"
}
}

// Failed validation
{
status: false,
values: {} // empty on failure
}

Validation Events:

Veli dispatches a custom event onCompleteValidation on the form element when validation completes. You can listen to this event to handle the response asynchronously.

const form = document.getElementById('myForm');

form.addEventListener('onCompleteValidation', () => {
// Access the global validationResponse object
// The key is the form's ID
const result = validationResponse.myForm;
console.log(result);
});

Form Attributes:

data-veli-response-exclude​

Exclude specific fields from the response object without excluding them from validation. Use this to prevent sensitive fields (like password confirmation or internal flags) from appearing in the final response.

Format: JSON array of field names as strings

Example:

<!-- Exclude password confirmation from response -->
<form
id="myForm"
data-veli-response-exclude='["confirmPassword", "newsletter"]'
>
<div class="veli-field-wrapper">
<label>Password</label>
<input
type="password"
name="password"
data-veli-rules='{"type":"password","name":"password","minLen":"8"}'
/>
<span class="veli-error"></span>
</div>

<div class="veli-field-wrapper">
<label>Confirm Password</label>
<input
type="password"
name="confirmPassword"
data-veli-rules='{"type":"password","name":"confirmPassword","confirmWith":"password"}'
/>
<span class="veli-error"></span>
</div>
</form>

<script>
const form = document.getElementById('myForm');
form.addEventListener('onCompleteValidation', () => {
const result = validationResponse.myForm;
console.log(result);
});
</script>

Use Cases for data-veli-response-exclude:

  • Password confirmation fields - validate but don't send to server
  • Internal tracking fields - validate but exclude from response
  • Temporary form flags - validate checkbox conditions but exclude from submission
  • Multi-step form fields - validate one step while excluding others

JavaScript Usage:

const form = document.getElementById("contactForm");
const validator = new Veli(form, "en");

form.addEventListener("submit", (e) => {
e.preventDefault();

const result = validator.validate();

if (result.status) {
// All validation passed
console.log("Form data:", result.values);

// Send to server
fetch("/api/submit", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(result.values),
});
} else {
// Validation failed - errors displayed automatically
console.log("Please fix the errors above");
}
});

Scanner​

Advanced security scanning class for threat detection.

const scanner = new Scanner(options?);

Parameters:

  • options (ScannerConfig, optional) — Configuration for scanning behavior
    • strictMode (boolean) — Elevate MEDIUM threats to HIGH
    • stopOnFirstThreat (boolean) — Exit on first threat for performance
    • includeValueInResponse (boolean) — Include field values in response
    • customPatterns (object) — Add custom threat patterns

Methods:

  • scanAll(fields) → Scan all threat types
  • scan(fields, type) → Scan specific threat type
  • scanAsync(fields) → Non-blocking scan for large datasets

Threat Types:

  • 'sqlInjection' — SQL injection detection
  • 'noSqlInjection' — NoSQL/MongoDB injection detection
  • 'xss' — Cross-Site Scripting detection
  • 'pathTraversal' — Directory traversal detection
  • 'tokenLeakage' — Sensitive token/credential detection

Example:

const scanner = new Scanner({strictMode: true});
const result = scanner.scanAll([
{name: "email", value: "[email protected]", type: "email"},
{
name: "comment",
value: "<script>alert(1)</script>",
type: "html",
allowedTags: ["p"],
},
]);

if (!result.passed) {
console.log("Security threats detected");
result.result.forEach((field) => {
field.threats.forEach((threat) => {
console.log(`${threat.type}: ${threat.recommendation}`);
});
});
}

👉 Full Security Scanner Documentation

Utility Functions​

createWatch(source, initialData, options)​

Create a Watcher instance for reactive form state.

const watcher = createWatch(source, initialData, options);

Parameters:

  • source (string | HTMLFormElement | NodeList | Element[]) — Form ID, Form Element, or list of fields
  • initialData (object, optional) — Initial values
  • options (object, optional) — Configuration options

Returns: A Watcher with methods:

  • isDirty() → boolean
  • isValid() → boolean
  • getCurrentValues() → object
  • reset() → void
  • on(event, callback) → unsubscribe function
  • off(event, callback) → void

validate(items, config)​

Standalone validation function for validating arrays of values against rules without form initialization. Supports all field types with optional security scanning.

const result = validate(items, config);

Parameters:

  • items (ValidationItem[]) — Array of fields to validate

    • value (string) — The value to validate
    • rules (Record<string, string>) — Validation rules as key-value pairs
    • constext (string, optional) — Field context/type hint
  • config (object) — Configuration options

    • lang ("en" | "fr", optional) — Error message language (default: "en")
    • scanner (object, optional) — Security scanning configuration
      • scanners (ScannerType) — Type of security scan to perform
      • config (ScannerConfig, optional) — Scanner configuration options

Returns: ValidationResult

interface ValidationResult {
status: boolean; // true if all validations pass
errors: ValidationError[]; // array of validation errors
scannerRes?: ScanResult | null; // security scan results (if scanner enabled)
}

interface ValidationError {
name: string; // field name
reason: string; // error reason/message
}

Basic Example:

const result = validate(
[
{
value: "[email protected]",
rules: {type: "email", name: "email", provider: "any"},
},
{
value: "password123",
rules: {
type: "password",
name: "password",
minLen: "8@@Password too short",
},
},
],
{lang: "en"}
);

if (result.status) {
console.log("All validations passed!");
} else {
result.errors.forEach((error) => {
console.log(`${error.name}: ${error.reason}`);
});
}

With Security Scanning:

const result = validate(
[
{
value: "[email protected]",
rules: {type: "email", name: "email", provider: "any"},
constext: "email",
},
{
value: userComment,
rules: {type: "text", name: "comment"},
constext: "html",
},
],
{
lang: "en",
scanner: {
scanners: "xss", // Check for XSS threats
config: {
strictMode: true,
stopOnFirstThreat: false,
},
},
}
);

// Check security results
if (result.scannerRes && !result.scannerRes.passed) {
console.log(`Security Score: ${result.scannerRes.securityScore}`);
result.scannerRes.result.forEach((field) => {
field.threats.forEach((threat) => {
console.log(`Threat: ${threat.type} - ${threat.recommendation}`);
});
});
}

Field Type Validations:

Each field type supports different rules:

  • text — minChar, maxChar, minWord, maxWord, case, specialChar, pattern, required
  • password — minLen, maxLen, minNumCount, minLowercaseAlphabetCount, minUppercaseAlphabetCount, minSpecialCharCount, pattern, required
  • email — provider, pattern, required
  • tel — pattern, required
  • number — min, max, range, pattern, required
  • checkbox — required

Custom Error Messages:

Append custom error messages to rule values using @@:

const rules = {
type: "text",
name: "username",
minChar: "3@@Username must be at least 3 characters",
maxChar: "20@@Username cannot exceed 20 characters",
pattern:
"/^[a-zA-Z0-9_]*$/@@Username can only contain letters, numbers, and underscores",
};

Language Support:

// English error messages (default)
const resultEn = validate(items, {lang: "en"});

// French error messages
const resultFr = validate(items, {lang: "fr"});

Returns: ValidationResult with status, errors array, and optional security scan results


VeliConfig(options)​

Configure global theme colors.

VeliConfig({
colors: {
error: "#ff0000",
success: "#00ff00",
warning: "#ffff00",
info: "#0000ff",
},
});

Event Emitters (Watcher)​

watcher.on("dirty", () => {
/* form has unsaved changes */
});
watcher.on("clean", () => {
/* form is pristine */
});

// Unsubscribe
const unsubscribe = watcher.on("dirty", callback);
unsubscribe(); // removes listener

HTML Data Attributes​

data-veli-rules​

JSON object defining validation rules for a field.

<input data-veli-rules="{...validation rules...}" />

data-veli-design​

Set the design system for the form.

<form data-veli-design="classic">
<!-- or "floating-label" or "ifta-label" -->
</form>

data-veli-lang​

Set language for error messages.

<form data-veli-lang="en"><!-- or "fr" --></form>

Types (TypeScript)​

For full type definitions, see dist/veli.d.ts.

interface ValidationResult {
status: boolean;
values: Record<string, string | string[]>;
errors?: ValidationError[];
}

interface ValidationError {
name: string;
reason: string;
}

interface VeliColorConfig {
error?: string;
success?: string;
warning?: string;
info?: string;
}

interface VeliConfigType {
colors?: VeliColorConfig;
}

Import Examples​

CommonJS​

const {Veli, createWatch, validate, VeliConfig} = require("@gd3v/veli");

ES Modules​

import {Veli, createWatch, validate, VeliConfig} from "@gd3v/veli";

Browser (UMD)​

<script src="https://cdn.jsdelivr.net/npm/@gd3v/veli@latest/dist/veli.js"></script>
<script>
const {Veli, validate} = window.Veli;
</script>

Common Usage Patterns​

Validate on Submit​

const form = document.getElementById("myForm");
const validator = new Veli(form, "en");

form.addEventListener("submit", (e) => {
e.preventDefault();
const result = validator.validate();

if (result.status) {
// Send data to server
fetch("/api/submit", {
method: "POST",
body: JSON.stringify(result.values),
});
}
});

Validate Specific Field​

const fields = [
{
value: document.querySelector('[name="email"]').value,
rules: {type: "email", name: "email", provider: "gmail"},
},
];

const result = validate(fields);
console.log(result);

Error Messages​

Error messages are automatically localized based on the language parameter:

  • 'en' — English error messages
  • 'fr' — French error messages

Common error reasons:

  • "Field is required"
  • "Minimum character length: X"
  • "Maximum character length: X"
  • "Invalid email format"
  • "Password does not meet security requirements"
  • "Passwords do not match"
  • "Invalid phone number"
  • "Only numeric values allowed"

Advanced Configuration​

Color Theme​

import {VeliConfig} from "@gd3v/veli";

VeliConfig({
colors: {
error: "#dc3545",
success: "#28a745",
warning: "#ffc107",
info: "#17a2b8",
},
});

Custom Patterns​

const field = {
type: "text",
name: "username",
minChar: 3,
maxChar: 20,
pattern: "^[a-zA-Z0-9_]*$", // Only alphanumeric and underscore
};

Password Confirmation​

// Password field
{
type: 'password',
name: 'password',
securityLevel: 's4'
}

// Confirm password field (use confirmWith property)
{
type: 'password',
name: 'confirmPassword',
confirmWith: 'password'
}

Debugging​

Enable Console Logging​

const form = document.getElementById("myForm");
const validator = new Veli(form, "en");

const result = validator.validate();
console.log("Validation Result:", result);
console.log("Is Valid:", result.status);
console.log("Form Values:", result.values);
console.log("Errors:", result.errors);

Check Field State​

// Check if specific field is valid
const emailInput = document.querySelector('[name="email"]');
const result = validate([
{
value: emailInput.value,
rules: emailInput.dataset.veliRules
? JSON.parse(emailInput.dataset.veliRules)
: {},
},
]);

console.log("Email is valid:", result.status);

Best Practices​

  1. Always define name in rules — Every field needs a unique name for tracking
  2. Include error spans — Keep <span class="veli-error"></span> in HTML
  3. Set language globally — Define data-veli-lang on the form element
  4. Use consistent design — Choose one design system per form
  5. Validate on submit — Don't rely only on real-time validation
  6. Test accessibility — Verify with screen readers, especially for IFTA design
  7. Handle async responses — Wrap API calls after validation succeeds