Building a Flexible Editable Table in Power Apps: Add, Edit, and Delete Modes
Extend a gallery-based editable table so users can insert new rows, modify existing data, and remove records — all from a single screen.
In many business apps, users need to work with data in a table that feels like Excel — quickly adding new rows, modifying existing ones, and removing unwanted entries. This tutorial shows how to add those three operations to a gallery-based editable table in Power Apps, building on the technique used for in-place editing (often called “Part 1”).
We’ll use a Team Task Tracker as our scenario. The data source is a SharePoint list named TeamTasks with the following columns:
| Column | Type |
|---|---|
| Title | Single line of text |
| AssignedTo | Person or Group |
| Priority | Choice (High, Medium, Low) |
| Status | Choice (Not Started, In Progress, Completed) |
| DueDate | Date and Time |
The main screen will contain a vertical gallery that shows tasks. Users can switch between view, edit, add, and delete modes using icons placed outside the gallery. The same Save/Cancel action buttons work across edit and add modes.
Setting Up the Editable Gallery
Assume you already have a gallery with text input controls bound to the fields. The gallery’s Items property points to a SharePoint list, but we’ll override it with a collection when the user enters add mode.
Define a mode variable, gvMode, and a flag gvDeleteActive.
The Items property of the gallery should be:
Switch( gvMode, "add", colNewRecords, "edit", colEditedRecords, "delete", TeamTasks, TeamTasks )
When gvMode is blank (view mode) or "delete", the gallery shows live data from the SharePoint list. During edit mode, the gallery shows a copy of the data in colEditedRecords. For add mode, it shows a collection of blank records.
The DisplayMode of each text input inside the gallery should be:
If( gvMode in ["add", "edit"], DisplayMode.Edit, DisplayMode.View )
Adding New Records
When the user clicks an Add icon, the app prepares two empty rows in a collection called colNewRecords and switches the gallery to add mode.
ClearCollect(
colNewRecords,
{ RecordID: 1, Title: "", AssignedTo: "", Priority: "Medium", Status: "Not Started", DueDate: DateAdd(Today(), 7) },
{ RecordID: 2, Title: "", AssignedTo: "", Priority: "Medium", Status: "Not Started", DueDate: DateAdd(Today(), 7) }
);
Set(gvMode, "add")Auto‑Add a New Row When the Last Row Is Filled
To keep adding rows without extra clicks, place the following code in the OnChange property of every text input in the gallery.
With(
{ lastId: Last(colNewRecords).RecordID },
If(
gvMode = "add" And ThisItem.RecordID = lastId,
Collect(colNewRecords, { RecordID: lastId + 1, Title: "", AssignedTo: "", Priority: "Medium", Status: "Not Started", DueDate: DateAdd(Today(), 7) })
)
)This way, as soon as the user enters data in the last visible row, a new empty row appears below it.
Saving and Cancelling New Records
The Save icon needs to behave differently depending on whether the gallery is in “add” or “edit” mode. We structure the OnSelect code with an If statement that branches on gvMode.
If(
gvMode = "add",
// ---- Add new records ----
ForAll(
colNewRecords As newRow,
Patch(
TeamTasks,
Defaults(TeamTasks),
{
Title: newRow.Title,
AssignedTo: newRow.AssignedTo,
Priority: newRow.Priority,
Status: newRow.Status,
DueDate: newRow.DueDate
}
)
);
Clear(colNewRecords);
Set(gvMode, Blank());
,
gvMode = "edit",
// ---- Update existing records ----
ForAll(
Filter(gal_Tasks.AllItems, tog_IsChanged.Value) As changedRow,
Patch(
TeamTasks,
LookUp(TeamTasks, ID = changedRow.ID),
{
Title: changedRow.txt_Title.Text,
AssignedTo: changedRow.txt_AssignedTo.Text,
Priority: changedRow.txt_Priority.Text,
Status: changedRow.txt_Status.Text,
DueDate: Value(changedRow.dte_DueDate.Text)
}
)
);
Clear(colEditedRecords);
Set(gvMode, Blank())
)The Cancel icon simply resets the mode and clears any temporary data without saving.
Clear(colNewRecords); Set(gvMode, Blank())
Deleting Records
Delete operations work in two ways: entering a dedicated delete mode where the user selects rows to remove, or deleting individual rows while already in edit or add mode.
Delete Mode
Add a Delete icon that sets gvMode to "delete" and enables the deletion flag.
Set(gvMode, "delete"); Set(gvDeleteActive, true)
Inside the gallery, place a Trash icon (named ico_DeleteRow). Its Icon property toggles between Trash and Cancel depending on whether the row is marked for deletion.
If(ThisItem in colDeleteQueue, Icon.Cancel, Icon.Trash)
The OnSelect of that icon adds or removes the record from a collection colDeleteQueue.
If( Self.Icon = Icon.Trash, Collect(colDeleteQueue, ThisItem), Remove(colDeleteQueue, ThisItem) ); Set(gvDeleteActive, CountRows(colDeleteQueue) > 0)
Make the delete‑row icon visible only when the gallery is in an appropriate mode:
gvMode in ["delete", "edit"] Or (gvMode = "add" And ThisItem.RecordID < Max(colNewRecords, RecordID) And CountRows(colNewRecords) > 1)
Two new icons on the screen – ConfirmDelete and CancelDelete – appear when gvDeleteActive is true. The ConfirmDelete icon removes all records stored in colDeleteQueue.
If( gvMode in ["delete", "edit"], Remove(TeamTasks, colDeleteQueue), Remove(colNewRecords, colDeleteQueue) ); Clear(colDeleteQueue); Set(gvDeleteActive, false); If(gvMode = "delete", Set(gvMode, Blank()))
The CancelDelete icon simply clears the queue and exits delete mode.
Clear(colDeleteQueue); Set(gvDeleteActive, false); If(gvMode = "delete", Set(gvMode, Blank()))
Deleting While in Add or Edit Mode
Because the delete icon inside the gallery is already visible during add/edit modes (thanks to the visibility expression above), users can delete rows without switching to delete mode. The Confirm icon’s If statement handles this by branching on gvMode. For add mode, it removes the row from colNewRecords; for edit mode, it removes it from the live data source through the colDeleteQueue collection.
Performance and Delegation Considerations
ForAllwith gallery.AllItems is not delegable. The examples above useForAllover small collections (new records or filtered edited rows). If you expect many rows, avoid this pattern – instead, loop through records using aPatchwith multiple arguments or use a singlePatchwith a table of values.Filter(TeamTasks, …)inside ForAll may also face delegation limits. For smaller lists (≤500–2000 items) the impact is negligible. For larger lists, consider breaking the operation into separatePatchcalls with explicit IDs.- Collecting all gallery items with
AllItemscan be slow. Limit the gallery to only the rows being changed, or use a hidden gallery to track changes. - Always test with real data volumes to catch hidden delegation problems.
Common Mistakes & Troubleshooting
| Mistake | Resolution |
|---|---|
| New rows are also deleted when deleting from the main data source | Use the If(gvMode…) check inside the Confirm icon to act on the correct collection. |
| Auto‑add doesn’t trigger | Ensure the OnChange code is placed on every input control, not just one. |
Duplicate IDs in colNewRecords | Use RecordID based on CountRows(colNewRecords) + 1 or another deterministic sequence. |
| Save icon works in edit mode but not add mode | Confirm that the If(gvMode = "add" … branch comes first; otherwise the default edit logic might be entered incorrectly. |
| Gallery doesn’t refresh after save | After patching, clear the temporary collection and reset gvMode to blank. Then call Refresh(TeamTasks) if needed. |
Final Recommendation
This pattern works well for small to medium data volumes (up to a few hundred rows) where full client‑side control is desired. For larger datasets, consider using a form instead of a gallery, or implement backend‑side operations via Power Automate.
When you adapt the code to your own app, rename the variables and collections to match your naming conventions. The logic remains the same regardless of the field names.
References
- Original source: Power Apps Excel‑Style Editable Table – Part 2 by Matthew Devaney
- Microsoft Learn: Create and modify collections in Power Apps
- Microsoft Learn: Delegation overview
Learn how small coding practices—like using descriptive names, flattening conditions, and simplifying logic—can make your apps easier to update and less error-prone.
Move past the gallery and discover the hidden patterns for validation, navigation, and smart submission handling in your data entry forms.
PowerShell unlocks admin capabilities that the Power Platform admin center simply doesn’t offer—from recovering deleted apps to blocking trial licenses. Here’s how to wield them safely.