API Reference
Core Classes
Veli / FormValidator
Main validation class for forms.
const validator = new Veli(formElement, language?);
Parameters:
formElement(HTMLFormElement) — The form to validatelanguage(string, optional) — 'en' or 'fr' (default: 'en')
Methods:
validate()→{ status: boolean; values: Record<string, any> }- Validates the entire form and returns the validation resultvalidateEach()→ 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:
trueif all fields pass validation,falseotherwise - 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
checkedValueorunCheckedValuestring - Grouped checkboxes: value is an array of selected
checkedValuestrings
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 behaviorstrictMode(boolean) — Elevate MEDIUM threats to HIGHstopOnFirstThreat(boolean) — Exit on first threat for performanceincludeValueInResponse(boolean) — Include field values in responsecustomPatterns(object) — Add custom threat patterns
Methods:
scanAll(fields)→ Scan all threat typesscan(fields, type)→ Scan specific threat typescanAsync(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 fieldsinitialData(object, optional) — Initial valuesoptions(object, optional) — Configuration options
Returns: A Watcher with methods:
isDirty()→ booleanisValid()→ booleangetCurrentValues()→ objectreset()→ voidon(event, callback)→ unsubscribe functionoff(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 validatevalue(string) — The value to validaterules(Record<string, string>) — Validation rules as key-value pairsconstext(string, optional) — Field context/type hint
-
config(object) — Configuration optionslang("en" | "fr", optional) — Error message language (default: "en")scanner(object, optional) — Security scanning configurationscanners(ScannerType) — Type of security scan to performconfig(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
- Always define
namein rules — Every field needs a unique name for tracking - Include error spans — Keep
<span class="veli-error"></span>in HTML - Set language globally — Define
data-veli-langon the form element - Use consistent design — Choose one design system per form
- Validate on submit — Don't rely only on real-time validation
- Test accessibility — Verify with screen readers, especially for IFTA design
- Handle async responses — Wrap API calls after validation succeeds