Getting values
You get cell values in three ways depending on context.
Open the live example: Selection + copy/paste (Selection & Clipboard)
Inside a column definition
field does the obvious thing - row[key]:
{ field: 'firstName', header: 'First' }
Use fieldFn for anything computed:
{
id: 'fullName',
header: 'Full name',
fieldFn: (row) => `${row.firstName} ${row.lastName}`,
}
Inside a cell renderer
A cell callback receives a CellContext:
{
field: 'salary',
header: 'Salary',
cell: (ctx) => {
const value = ctx.getValue() // unknown
const row = ctx.row.original // your TData
const all = ctx.row.getAllCells() // array of Cell
return /* renderSnippet / string / etc. */
},
}
ctx.row.original is the raw row object you passed in - handy when
you want sibling values without going through accessors.
From outside the grid
After onApiReady:
const v = api.getCellValue(rowIndex, columnId)
api.setCellValue(rowIndex, columnId, newValue)
rowIndex is the index in the source data array, not the post-pipeline
displayed index.
Reading by row id
api.getRowId(rowIndex | row) gives a row's stable id: the value your
getRowId prop computed, or the row's position when you set no getRowId.
Pass a display index (the space getActiveCell, scrollToRow and the cell
methods use) or a row object; it returns null for an index or object that
is not in the grid. The id is what selectRows, toggleRowSelected and an
applyTransaction remove all take, so this is how you go from "the active
cell" or "this row object" to an operation keyed by id.
There is no api.getCellValueByRowId(rowId, columnId) helper today. If you
need that, walk api.getData():
function valueByRowId(api: SvGridApi<{}, Person>, rowId: string, col: string) {
const data = api.getData()
const idx = data.findIndex((r) => r.id === rowId)
return idx === -1 ? undefined : api.getCellValue(idx, col)
}
What the grid is showing
api.getDisplayedRows() returns the rows after filter and sort, which is what
you want for an export, a count, or anything a user would describe as "what is
on screen". The source array answers a different question.
<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
joined: string
active: boolean
trend: number[]
}
const people: Person[] = [
{ id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000, joined: '2021-03-01', active: true, trend: [4, 6, 5, 9, 12, 11, 15] },
{ id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000, joined: '2019-07-15', active: true, trend: [9, 8, 11, 10, 14, 16, 15] },
{ id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000, joined: '2020-01-20', active: false, trend: [12, 10, 9, 7, 6, 6, 4] },
{ id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000, joined: '2022-09-05', active: true, trend: [3, 5, 4, 8, 7, 11, 13] },
]
let api = $state<SvGridApi<{}, Person> | null>(null)
let report = $state('(filter or sort, then read)')
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 190 },
{ field: 'department', header: 'Department', width: 160 },
{ field: 'salary', header: 'Salary', width: 140,
format: { type: 'currency', currency: 'USD' } },
]
function read() {
const shown = api?.getDisplayedRows() ?? []
const total = shown.reduce((n, r) => n + (r.salary ?? 0), 0)
report = shown.length + ' row(s), ' + total.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
}
</script>
<button type="button" onclick={read}>Read what is displayed</button>
<SvGrid data={people} {columns} sortable filterable filterMode="row" onApiReady={(next) => (api = next)} />
<p>{report}</p>
The row behind the cell
A cell context carries row.original - your object, untouched. That is what a
renderer or a tooltip should read, because the formatted value has already lost
the type.
<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
joined: string
}
const people: Person[] = [
{ id: 1, name: 'Ada Lovelace', department: 'Engineering', city: 'London', age: 36, salary: 142000, joined: '2021-03-01' },
{ id: 2, name: 'Grace Hopper', department: 'Engineering', city: 'New York', age: 45, salary: 168000, joined: '2019-07-15' },
{ id: 3, name: 'Linus Torvalds', department: 'Platform', city: 'Portland', age: 54, salary: 155000, joined: '2020-01-20' },
{ id: 4, name: 'Radia Perlman', department: 'Networking', city: 'Seattle', age: 49, salary: 161000, joined: '2022-09-05' },
{ id: 5, name: 'Barbara Liskov', department: 'Platform', city: 'Boston', age: 52, salary: 172000, joined: '2018-11-11' },
]
import { renderSnippet } from '@svgrid/grid'
const columns: GridColumns<Person> = [
{ field: 'name', header: 'Name', width: 190 },
{ field: 'salary', header: 'Salary', width: 200,
// ctx.getValue() is the raw number; row.original is the whole row.
cell: (ctx) => renderSnippet(Ratio, { row: ctx.row.original }) },
]
</script>
{#snippet Ratio(props: { row: Person })}
<span>{Math.round(props.row.salary / props.row.age).toLocaleString()} per year of age</span>
{/snippet}
<SvGrid data={people} {columns} />
See also
Related articles
- Render Your First Svelte Data Grid in Under 5 Minutes - How to add a fast, accessible, sortable data grid to a Svelte 5 app with SvGrid - covering data, typed columns, feature composition, and the imperative API.