Interactive table generation JavaScript library with sorting, filtering, editing, formatting, and extensive customization capabilities
—
Comprehensive data validation system with built-in validators, custom validation functions, and flexible validation modes for ensuring data integrity.
Core validation functions for managing table-wide validation state and operations.
/**
* Validate all cells in the table
* @returns Array of invalid CellComponent objects
*/
validate(): CellComponent[];
/**
* Get all currently invalid cells
* @returns Array of invalid CellComponent objects
*/
getInvalidCells(): CellComponent[];
/**
* Clear validation state for specific cell
* @param cell - Cell to clear validation for
*/
clearCellValidation(cell: CellComponent): void;Validation Configuration:
interface ValidationOptions {
validationMode?: "blocking" | "highlighting" | "manual";
}Column-level validation configuration and methods.
// Added to ColumnComponent by Validate module
/**
* Validate all cells in this column
* @returns Array of invalid CellComponent objects
*/
validate(): CellComponent[];Column Validation Configuration:
interface ColumnDefinition {
validator?: string | Function | Array<string | Function>;
// ... other column options
}Cell-level validation state management and validation execution.
// Added to CellComponent by Validate module
/**
* Check if cell value is valid
* @returns True if valid, false if invalid
*/
isValid(): boolean;
/**
* Validate this cell's current value
* @returns True if valid, error message/object if invalid
*/
validate(): boolean | string | any;
/**
* Clear validation state for this cell
*/
clearValidation(): void;Row-level validation for validating all cells within a row.
// Added to RowComponent by Validate module
/**
* Validate all cells in this row
* @returns Array of invalid CellComponent objects
*/
validate(): CellComponent[];Usage Examples:
import { Tabulator } from "tabulator-tables";
// Table with validation configuration
const table = new Tabulator("#table", {
data: [
{ name: "", email: "invalid-email", age: 15, score: 150 },
{ name: "Bob", email: "bob@example.com", age: 25, score: 85 }
],
columns: [
{
title: "Name",
field: "name",
validator: ["required", "minLength", "unique"],
editor: "input"
},
{
title: "Email",
field: "email",
validator: ["required", "regex"],
validatorParams: {
regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
},
editor: "input"
},
{
title: "Age",
field: "age",
validator: ["required", "integer", "min", "max"],
validatorParams: {
min: 18,
max: 120
},
editor: "number"
},
{
title: "Score",
field: "score",
validator: function(cell, value, parameters) {
return value >= 0 && value <= 100 ? true : "Score must be between 0-100";
},
editor: "number"
}
],
validationMode: "highlighting" // highlight invalid cells but allow editing
});
// Validate entire table
const invalidCells = table.validate();
if (invalidCells.length > 0) {
console.log(`Found ${invalidCells.length} invalid cells`);
invalidCells.forEach(cell => {
console.log(`Invalid: ${cell.getField()} = ${cell.getValue()}`);
});
}
// Get currently invalid cells
const currentlyInvalid = table.getInvalidCells();
console.log(`Currently invalid cells: ${currentlyInvalid.length}`);
// Validate specific column
const nameColumn = table.getColumn("name");
const invalidNameCells = nameColumn.validate();
// Validate specific row
const firstRow = table.getRow(0);
const invalidRowCells = firstRow.validate();
// Validate specific cell
const emailCell = table.getRow(0).getCell("email");
const isEmailValid = emailCell.isValid();
const emailValidationResult = emailCell.validate();
// Clear validation for specific cell
emailCell.clearValidation();Tabulator provides comprehensive built-in validators for common validation scenarios.
/**
* Built-in validator functions
*/
interface BuiltinValidators {
/**
* Must be an integer value
*/
integer(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Must be a float value
*/
float(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Must be a numeric value
*/
numeric(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Must be a string value
*/
string(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Must be alphanumeric characters only
*/
alphanumeric(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Must be less than or equal to maximum value
*/
max(cell: CellComponent, value: any, parameters: number): boolean;
/**
* Must be greater than or equal to minimum value
*/
min(cell: CellComponent, value: any, parameters: number): boolean;
/**
* Must start with specified string
*/
starts(cell: CellComponent, value: any, parameters: string): boolean;
/**
* Must end with specified string
*/
ends(cell: CellComponent, value: any, parameters: string): boolean;
/**
* String must be at least minimum length
*/
minLength(cell: CellComponent, value: any, parameters: number): boolean;
/**
* String must be at most maximum length
*/
maxLength(cell: CellComponent, value: any, parameters: number): boolean;
/**
* Value must be in provided list
*/
in(cell: CellComponent, value: any, parameters: any[] | string): boolean;
/**
* Must match provided regular expression
*/
regex(cell: CellComponent, value: any, parameters: string | RegExp): boolean;
/**
* Value must be unique in this column
*/
unique(cell: CellComponent, value: any, parameters?: any): boolean;
/**
* Value is required (not empty, null, or undefined)
*/
required(cell: CellComponent, value: any, parameters?: any): boolean;
}Validator Usage Examples:
// Single validator
{
title: "Age",
field: "age",
validator: "required"
}
// Multiple validators
{
title: "Username",
field: "username",
validator: ["required", "minLength", "alphanumeric", "unique"],
validatorParams: {
minLength: 3
}
}
// Validator with parameters
{
title: "Score",
field: "score",
validator: ["required", "numeric", "min", "max"],
validatorParams: {
min: 0,
max: 100
}
}
// Regex validator
{
title: "Phone",
field: "phone",
validator: "regex",
validatorParams: "^\\+?[1-9]\\d{1,14}$" // E.164 format
}
// In list validator
{
title: "Status",
field: "status",
validator: "in",
validatorParams: ["active", "inactive", "pending"]
}Create custom validation functions for application-specific validation requirements.
/**
* Custom validator function signature
* @param cell - CellComponent being validated
* @param value - Current cell value
* @param parameters - Validation parameters
* @returns True if valid, error message/object if invalid
*/
type ValidatorFunction = (
cell: CellComponent,
value: any,
parameters?: any
) => boolean | string | any;Custom Validator Examples:
// Custom email validator
function emailValidator(cell, value, parameters) {
if (!value) return true; // Allow empty values
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(value) ? true : "Please enter a valid email address";
}
// Age range validator with context
function ageValidator(cell, value, parameters) {
const rowData = cell.getRow().getData();
const minAge = parameters.min || 0;
const maxAge = parameters.max || 120;
if (value < minAge) {
return `Age must be at least ${minAge}`;
}
if (value > maxAge) {
return `Age cannot exceed ${maxAge}`;
}
// Additional business logic
if (rowData.role === "manager" && value < 25) {
return "Managers must be at least 25 years old";
}
return true;
}
// Cross-field validation
function passwordConfirmValidator(cell, value, parameters) {
const rowData = cell.getRow().getData();
const password = rowData.password;
return value === password ? true : "Passwords do not match";
}
// Async validator (returns Promise)
function uniqueUsernameValidator(cell, value, parameters) {
if (!value) return true;
return fetch(`/api/check-username/${encodeURIComponent(value)}`)
.then(response => response.json())
.then(data => data.unique ? true : "Username already exists");
}
// Usage in column definitions
const table = new Tabulator("#table", {
columns: [
{
title: "Email",
field: "email",
validator: emailValidator,
editor: "input"
},
{
title: "Age",
field: "age",
validator: ageValidator,
validatorParams: { min: 18, max: 65 },
editor: "number"
},
{
title: "Confirm Password",
field: "confirmPassword",
validator: passwordConfirmValidator,
editor: "input"
},
{
title: "Username",
field: "username",
validator: [uniqueUsernameValidator, "required", "minLength"],
validatorParams: { minLength: 3 },
editor: "input"
}
]
});Configure how validation errors are handled and displayed.
type ValidationMode = "blocking" | "highlighting" | "manual";Validation Mode Examples:
// Blocking mode - prevent invalid edits
const strictTable = new Tabulator("#strict-table", {
validationMode: "blocking", // Default mode
columns: [
{
title: "Required Field",
field: "required_field",
validator: "required",
editor: "input"
}
]
});
// Highlighting mode - allow edits but highlight invalid cells
const flexibleTable = new Tabulator("#flexible-table", {
validationMode: "highlighting",
columns: [
{
title: "Optional Field",
field: "optional_field",
validator: "numeric",
editor: "input"
}
]
});
// Manual mode - validation only when explicitly called
const manualTable = new Tabulator("#manual-table", {
validationMode: "manual",
columns: [
{
title: "Manual Validation",
field: "manual_field",
validator: "required",
editor: "input"
}
]
});
// Manually trigger validation
document.getElementById("validate-btn").addEventListener("click", () => {
const invalid = manualTable.validate();
if (invalid.length > 0) {
alert(`Found ${invalid.length} validation errors`);
} else {
alert("All data is valid!");
}
});Validation-related events for responding to validation state changes.
// Validation events
table.on("validationFailed", function(cell, value, validators) {
console.log("Validation failed:", cell.getField(), value, validators);
});
table.on("validationPassed", function(cell, value) {
console.log("Validation passed:", cell.getField(), value);
});interface ValidatorParams {
[key: string]: any;
min?: number;
max?: number;
minLength?: number;
maxLength?: number;
regex?: string | RegExp;
}
interface ValidationResult {
valid: boolean;
error?: string | any;
}Install with Tessl CLI
npx tessl i tessl/npm-tabulator-tables