Unify Logo Footer.svg
Unify Applications
Logo
Inline Editing & Changesets

Inline Editing & Changesets

Logo

7 mins READ

Making a Column Editable

The Editable toggle appears in a column's settings when all three conditions hold:

  1. The column's type is one of the editable types: Text, Number, Percent, Currency, Tag, Boolean, Date Time, Date, Time, Mapped.

  2. The column has a Field Key set.

  3. 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 PropertyDefaultDescription
EditableoffBoolean or condition. Turns on inline editing always or per row
Placeholder TextHint shown in the empty edit control
Validity ConditionsRules an entered value must pass. Failing values are rejected on commit and never enter the changeset
Step size (in minutes)15Time columns only: minute increments for the time picker dropdown (does not constrain typed input)
Date Selection LimitsDate 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.

PropertyDefaultDescription
On Save (event)The handler that runs when the user clicks Save. Wire your update call here, binding {{ id.changesetList }} as its input
DisabledCondition to disable the Save button
LoadingCondition to show a spinner on the Save button
Clear changeset on successful savetrueClears 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

  1. The user edits one or more cells. Each edit fires On Change Cell Value (table-level) and the column's own change event.

  2. 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.

  3. Cancel discards all pending edits. Save fires your On Save event — read {{ id.changesetList }} there and pass it to your update call.

  4. End the On Save handler by calling the table's refetchData method to reload the grid.

  5. With Clear changeset on successful save on (the default), the pending changes clear automatically once the data refresh completes.

What the Changeset Exposes

BindingTypeDescription
{{ id.changesetList }}arrayPending changes as a list ready for an update call. The recommended binding
{{ id.changesetMap }}objectThe 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 }}arrayPending 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:

FieldDescription
primaryKeyThe row's primary key value
targetIndexThe 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.

PageRelationship
Column TypesWhich types are editable and their edit-time options
Table OverviewPrimary key, events and methods in full
Toolbar & ViewsSave Action add-on and its relationship to the toolbar