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
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
Migrated from primefaces/primeng#19487 — originally by @domenicotds on 2026-03-20
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);
}
};
}`
Pull Request Link
No response
Reason for not contributing a PR
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
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