Validation
Introduction
Section titled “Introduction”Validation gates an edit before it is written to the row. When the user finishes an edit, the grid runs the column’s validator against the value that would be stored; if it fails, the edit is rejected (or flagged) instead of silently corrupting your data.
Two layers cooperate:
- Core (community): a declarative
ColumnDef.validator— an editor-agnostic function that runs on any editor for the column, on the final (parsed) value, with the whole row in scope. Returntrueto accept, or a messagestring/{ valid, message }to reject. - Enterprise:
cellValidation()— a one-call column helper that composes a rule library (required,min,max,minLength,maxLength,pattern,email,oneOf,custom) plus a cross-fieldvalidate, on top of that core primitive.
import { cellValidation, validationRules as v } from '@zengrid/enterprise';
const grid = new Zengrid(mount, { editing: { invalidEditMode: 'block' }, // how a failing value is handled columns: [ cellValidation({ field: 'email', header: 'Email', editor: 'text', rules: [v.required(), v.email()], }), cellValidation({ field: 'seats', header: 'Seats', editor: 'number', rules: [v.required(), v.min(1), v.max(500)], }), ],});The rule library
Section titled “The rule library”Every rule is a small function you compose in a list — the first that fails
blocks the commit with its message. Each rule but required treats an empty
value as valid, so pair required() with the others to make a field mandatory.
| Rule | Rejects |
|---|---|
required(msg?) |
null/undefined/blank string |
minLength(n, msg?) / maxLength(n, msg?) |
strings shorter / longer than n |
min(n, msg?) / max(n, msg?) |
numbers below / above n |
pattern(re, msg?) |
values not matching the regex |
email(msg?) |
malformed email addresses |
oneOf(values, msg?) |
values outside the allowed set |
custom(fn) |
whatever your ({ value, data }) => true | string returns |
You can also write a validator by hand without the helper — anything
({ value }) => true | string — and set it as validator on a plain column.
Cross-field rules
Section titled “Cross-field rules”Both the core validator and the helper’s validate receive the whole row as
params.data, so a rule can compare against sibling columns — e.g. a min that
can’t exceed a max, or a discount that’s only allowed on certain plans.
How a failing value is handled — invalidEditMode
Section titled “How a failing value is handled — invalidEditMode”The column decides whether a value is valid; the grid’s
editing.invalidEditMode decides what happens when it isn’t:
| Mode | Behavior |
|---|---|
'block' (default) |
Keep the editor open, flag the input red, and show the message below it. Nothing is written; the user fixes it or presses Escape. |
'revert' |
Discard the invalid input, restore the original value, and close the editor so focus can move on. |
'commit' |
Write the value anyway but tag the cell .zg-cell-invalid (a red marker) so the error stays visible in the grid. |
Try it live
Section titled “Try it live”Default 'block' mode. Double-click a cell and enter something invalid — Name under 2 chars, a malformed Email, Seats outside 1–500, or a Code that isn't 3 uppercase letters. The editor stays open with a red message until you fix it or press Escape.
- Full Row — validate the whole record at once
with a row-level
validateguard. - Parsing Values —
valueParserruns before validation, so your validator sees the stored value, not the raw text. - Undo / Redo Edits — every accepted edit is undoable.