Making a Column Editable
The Editable toggle appears in a column's settings when all three conditions hold:
The column's type is one of the editable types: Text, Number, Percent, Currency, Tag, Boolean, Date Time, Date, Time, Mapped.
The column has a Field Key set.
The table has a Primary Key configured (edits are tracked per row key).
The toggle also accepts conditions, so a column can be editable only for specific rows — for example only while {{ orders.context.currentRow.status }} === 'draft'.
| Edit Property | Default | Description |
| Editable | off | Boolean or condition. Turns on inline editing always or per row |
| Placeholder Text | — | Hint shown in the empty edit control |
| Validity Conditions | — | Rules an entered value must pass. Failing values are rejected on commit and never enter the changeset |
| Step size (in minutes) | 15 | Time columns only: minute increments for the time picker dropdown (does not constrain typed input) |
| Date Selection Limits | — | Date columns only: restrict the selectable date range |
The Save Action Add-On
Once at least one column is editable, a Save Action add-on appears under Inspector → Content → Add-ons.
| Property | Default | Description |
| On Save (event) | — | The handler that runs when the user clicks Save. Wire your update call here, binding {{ id.changesetList }} as its input |
| Disabled | — | Condition to disable the Save button |
| Loading | — | Condition to show a spinner on the Save button |
| Clear changeset on successful save | true | Clears pending changes automatically once the save's data refresh completes |
Warning: Without an On Save handler, there is no Save bar. The floating Save/Cancel bar only renders when an On Save handler is configured. Without one, users can edit cells, the edits pile up in the changeset, but nothing on screen offers to save or cancel them. The inspector shows a warning in this case.
The Typical Save Flow
The user edits one or more cells. Each edit fires On Change Cell Value (table-level) and the column's own change event.
A dark floating bar appears at the bottom of the table: "N changes", Cancel, Save. The count is the number of changed fields, not rows.
Cancel discards all pending edits. Save fires your On Save event — read
{{ id.changesetList }}there and pass it to your update call.End the On Save handler by calling the table's
refetchDatamethod to reload the grid.With Clear changeset on successful save on (the default), the pending changes clear automatically once the data refresh completes.
What the Changeset Exposes
| Binding | Type | Description |
{{ id.changesetList }} | array | Pending changes as a list ready for an update call. The recommended binding |
{{ id.changesetMap }} | object | The same edits keyed by row primary-key value, then field key. Resolves at runtime only — not surfaced as a first-class binding suggestion |
{{ id.rowOrderChangesetList }} | array | Pending drag-reorder changes — each entry has the row's primary key and its target index |
changesetList Entry Shape
Each entry in changesetList names the row under a property named after your Primary Key field, plus an updateFields array with one item per changed field:
Warning: Changeset values are always text. Each value in updateFields is a text string regardless of the column's real type — a number or date edit still arrives as text. Convert it on the way into your update call if the target expects a typed value.
Using changesetMap for Pending Values in Other Columns
changesetMap is keyed by the row's primary-key value, then the field key. It only holds values that differ from the original data (unedited rows have no entry). Use it to show a pending value in a different column before saving:
The Changeset Cursor
A changeset cursor is a position in changesetList. Calling clearChangeset(N) removes the first N entries and keeps the rest — useful when you process edits one batch at a time without an On Save handler.
Note: Without an On Save handler, the changeset grows as a log. Every edit appends a new entry (instead of merging per row). Use the cursor to consume and trim: read the current list, process the first N entries, then call clearChangeset(N). Any edits made while the call was running survive at position N and later.
Pasting from a Spreadsheet
Users can paste a block of cells copied from Excel or Google Sheets: click a cell to focus it, then press Ctrl/Cmd+V. The clipboard is read as a grid (tab-separated columns, one row per line) and applied as bulk edits starting at the focused cell. Only cells whose column is editable receive a value. Pasted values enter the changeset exactly as typed edits do.
Note: Copying a range of table cells out to the clipboard is not supported — only pasting in.
Row Ordering Changeset
When the Row Ordering add-on is enabled, users can drag rows to new positions. Pending reorder moves accumulate in {{ id.rowOrderChangesetList }}. Each entry has:
| Field | Description |
primaryKey | The row's primary key value |
targetIndex | The row's new position (0-indexed) |
Process and clear reorder changes with clearRowOrderChangeset(cursor?) — same cursor semantics as clearChangeset.
Behavior & Gotchas
Auto-clear waits for the data refresh, not the save call
"Clear changeset on successful save" clears once the table's data source finishes its next refresh after On Save fires — typically the refetchData call. If On Save never refreshes the data, pending changes linger. If it fails mid-way but a refresh still happens, they clear anyway. Bind {{ id.changesetList }} as your update call's input in the same step — do not read it in a later step after the save, because auto-clear will have emptied it by then.
Editing a cell back to its original value removes it from the pending list
The pending-values map compares each edit against the row's original data. Type the old value back and the entry disappears, lowering the change count. The user cannot "save" a no-op edit through the changeset.
One cell edit fires two change events
An edit emits both the table-level On Change Cell Value and the edited column's own change event. Wire your handler at one level only to avoid running it twice per edit.
Validation runs on commit, not on every keystroke
Validity Conditions run when the user commits the cell (Enter, Tab, or click away). A failing value shows an error on the cell and keeps focus there; it never enters the changeset. Save is never blocked by invalid input because invalid values never reach it.
Second click on a non-editable cell shows "This cell can't be edited"
The first click on any cell focuses it. A second interaction with a non-editable cell (click, Enter, or typing) makes the cell shake briefly and shows an anchored tooltip for about a second. This is not configurable and cannot be turned off; the only exception is Custom columns which never show it.
Frequently Asked Questions
I edited cells but no Save bar appeared. What is missing?
Configure an On Save handler under Add-ons → Save Action → Interactions. The floating Save/Cancel bar only renders when an On Save handler is wired. Without a handler, edits accumulate silently in the changeset with no way for the user to save or discard them.
My pending changes don't clear after my save runs. Why?
"Clear changeset on successful save" waits for the table's data to refresh — not for your save call to complete. Make sure the last action in your On Save handler is a Trigger Component Method → refetchData. If you turned auto-clear off, call clearChangeset explicitly in your handler.
Can users paste a range from Excel into the table?
Yes — focus a cell and press Ctrl/Cmd+V. The clipboard grid is applied as bulk pending edits, editable columns only. Non-editable columns in the paste range are skipped. Copying a range of table cells out to the clipboard is not supported (one direction only: paste in).
My changeset list keeps growing and never resets. What is happening?
This happens when no On Save handler is configured. Without one, the changeset behaves as an append-only log — every edit adds a new entry. Either wire an On Save handler (edits then merge per row and the Save bar appears), or use the changeset cursor pattern to consume and trim the list yourself programmatically.
How do I let users reorder rows and persist the new order?
Enable the Row Ordering add-on. Drag moves accumulate in {{ id.rowOrderChangesetList }}, where each entry has the row's primary key and its targetIndex. In an On Save handler (or from a custom Save button), pass the reorder list to your update call, then call refetchData and clearRowOrderChangeset to clean up.
Related Pages
| Page | Relationship |
| Column Types | Which types are editable and their edit-time options |
| Table Overview | Primary key, events and methods in full |
| Toolbar & Views | Save Action add-on and its relationship to the toolbar |