Data Grid Cell & Batch Editing

In-place editing for BbDataGrid: whole-row editing, isolated single-cell drafts, and staged batch edits saved together. Any Blazor Blueprint input can be the editor.

Row Editing

Add a BbDataGridEditColumn for the pencil, save and cancel buttons, and an EditTemplate to each column you want editable — columns without one stay read-only. An EditTemplate is just a render fragment, so any component works: a text input, a select, a date input, a checkbox. Editors bind straight to the source row, and Cancel restores the values recorded when editing started, on the same instance. Validation runs through a per-row EditContext with DataAnnotations.

Cell Editing with Popup Editors

Each editable cell gets its own small pencil button. Opening one clones the row through EditItemFactory, so nothing touches the real record until the save is accepted. Popup editors — combobox, multi select, the time picker — work here because they render through the portal host, and Escape closes the open picker before it cancels the edit. Clear a name and try to save: the callback rejects it, the draft is kept, and the editor stays open.

Batch Editing

Cells edit exactly as in Cell mode, but saving one only stages its draft — no callback runs. A toolbar above the grid shows "Save changes", "Discard changes" and a pending-row count. Edit a few cells across different rows and different editor types, then save: OnBatchCommit gets every change at once, so you can persist them in one transaction.

Edit on Row Click

EditOnRowClick starts an edit from a plain row click — the whole row in Row mode, or the first editable column in Cell and Batch modes. Leave it off when row click also selects, or the two fight each other.

Choosing an Editor Component

An EditTemplate is an ordinary render fragment, so there is no list of "supported" editors — anything that binds to a property works. The examples above use Input, NumericInput, Select, Combobox, MultiSelect, Checkbox, DateInput and TimeInput. Switch, DatePicker, TimePicker, TreeSelect and Cascader behave the same way.

Two things are worth knowing. Enter commits from a text or numeric editor — the input is blurred first so its pending value is written — but Enter on a button, link, select, combobox, checkbox or switch does not, because those keys belong to the control. Escape closes an open picker first, and only cancels the edit on a second press, so a stray Escape never throws away a half-finished row.

Popup editors render through the portal, so the layout needs BbPortalHost — the same requirement as using those components anywhere else. In Cell and Batch modes the column keeps its width while editing, so give a wide editor such as a multi select an explicit Width on its column.

Drafts and Keys

EditItemFactory must return a genuinely independent copy, including any editable collections or nested objects. The Clone() below copies the skills list with [.. Skills] rather than handing over the same List<string>; without that, editing a draft would silently change the source row. The grid calls the factory to build the draft and again to build a cancel checkpoint, so returning the same instance throws.

Set a stable ItemKey whose value no editor can change. Selection, expansion and editing state are all tracked by key, so they survive a data re-fetch. Changing a key value mid-edit fails the commit with "The row key cannot be changed."

An accepted save copies the draft's public writable properties onto the source row — reference values are assigned, not cloned — and then reprocesses the data, so the row moves to wherever the active sort, filters and grouping put it.

Loading example…