Start / stop editing
Start
Open the live example: Inline editing (Editing)
| Trigger | Behaviour |
|---|---|
| Double-click a cell | Opens the editor with all text selected. |
Enter on a focused cell |
Same as double-click. |
F2 on a focused cell |
Opens the editor with the caret at the end (no text selection). |
| Typing a character | Opens the editor and replaces the value with the typed character. |
The cell must be focused (the grid's active cell). Click any cell or use the arrow keys to set focus.
The cell must also be editable - its column must have an
editorType, and the grid must have enableInlineEditing={true}.
Stop
| Trigger | Outcome |
|---|---|
Enter |
Commit. Move focus down one row. |
Tab |
Commit. Move focus to the next editable cell in the same row. |
Shift+Tab |
Commit. Move focus to the previous editable cell. |
Esc |
Cancel. Revert to the pre-edit value. |
| Click outside the cell | Commit. |
Programmatic start/stop
Drive the editor from outside the grid with the SvGridApi:
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>
// begin editing a cell (as a double-click would); returns true if it started
api.startEditing(rowIndex, columnId)
api.stopEditing() // commit the active edit (default)
api.stopEditing(true) // cancel / discard the active edit
startEditing returns false when the cell doesn't exist, isn't editable, or
inline editing is disabled. stopEditing returns true if an edit was in
progress. Combine with selectCells and onActiveCellChange to build
form-style / guided-entry flows entirely on the API:
rowIndexis the displayed index.startEditing,selectCellsandonActiveCellChangeall address rows by their position as rendered - after a sort or filter that differs from your source data array. If you scan your own data to decide what to edit next, walkapi.getDisplayedRows()(it returns the rows in display order) and use that index - indexing your unsorted source array would open the wrong cell once the grid is sorted.
<script lang="ts">
let api = $state<SvGridApi<F, Lead> | null>(null)
let active = $state<{ rowIndex: number; columnId: string } | null>(null)
</script>
<button onclick={() => active && api?.startEditing(active.rowIndex, active.columnId)}>Edit</button>
<button onclick={() => api?.stopEditing()}>Save</button>
<button onclick={() => api?.stopEditing(true)}>Cancel</button>
<SvGrid {data} {columns} enableInlineEditing
onApiReady={(a) => (api = a)}
onActiveCellChange={(e) => (active = { rowIndex: e.rowIndex, columnId: e.columnId })} />
Try it
startEditing(rowIndex, columnId) opens an editor without a click, which is how
you wire "edit this row" from a toolbar or a keyboard shortcut.
stopEditing(true) cancels rather than commits.
<script lang="ts">
let api = $state<SvGridApi<{}, Person> | null>(null)
</script>
<div>
<button type="button" onclick={() => api?.startEditing(0, 'name')}>Edit first name</button>
<button type="button" onclick={() => api?.stopEditing(false)}>Commit</button>
<button type="button" onclick={() => api?.stopEditing(true)}>Cancel</button>
</div>
<SvGrid data={people} {columns} editable onApiReady={(next) => (api = next)} />
See also
Live examples
- Inline editing - Typed editors (text/number/checkbox/date) with dirty tracking + save.
- Programmatic editing (start/stop) - Drive the editor from outside via api.startEditing(row, columnId) / stopEditing(cancel?). A toolbar edits the active cell, commits or cancels, and a guided-entry flow jumps to the next blank required field and opens it.
Related articles
- Paste from Excel into a Svelte Data Grid - How to wire up clipboard paste so users can drop a copied Excel or Google Sheets block directly into SvGrid - TSV parsing, type coercion, validation, and row growth all covered.
- A Fill Handle (Drag to Fill) in SvGrid - Build a working spreadsheet-style fill handle on top of SvGrid's cell selection and editing - pointer tracking, range highlighting, series fill, and undo/redo integration all covered.
- An Editable Select / Dropdown Cell in SvGrid - Build a dropdown cell editor in SvGrid using a Svelte 5 snippet - constrain user input to a fixed option set while keeping sort, filter, and undo working on the underlying value.