Choose an edit transaction model
Immediate saves need optimistic UI, request cancellation, server rejection handling, and row-version conflicts. Staged saves need dirty indicators, batch validation, review, partial failure behavior, and discard or rollback.
Validate at three layers
Use parsers and column validators for immediate feedback, Pro validation workflows for richer grid rules, and backend validation for authority. Never rely on the browser to enforce permissions or business invariants.
Protect identity and recovery
Use stable row IDs, include a version or ETag in writes, keep the failed user value visible, explain server errors at the affected cell or row, and provide a retry or reset path. Test concurrent edits with two sessions.
Handle concurrent changes
Include a row version or ETag in writes. When another user changes the same record, show which value is stale and let the user refresh, retry, or reconcile. Test a row moving out of the current filter after an edit, permissions changing during a session, and partial batch success. Stable row IDs are essential for attaching outcomes to the correct record.
Design permissions and protected fields
The server determines which users can edit each record and field. The grid can disable or hide editors for clarity, but client state is not enforcement. Recheck permission at commit time and return a specific outcome. Test permission changes during an open session and avoid exposing protected values through exports, clipboard, or validation messages.
Test bulk editing and failure recovery
Paste, fill, multi-row actions, and batch saves can affect many records. Define atomic versus partial behavior, validation summaries, progress, cancellation, retry, and rollback. Return outcomes keyed by stable row and column identity. Users should be able to correct rejected values without re-entering successful changes.
Product evidence
Editing APIs
GridColumn exposes editable, editorType, renderEditor, parser, formatter, validator, and validation configuration. Pro adds broader validation workflows and formulas.
Controlled cell updates with pending row state
import { useState } from "react";
import { Grid, type CellValue, type GridRow } from "@ace-grid/core";
export function EditableOrdersGrid({ initialRows, columns }) {
const [rows, setRows] = useState<GridRow[]>(initialRows);
const [pending, setPending] = useState(new Set<string>());
const updateCell = (
rowId: string | number,
columnKey: string,
value: CellValue,
) => {
setRows((current) =>
current.map((row) =>
row.id === rowId
? { ...row, data: { ...row.data, [columnKey]: value } }
: row,
),
);
setPending((current) => new Set(current).add(String(rowId)));
};
return (
<Grid
data={{ rows, columns }}
columns={{ columnWidths: {}, fillWidth: true }}
layout={{ width: 1200, height: 520 }}
edit={{ isCellEditing: true, onCellChange: updateCell }}
virtual={{ enableVirtualization: true }}
/>
);
}
Limitations and tradeoffs
- Use a form when people edit one record at a time and field-level guidance matters more than scanning comparable rows.
- Do not allow grid edits until the application defines validation, save failure, permission, and conflict behavior.
Common questions
Should cell changes save immediately?
It depends on risk and backend behavior. Immediate saves fit independent low-risk fields; batch or approval flows fit related changes that must be reviewed together.
How should rejected edits appear?
Keep the attempted value and server message attached to the affected row and field, preserve focus, and offer retry or revert without discarding unrelated edits.