resizableColumns broken when using a second header row (column grouping) in p-table
#19487 opened on Mar 20, 2026
Description
Describe the bug
When adding a second header row to group columns (e.g. using colspan on a above the main header row), the column resize functionality breaks: resizing a column affects the wrong column instead.
Root cause
The internal method _totalTableWidth() collects column widths using:
let headers = DomHandler.find(tableHead, "tr > th");
This selector matches all elements across all rows in the , including the group header row. As a result, the widths array contains more entries than there are real columns (e.g. 12 group + 33 column = 45 entries instead of 33). When updateStyleElement uses this array with the colIndex of the resized column, it applies the new width to the wrong nth-child index, causing an incorrect column to be resized. To Reproduce
Create a p-table with resizableColumns="true" and scrollable="true" Add a custom header template with two rows: the first with grouped cells, the second with the actual column cells with pResizableColumn Try to resize any column by dragging its resize handle Observe that a different column gets resized instead of the one being dragged
Expected behavior Column resize should affect only the dragged column, regardless of how many rows are present in the . Actual behavior The resized column is offset by the number of elements in the group header row. For example, with 12 group headers, resizing column at index 3 actually resizes column at index 3 within the full 45-element array — which corresponds to a different visual column. Proposed fix In _totalTableWidth(), change the selector from "tr > th" to "tr:last-child > th" so that only the elements of the last header row (the actual columns) are collected:
`// BEFORE let headers = DomHandler.find(tableHead, "tr > th");
// AFTER let headers = DomHandler.find(tableHead, "tr:last-child > th");`
This is a one-line fix that makes the width array length consistent with the actual number of resizable columns. Workaround Monkey-patching _totalTableWidth on the Table instance in ngAfterViewInit:
`ngAfterViewInit(): void { this.patchResizeTableCells(); }
private patchResizeTableCells(): void { if (!this.dtGrid) return;
(this.dtGrid as any)._totalTableWidth = () => { if (!this.columnHeaderGroups?.length) { const tableHead = this.dtGrid.el.nativeElement .querySelector('[data-pc-section="thead"]'); const headers = tableHead.querySelectorAll('tr > th'); return Array.from(headers).map((h: any) => h.offsetWidth); }
const tableHead = this.dtGrid.el.nativeElement
.querySelector('[data-pc-section="thead"]');
const rows = tableHead.querySelectorAll('tr');
const lastRow = rows[rows.length - 1] as HTMLTableRowElement;
const headers = lastRow.querySelectorAll('th');
const widths: number[] = [];
headers.forEach((header: HTMLElement) => {
widths.push(header.offsetWidth);
});
return widths;
}; }`
Pull Request Link
No response
Reason for not contributing a PR
- Lack of time
- Unsure how to implement the fix/feature
- Difficulty understanding the codebase
- Other
Other Reason
No response
Reproducer
https://stackblitz.com/edit/github-jmtdk8rn?file=src%2Fapp%2Fapp.component.ts,package.json
Environment
PrimeNg: 21.1.3
Angular: 21.2.1
TypeScript: 5.9.3
Chrome: 146.0.7680.81
Angular version
21.2.1
PrimeNG version
v21
Node version
No response
Browser(s)
Chrome 146.0.7680.81
Steps to reproduce the behavior
- Create a p-table with resizableColumns="true", columnResizeMode="expand" and scrollable="true"
- Add a custom header template with two rows: the first row contains grouped cells, the second row contains the actual column headers with pResizableColumn
- Load the page and wait for the table to render
- Hover over any column separator in the second header row until the resize cursor appears
- Drag the resize handle to the right to resize the column
Expected behavior
Expected: the dragged column gets wider Actual: a different column gets resized instead — the one at index colIndex - numberOfGroupHeaders, causing a visible layout shift on the wrong column