Parsing values
When the user commits an edit, the editor's DOM value (a string for text /
number / date inputs, a boolean for checkboxes) is parsed by
parseEditorValue into the canonical value for the column's type.
The examples on this page run against these rows:
<script lang="ts">
import { SvGrid, type GridColumns, type SvGridApi } from '@svgrid/grid'
type Person = {
id: number
name: string
department: string
city: string
age: number
salary: number
}
const people: Person[] = [
{ id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000 },
{ id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000 },
{ id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000 },
{ id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000 },
{ id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000 },
]
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 190, editorType: 'text' },
{ field: 'department', header: 'Department', width: 150, editorType: 'text' },
{ field: 'city', header: 'City', width: 130, editorType: 'text' },
{ field: 'age', header: 'Age', width: 80, editorType: 'number' },
{ field: 'salary', header: 'Salary', width: 130, editorType: 'number', format: { type: 'currency', currency: 'USD' } },
]
</script>
import { parseEditorValue } from '@svgrid/grid'
parseEditorValue('text', 'Ada') // 'Ada'
parseEditorValue('number', '42') // 42
parseEditorValue('number', '4.5') // 4.5
parseEditorValue('number', 'NaN') // null (rejected - caller decides)
parseEditorValue('number', '') // null
parseEditorValue('date', '2026-05-27') // '2026-05-27T00:00:00.000Z'
parseEditorValue('datetime', '2026-05-27T14:32') // '2026-05-27T14:32:00.000Z'
parseEditorValue('checkbox', 'true') // true
parseEditorValue('checkbox', true) // true
The full source is short and worth reading: cell-editors.ts.
Custom parsing with valueParser
Add a per-column valueParser to refine the committed value after the
built-in parseEditorValue coercion, before it is written to the row. Return
the final value to store. It runs on every commit and flows through the undo
history and onCellValueChange.
{ field: 'sku', editorType: 'text',
// "kb 101" -> "KB-101"
valueParser: ({ newValue }) =>
String(newValue).trim().toUpperCase().replace(/\s+/g, '-') },
{ field: 'price', editorType: 'text', format: { type: 'currency', currency: 'USD' },
// accept "$1,299.90" / "1299.9" -> 1299.9
valueParser: ({ newValue, oldValue }) => {
const n = Number(String(newValue).replace(/[^0-9.\-]/g, ''))
return Number.isFinite(n) ? Math.round(n * 100) / 100 : oldValue
} },
{ field: 'discount', editorType: 'number',
// clamp 0..100, integer
valueParser: ({ newValue }) => Math.max(0, Math.min(100, Math.round(Number(newValue) || 0))) },
The callback receives ValueParserParams:
type ValueParserParams<TData> = {
newValue: unknown // value after built-in per-editorType coercion
oldValue: unknown // the cell's previous value
rawInput: string // the raw string the editor produced (pre-coercion)
data: TData // the row object
columnId: string
}
What "null" means
parseEditorValue returns null to signal "could not parse". The grid
treats null as an empty value and writes it into the cell. If you want
invalid input rejected (the value reverts to its pre-edit state),
intercept before the write - see Validation.
Try it
valueParser runs after the editor's own coercion and before the value reaches
your row, so it is the place to normalise input. Type a name in lower case, or
a salary with a k suffix.
<script lang="ts">
const parsed: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 220, editorType: 'text',
// Title-case whatever they typed.
valueParser: (p) =>
String(p.newValue ?? '')
.toLowerCase()
.replace(/\b[a-z]/g, (c) => c.toUpperCase()) },
{ field: 'salary', header: 'Salary', width: 150, editorType: 'text',
// "142k" -> 142000. rawInput is the string before coercion, which is the
// only place the k is still visible.
valueParser: (p) => {
const raw = p.rawInput.trim().toLowerCase()
const n = Number.parseFloat(raw)
if (Number.isNaN(n)) return p.oldValue
return raw.endsWith('k') ? n * 1000 : n
},
format: { type: 'currency', currency: 'USD' } },
]
</script>
<SvGrid data={people} columns={parsed} editable />
See also
Live examples
- Validation while editing - Per-column rules: invalid commits get rolled back via setCellValue + logged to a recent-rejections panel.
- valueParser - transform on commit - Per-column `valueParser` refines the committed value after built-in coercion: uppercase a SKU, parse "$1,299.90" into a number, clamp a discount 0–100, round a weight. Log shows raw input → stored.