enhancement
major
minor
defect
critical
major
minor
minor
#30198
React Views: Tree Table ({{{<tree-table>}}}) without row editing ({{{row-edit}}}) – not a replacement for the classic tree grid
Problem
The new view layer does not include a tree table whose rows can be edited in a form.
- <table row-edit="ALL|SELECTED"> (RowSetTableControl) only supports flat sets of rows.
- According to the documentation,<tree-table> has “no rows, no group-by, and no row-edit.”
- Setting `edit-in-place="true" ` on the `<tree-table> ` is not a substitute:
- Each value is written immediately in its own transaction, without a shared save/cancel mechanism.
- Attribute columns are not edited in place; calculated columns with their own <update> would be required.
- The classic Tree Grid (GridComponent with TreeGridBuilder) can do exactly that: tree structure, row-by-row editing, and only the fields of the row type per row. However, it cannot be embedded in the React view layer.
Version: 8.0.0-alpha12, module tl-layout-react (TreeTableElement, RowSetTableControl).
Use Case
Project status overview (new VW PRIME project):
- Tree structure: Project → Subproject → Sub-subproject → Work Package.
- For each row, the current status report with traffic lights, progress, and a note on bulk maintenance.
- The legacy application displays this as a tree grid.
- Workaround: flat <table row-edit="ALL"> in tree order with a PSP column for the structure. Expand/collapse functionality and indentation are missing.
Expected Behavior (Suggestion)
<tree-table row-edit="ALL|SELECTED"> within a <form>, analogous to the flat table:
- The cells of the editable rows display the input for the attribute column (AttributeCellEditing). The attribute is resolved based on the row type, so that rows without the attribute remain empty and uneditable.
- Changes are buffered and written when the form is saved.
- During editing, the tree remains frozen (no rebuilding; expanded state is preserved).
- Desirable: Adding and removing child rows via the parent node’s composition.
Impact
Mass maintenance of hierarchical data is a core pattern of migrated TL-7 applications (Tree-Grid). Without Tree-Row-Edit, only flat workarounds remain.
Solution
<tree-table row-edit="ALL|SELECTED"> within a <form> edits the tree’s rows just like the flat row-edit table: {{{#!xml <form input="editAnchor">
<tree-table row-edit="ALL" on-remove="DELETE" selection="selected"
types="demo.tickets:Project,demo.tickets:Item"
root="$project" children="$node.get(demo.tickets:Item#children)">
<inputs><input channel="project"/></inputs>
<add-child create-type="demo.tickets:Item"
insert="$parent.add(demo.tickets:Item#children, $child)"/>
<columns>...</columns>
</tree-table>
</form> }}}
- Cached editing: The cells of editable rows display the input for their respective columns; the attribute is resolved based on the type of the respective row. All changes are written together when the form is saved; canceling discards them. With ` row-edit="SELECTED" `, exactly the selected row is editable.
- Rows are added when expanded: A row is only included in editing when it is displayed (its parent node is expanded). Expanding the node does not change the form. This allows editing to work even for large or unlimited trees (canExpandAll="false").
- Tree during editing: The tree is not rebuilt based on model changes from other locations but follows the entries inthe form: the ` children` function is evaluated via the form’s buffer, so that added and removed rows appear or disappear immediately. Only the child lists that have read a changed value are recalculated. The expanded state and the selection are preserved when switching between view and edit modes. After saving or canceling, the tree reverts to following the model.
- Add child rows with <add-child create-type="…" insert="…"/>: `create-type` calculates the type of the new object from the parent object (`$parent`: the selected row; if nothing is selected, the root object of the tree)—an abstract class offers its concrete specializations in a menu; if no result is returned, no addition is available for this parent node. `insert` inserts the new, unsaved object ($child) into the parent object’s buffer, typically into a composition; it is not saved until the form is submitted. The parent row is expanded, the new row is selected, and becomes editable. `parent-as` and ` child-as ` rename the variables.
- Remove rows with ` on-remove="DELETE"`: The row disappears immediately and is deleted upon saving; canceling the operation restores it. Deleting the object also deletes the parts of its compositions; rows that were linked to the deleted row via a simple reference disappear from view but are not deleted. `on-remove="UNLINK"` is a configuration error in a tree table.
- Limitation: A backward reference (kind="backwards") is resolved from the saved objects. A child that can only be found via a backward reference from the parent node therefore appears only after saving; children are inserted via a forward reference (composition) from the parent object.
- Using `row-edit` outside of a `<form> ` element, or in combination with `edit-in-place`, `<drag> `, or `<drop>`, is a configuration error, just as it is with the flat table.
- Fixed as a side note: An attribute column no longer displays a cell in a row whose type does not include that attribute. Previously, for example, a Boolean attribute would display an empty checkbox or, in edit mode, a disabled input field (this affects all tables with rows of different types).
Demo in tl-demo-react: Demos → Tree Grid (Project Areas → Milestones / Deliverables → Tickets), once with `row-edit="ALL" ` (add milestones, delete rows), and once with ` row-edit="SELECTED" ` (add deliverables of a selected type).
Technical note: RowSetTableControl organizes its rows using a RowArrangement (flat: ListRowArrangement; tree: TreeRowArrangement on the RowTree, which is also used by the read-only tree table); new rows are created via RowCreation (ChildRowCreation for <add-child>). RowSetEditSession#adoptRows adopts saved rows as the original rows during an ongoing editing session. row-edit and on-remove are now properties of all table elements (AbstractTableElement.Config). Documentation: Article view-layer/tree-tables, section “Editing rows.”