or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cell-editing.mdclipboard.mdcolumn-management.mddata-management.mddata-sorting.mddata-trees.mdevent-system.mdfiltering-search.mdhistory-undo.mdimport-export.mdindex.mdpagination.mdrange-selection.mdrow-grouping.mdtable-construction.mdvalidation.md

validation.mddocs/

0

# Data Validation

1

2

Comprehensive data validation system with built-in validators, custom validation functions, and flexible validation modes for ensuring data integrity.

3

4

## Capabilities

5

6

### Table Validation Methods

7

8

Core validation functions for managing table-wide validation state and operations.

9

10

```javascript { .api }

11

/**

12

* Validate all cells in the table

13

* @returns Array of invalid CellComponent objects

14

*/

15

validate(): CellComponent[];

16

17

/**

18

* Get all currently invalid cells

19

* @returns Array of invalid CellComponent objects

20

*/

21

getInvalidCells(): CellComponent[];

22

23

/**

24

* Clear validation state for specific cell

25

* @param cell - Cell to clear validation for

26

*/

27

clearCellValidation(cell: CellComponent): void;

28

```

29

30

**Validation Configuration:**

31

32

```javascript { .api }

33

interface ValidationOptions {

34

validationMode?: "blocking" | "highlighting" | "manual";

35

}

36

```

37

38

### Column Validation

39

40

Column-level validation configuration and methods.

41

42

```javascript { .api }

43

// Added to ColumnComponent by Validate module

44

/**

45

* Validate all cells in this column

46

* @returns Array of invalid CellComponent objects

47

*/

48

validate(): CellComponent[];

49

```

50

51

**Column Validation Configuration:**

52

53

```javascript { .api }

54

interface ColumnDefinition {

55

validator?: string | Function | Array<string | Function>;

56

// ... other column options

57

}

58

```

59

60

### Cell Validation

61

62

Cell-level validation state management and validation execution.

63

64

```javascript { .api }

65

// Added to CellComponent by Validate module

66

/**

67

* Check if cell value is valid

68

* @returns True if valid, false if invalid

69

*/

70

isValid(): boolean;

71

72

/**

73

* Validate this cell's current value

74

* @returns True if valid, error message/object if invalid

75

*/

76

validate(): boolean | string | any;

77

78

/**

79

* Clear validation state for this cell

80

*/

81

clearValidation(): void;

82

```

83

84

### Row Validation

85

86

Row-level validation for validating all cells within a row.

87

88

```javascript { .api }

89

// Added to RowComponent by Validate module

90

/**

91

* Validate all cells in this row

92

* @returns Array of invalid CellComponent objects

93

*/

94

validate(): CellComponent[];

95

```

96

97

**Usage Examples:**

98

99

```javascript

100

import { Tabulator } from "tabulator-tables";

101

102

// Table with validation configuration

103

const table = new Tabulator("#table", {

104

data: [

105

{ name: "", email: "invalid-email", age: 15, score: 150 },

106

{ name: "Bob", email: "bob@example.com", age: 25, score: 85 }

107

],

108

columns: [

109

{

110

title: "Name",

111

field: "name",

112

validator: ["required", "minLength", "unique"],

113

editor: "input"

114

},

115

{

116

title: "Email",

117

field: "email",

118

validator: ["required", "regex"],

119

validatorParams: {

120

regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/

121

},

122

editor: "input"

123

},

124

{

125

title: "Age",

126

field: "age",

127

validator: ["required", "integer", "min", "max"],

128

validatorParams: {

129

min: 18,

130

max: 120

131

},

132

editor: "number"

133

},

134

{

135

title: "Score",

136

field: "score",

137

validator: function(cell, value, parameters) {

138

return value >= 0 && value <= 100 ? true : "Score must be between 0-100";

139

},

140

editor: "number"

141

}

142

],

143

validationMode: "highlighting" // highlight invalid cells but allow editing

144

});

145

146

// Validate entire table

147

const invalidCells = table.validate();

148

if (invalidCells.length > 0) {

149

console.log(`Found ${invalidCells.length} invalid cells`);

150

invalidCells.forEach(cell => {

151

console.log(`Invalid: ${cell.getField()} = ${cell.getValue()}`);

152

});

153

}

154

155

// Get currently invalid cells

156

const currentlyInvalid = table.getInvalidCells();

157

console.log(`Currently invalid cells: ${currentlyInvalid.length}`);

158

159

// Validate specific column

160

const nameColumn = table.getColumn("name");

161

const invalidNameCells = nameColumn.validate();

162

163

// Validate specific row

164

const firstRow = table.getRow(0);

165

const invalidRowCells = firstRow.validate();

166

167

// Validate specific cell

168

const emailCell = table.getRow(0).getCell("email");

169

const isEmailValid = emailCell.isValid();

170

const emailValidationResult = emailCell.validate();

171

172

// Clear validation for specific cell

173

emailCell.clearValidation();

174

```

175

176

## Built-in Validators

177

178

Tabulator provides comprehensive built-in validators for common validation scenarios.

179

180

```javascript { .api }

181

/**

182

* Built-in validator functions

183

*/

184

interface BuiltinValidators {

185

/**

186

* Must be an integer value

187

*/

188

integer(cell: CellComponent, value: any, parameters?: any): boolean;

189

190

/**

191

* Must be a float value

192

*/

193

float(cell: CellComponent, value: any, parameters?: any): boolean;

194

195

/**

196

* Must be a numeric value

197

*/

198

numeric(cell: CellComponent, value: any, parameters?: any): boolean;

199

200

/**

201

* Must be a string value

202

*/

203

string(cell: CellComponent, value: any, parameters?: any): boolean;

204

205

/**

206

* Must be alphanumeric characters only

207

*/

208

alphanumeric(cell: CellComponent, value: any, parameters?: any): boolean;

209

210

/**

211

* Must be less than or equal to maximum value

212

*/

213

max(cell: CellComponent, value: any, parameters: number): boolean;

214

215

/**

216

* Must be greater than or equal to minimum value

217

*/

218

min(cell: CellComponent, value: any, parameters: number): boolean;

219

220

/**

221

* Must start with specified string

222

*/

223

starts(cell: CellComponent, value: any, parameters: string): boolean;

224

225

/**

226

* Must end with specified string

227

*/

228

ends(cell: CellComponent, value: any, parameters: string): boolean;

229

230

/**

231

* String must be at least minimum length

232

*/

233

minLength(cell: CellComponent, value: any, parameters: number): boolean;

234

235

/**

236

* String must be at most maximum length

237

*/

238

maxLength(cell: CellComponent, value: any, parameters: number): boolean;

239

240

/**

241

* Value must be in provided list

242

*/

243

in(cell: CellComponent, value: any, parameters: any[] | string): boolean;

244

245

/**

246

* Must match provided regular expression

247

*/

248

regex(cell: CellComponent, value: any, parameters: string | RegExp): boolean;

249

250

/**

251

* Value must be unique in this column

252

*/

253

unique(cell: CellComponent, value: any, parameters?: any): boolean;

254

255

/**

256

* Value is required (not empty, null, or undefined)

257

*/

258

required(cell: CellComponent, value: any, parameters?: any): boolean;

259

}

260

```

261

262

**Validator Usage Examples:**

263

264

```javascript

265

// Single validator

266

{

267

title: "Age",

268

field: "age",

269

validator: "required"

270

}

271

272

// Multiple validators

273

{

274

title: "Username",

275

field: "username",

276

validator: ["required", "minLength", "alphanumeric", "unique"],

277

validatorParams: {

278

minLength: 3

279

}

280

}

281

282

// Validator with parameters

283

{

284

title: "Score",

285

field: "score",

286

validator: ["required", "numeric", "min", "max"],

287

validatorParams: {

288

min: 0,

289

max: 100

290

}

291

}

292

293

// Regex validator

294

{

295

title: "Phone",

296

field: "phone",

297

validator: "regex",

298

validatorParams: "^\\+?[1-9]\\d{1,14}$" // E.164 format

299

}

300

301

// In list validator

302

{

303

title: "Status",

304

field: "status",

305

validator: "in",

306

validatorParams: ["active", "inactive", "pending"]

307

}

308

```

309

310

## Custom Validators

311

312

Create custom validation functions for application-specific validation requirements.

313

314

```javascript { .api }

315

/**

316

* Custom validator function signature

317

* @param cell - CellComponent being validated

318

* @param value - Current cell value

319

* @param parameters - Validation parameters

320

* @returns True if valid, error message/object if invalid

321

*/

322

type ValidatorFunction = (

323

cell: CellComponent,

324

value: any,

325

parameters?: any

326

) => boolean | string | any;

327

```

328

329

**Custom Validator Examples:**

330

331

```javascript

332

// Custom email validator

333

function emailValidator(cell, value, parameters) {

334

if (!value) return true; // Allow empty values

335

336

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

337

return emailRegex.test(value) ? true : "Please enter a valid email address";

338

}

339

340

// Age range validator with context

341

function ageValidator(cell, value, parameters) {

342

const rowData = cell.getRow().getData();

343

const minAge = parameters.min || 0;

344

const maxAge = parameters.max || 120;

345

346

if (value < minAge) {

347

return `Age must be at least ${minAge}`;

348

}

349

350

if (value > maxAge) {

351

return `Age cannot exceed ${maxAge}`;

352

}

353

354

// Additional business logic

355

if (rowData.role === "manager" && value < 25) {

356

return "Managers must be at least 25 years old";

357

}

358

359

return true;

360

}

361

362

// Cross-field validation

363

function passwordConfirmValidator(cell, value, parameters) {

364

const rowData = cell.getRow().getData();

365

const password = rowData.password;

366

367

return value === password ? true : "Passwords do not match";

368

}

369

370

// Async validator (returns Promise)

371

function uniqueUsernameValidator(cell, value, parameters) {

372

if (!value) return true;

373

374

return fetch(`/api/check-username/${encodeURIComponent(value)}`)

375

.then(response => response.json())

376

.then(data => data.unique ? true : "Username already exists");

377

}

378

379

// Usage in column definitions

380

const table = new Tabulator("#table", {

381

columns: [

382

{

383

title: "Email",

384

field: "email",

385

validator: emailValidator,

386

editor: "input"

387

},

388

{

389

title: "Age",

390

field: "age",

391

validator: ageValidator,

392

validatorParams: { min: 18, max: 65 },

393

editor: "number"

394

},

395

{

396

title: "Confirm Password",

397

field: "confirmPassword",

398

validator: passwordConfirmValidator,

399

editor: "input"

400

},

401

{

402

title: "Username",

403

field: "username",

404

validator: [uniqueUsernameValidator, "required", "minLength"],

405

validatorParams: { minLength: 3 },

406

editor: "input"

407

}

408

]

409

});

410

```

411

412

## Validation Modes

413

414

Configure how validation errors are handled and displayed.

415

416

```javascript { .api }

417

type ValidationMode = "blocking" | "highlighting" | "manual";

418

```

419

420

**Validation Mode Examples:**

421

422

```javascript

423

// Blocking mode - prevent invalid edits

424

const strictTable = new Tabulator("#strict-table", {

425

validationMode: "blocking", // Default mode

426

columns: [

427

{

428

title: "Required Field",

429

field: "required_field",

430

validator: "required",

431

editor: "input"

432

}

433

]

434

});

435

436

// Highlighting mode - allow edits but highlight invalid cells

437

const flexibleTable = new Tabulator("#flexible-table", {

438

validationMode: "highlighting",

439

columns: [

440

{

441

title: "Optional Field",

442

field: "optional_field",

443

validator: "numeric",

444

editor: "input"

445

}

446

]

447

});

448

449

// Manual mode - validation only when explicitly called

450

const manualTable = new Tabulator("#manual-table", {

451

validationMode: "manual",

452

columns: [

453

{

454

title: "Manual Validation",

455

field: "manual_field",

456

validator: "required",

457

editor: "input"

458

}

459

]

460

});

461

462

// Manually trigger validation

463

document.getElementById("validate-btn").addEventListener("click", () => {

464

const invalid = manualTable.validate();

465

if (invalid.length > 0) {

466

alert(`Found ${invalid.length} validation errors`);

467

} else {

468

alert("All data is valid!");

469

}

470

});

471

```

472

473

## Events

474

475

Validation-related events for responding to validation state changes.

476

477

```javascript { .api }

478

// Validation events

479

table.on("validationFailed", function(cell, value, validators) {

480

console.log("Validation failed:", cell.getField(), value, validators);

481

});

482

483

table.on("validationPassed", function(cell, value) {

484

console.log("Validation passed:", cell.getField(), value);

485

});

486

```

487

488

## Types

489

490

```javascript { .api }

491

interface ValidatorParams {

492

[key: string]: any;

493

min?: number;

494

max?: number;

495

minLength?: number;

496

maxLength?: number;

497

regex?: string | RegExp;

498

}

499

500

interface ValidationResult {

501

valid: boolean;

502

error?: string | any;

503

}

504

```