Skip to content

Cell Validation with Renderers

Source code
import { defineCustomElements } from '@revolist/revogrid/loader';
import { ColumnStretchPlugin, TooltipPlugin } from '@revolist/revogrid-pro';
import { currentTheme } from '../composables/useRandomData';
import './validate-basic.css';
import {
cloneBasicValidationSource,
createValidateBasicColumns,
defaultValidateBasicOptions,
getInvalidPriceCount,
type ValidateBasicOptions,
} from './validate-basic.data';
import {
VALIDATE_BASIC_OPTIONS_CHANGE_EVENT,
createValidateBasicToolbar,
defineValidateBasicToolbarElement,
type ValidateBasicOptionsChangeEvent,
} from './validate-basic-toolbar';
defineCustomElements();
defineValidateBasicToolbarElement();
export function load(parentSelector: string) {
const host = document.querySelector(parentSelector);
if (!host) {
return;
}
const { isDark } = currentTheme();
const wrapper = document.createElement('div');
const grid = document.createElement('revo-grid');
const source = cloneBasicValidationSource();
const options: ValidateBasicOptions = { ...defaultValidateBasicOptions };
const toolbar = createValidateBasicToolbar(
options,
getInvalidPriceCount(source, options.rule),
);
wrapper.className = `validate-basic-demo ${isDark() ? 'is-dark' : ''}`;
const applyOptions = () => {
grid.columns = createValidateBasicColumns(options);
toolbar.invalidCount = getInvalidPriceCount(source, options.rule);
};
toolbar.addEventListener(VALIDATE_BASIC_OPTIONS_CHANGE_EVENT, (event) => {
Object.assign(options, (event as ValidateBasicOptionsChangeEvent).detail);
applyOptions();
});
grid.plugins = [ColumnStretchPlugin, TooltipPlugin];
grid.stretch = 'all';
grid.theme = isDark() ? 'darkCompact' : 'compact';
grid.className = 'validate-basic-grid cell-border';
grid.hideAttribution = true;
grid.range = true;
grid.addEventListener('afteredit', () => {
toolbar.invalidCount = getInvalidPriceCount(source, options.rule);
});
applyOptions();
wrapper.append(toolbar, grid);
host.appendChild(wrapper);
grid.source = source;
return () => wrapper.remove();
}

One straightforward way to validate cell data is by combining validate, validationTooltip, and validationRenderer. This marks invalid cells during rendering without changing edit behavior, which is useful for audits, imported data review, and soft warnings.

import { validationRenderer } from '@revolist/revogrid-pro';
const columns = [
{
prop: 'price',
name: 'Price',
validate: (value, row) => value >= row.floor && value <= row.ceiling,
validationTooltip: (value, row) =>
`Price ${value} must stay between ${row.floor} and ${row.ceiling}`,
...validationRenderer({
severity: 'error',
indicatorPlacement: 'corner',
messagePlacement: 'tooltip',
}),
},
];

validationRenderer returns cellProperties and cellTemplate, so it can wrap your existing cell renderer while keeping validation styling in one place. The helper supports:

  • severity: error, warning, or info.
  • indicatorPlacement: corner, start, end, or none.
  • messagePlacement: tooltip, inline, both, or none.
  • message: a custom message resolver when validationTooltip is not enough.
  • invalidProperties: extra cell properties for invalid cells.

messagePlacement controls where the validation message is exposed:

  • tooltip adds title and tooltip data attributes.
  • inline renders the message inside the cell without tooltip attributes.
  • both renders inline text and tooltip attributes.
  • none keeps the visual indicator but hides the message text.