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: "john@example.com",
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: "user@example.com", 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: "user@example.com",
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: "john@example.com",
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