2026-04-01
Matrix Widget: Row Count — Renderer
Completed the renderer-side of the Matrix Row Count feature. The builder side (Phase 1) was already merged; today's work makes the row count display live and correctly in the actual form filled by end users.
What we built
matrix.component.ts
- Registered a single
FormControlper table using the key${matrixKey}_row_count:- Static tables: registered in
ensureNormalMatrixControls(), initialized toconfig.rows.length. - Iterative tables: registered in
ensureIterativeRowControls(), guarded byiterativeRows.length === 1(same guard pattern already used for column sum controls), initialized to0.
- Static tables: registered in
- Extended
calculateTotal()with a row-count block: for iterative tables count =iterativeRows.length(automatically reactive via the existingvalueChangessubscription); for static tables count =config.rows?.length. Equality check prevents infinite loops. - Added
getRowCountControl()public helper — mirrors thegetSumControlForRow/Colpattern so the template can access the control directly.
matrix.component.html (renderer)
- Added
<tr *ngIf="config.includeRowCount">summary row before the column aggregate row in both iterative and static table blocks. - Count input appears in the last data cell only (not first):
- Simple columns:
let last = laston*ngFor, show input only whenlast. - Grouped columns:
let lastGroup = laston group loop +let lastCol = laston column loop, show input only whenlastGroup && lastCol. Ensures one count per table regardless of group count.
- Simple columns:
- Fixed actions-column filler in the iterative Row Count row: removed
bg-gray-100to match un-highlighted actions column style. - Added
<!-- Column Aggregate Row (iterative) -->comment for readability.
Additional fixes
center-panel.component.html (builder)
- Added
border border-gray-300to all row-aggregate filler cells (*ngIf="item.includeRowAggregate") that were missing borders inside:- Iterative Row Count row (grouped + simple branches)
- Iterative Column Aggregate row (grouped + simple branches)
- Static Row Count row grouped branch
- Static Column Aggregate row grouped branch
- Fixes visual table grid gaps where filler cells for the row-aggregate column had no border, causing a visual break in the table layout.
Matrix Widget: Row Count — Formula Reference Support (Phase 3)
Allowed the Row Count cell (${matrixKey}_row_count) to be selected in the @ mention dropdown of the formula builder and resolved by the formula evaluator, just like column sum cells.
Decisions & Solutions
- No renderer changes needed: The
${matrixKey}_row_countFormControl was already registered in the liveFormGroup(Phase 2), so formula evaluation works automatically. - Label format: Set to
${labelPath}.${el.rowCountLabel || 'Count'}. - Iterative table refactor: Changed an early
returnto a conditional block inupdateFormulaFieldSuggestions()so the iterative branch can push the row count entry whenincludeRowCountis true. - Guard in
onToggleRowCount(): Added a formula-reference guard to block disabling Row Count if referenced, showing an error toast. checkRowCountoption: Added togetFormulaKeysForMatrixStructure()indynaform.service.tsto push${matrixKey}_row_countinto the keys array for reference checking.- Updated
right-panel-static.component.ts(iterative, static simple, and static grouped branches) anddynaform.service.tsaccordingly.
Matrix Widget: Row Count — Validation Rule Fix
Fixed an issue where validation rules referencing @Table.Count (e.g., @Expense.Count < 5) always showed an error, regardless of the actual count because the _row_count control was not pre-registered when validators were attached.
Decisions & Solutions
- Pre-register
_row_count: UpdatedFormEngineService.addMatrixControlsto pre-register the_row_countFormControl beforeattachFormulaValidatorsruns. The matrix component's own registration is safely guarded against conflicts. - Iterative tables: Pre-registered column sum controls and
_row_countin the early return block. - Static tables: Added
addControl('${matrixKey}_row_count', rows.length)after column sum registration for both simple and grouped modes inform-engine.service.ts.