Skip to content

Commit 20dedc8

Browse files
committed
fix(multi-column-headers): error is thrown when dynamically removing mch
error is thrown, when dynamically removing a multi column header from a bound collecting with filtering enabled Closes #5393
1 parent 8f4af7b commit 20dedc8

File tree

2 files changed

+112
-9
lines changed

2 files changed

+112
-9
lines changed

projects/igniteui-angular/src/lib/grids/grid-base.component.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import { IgxCheckboxComponent } from './../checkbox/checkbox.component';
4949
import { GridBaseAPIService } from './api.service';
5050
import { IgxGridCellComponent } from './cell.component';
5151
import { IColumnVisibilityChangedEventArgs } from './column-hiding-item.directive';
52-
import { IgxColumnComponent } from './column.component';
52+
import { IgxColumnComponent, IgxColumnGroupComponent } from './column.component';
5353
import { ISummaryExpression } from './summaries/grid-summary';
5454
import { DropPosition, ContainerPositioningStrategy, IgxDecimalPipeComponent, IgxDatePipeComponent } from './grid.common';
5555
import { IgxGridToolbarComponent } from './grid-toolbar.component';
@@ -4283,12 +4283,18 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
42834283
added = true;
42844284
});
42854285

4286-
diff.forEachRemovedItem((record: IterableChangeRecord<IgxColumnComponent>) => {
4287-
// Clear Filtering
4288-
this.gridAPI.clear_filter(record.item.field);
4286+
diff.forEachRemovedItem((record: IterableChangeRecord<IgxColumnComponent | IgxColumnGroupComponent>) => {
4287+
const isColumnGroup = record.item instanceof IgxColumnGroupComponent;
4288+
if (isColumnGroup) {
4289+
this.clearSortingAndFilteringRecursively(record.item);
4290+
} else {
4291+
// Clear Filtering
4292+
this.gridAPI.clear_filter(record.item.field);
4293+
4294+
// Clear Sorting
4295+
this.gridAPI.clear_sort(record.item.field);
4296+
}
42894297

4290-
// Clear Sorting
4291-
this.gridAPI.clear_sort(record.item.field);
42924298
removed = true;
42934299
});
42944300

@@ -5099,6 +5105,19 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
50995105
return false;
51005106
}
51015107

5108+
private clearSortingAndFilteringRecursively(column: IgxColumnGroupComponent | IgxColumnComponent) {
5109+
const isColumnGroup = column instanceof IgxColumnGroupComponent;
5110+
if (isColumnGroup) {
5111+
const columnChildren = column.children;
5112+
columnChildren.forEach((col: IgxColumnComponent | IgxColumnGroupComponent) => {
5113+
return this.clearSortingAndFilteringRecursively(col);
5114+
});
5115+
} else {
5116+
this.gridAPI.clear_filter(column.field);
5117+
this.gridAPI.clear_sort(column.field);
5118+
}
5119+
}
5120+
51025121
/**
51035122
* @hidden
51045123
*/

projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { async, TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
22
import { IgxGridModule } from './grid.module';
33
import { IgxGridComponent } from './grid.component';
4-
import { Component, ViewChild, DebugElement, OnInit, TemplateRef } from '@angular/core';
4+
import { Component, ViewChild, DebugElement, OnInit, TemplateRef, ElementRef } from '@angular/core';
5+
56
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
67
import { IgxColumnComponent, IgxColumnGroupComponent } from '../column.component';
78
import { SortingDirection } from '../../data-operations/sorting-expression.interface';
@@ -17,7 +18,7 @@ const GRID_COL_GROUP_THEAD_TITLE_CLASS = 'igx-grid__thead-title';
1718
const GRID_COL_GROUP_THEAD_GROUP_CLASS = 'igx-grid__thead-group';
1819
const GRID_COL_THEAD_CLASS = '.igx-grid__th';
1920

20-
describe('IgxGrid - multi-column headers', () => {
21+
fdescribe('IgxGrid - multi-column headers', () => {
2122
configureTestSuite();
2223
beforeEach(async(() => {
2324
TestBed.configureTestingModule({
@@ -38,7 +39,8 @@ describe('IgxGrid - multi-column headers', () => {
3839
NestedColumnGroupsGridComponent,
3940
DynamicGridComponent,
4041
NumberColWidthGridComponent,
41-
NestedColGroupsWithTemplatesGridComponent
42+
NestedColGroupsWithTemplatesGridComponent,
43+
DynamicColGroupsGridComponent
4244
],
4345
imports: [
4446
NoopAnimationsModule,
@@ -1416,6 +1418,40 @@ describe('IgxGrid - multi-column headers', () => {
14161418
headerSpans = fixture.debugElement.queryAll(By.css('.' + GRID_COL_GROUP_THEAD_TITLE_CLASS));
14171419
expect(headerSpans[1].nativeElement.textContent).toBe('Location');
14181420
}));
1421+
1422+
it('There shouldn\'t be any errors when dynamically removing a column group with filtering enabled', () => {
1423+
const fixture = TestBed.createComponent(DynamicColGroupsGridComponent);
1424+
fixture.detectChanges();
1425+
1426+
const grid = fixture.componentInstance.grid;
1427+
const button = fixture.componentInstance.removeBtn;
1428+
1429+
let columnLength = grid.columnList.length;
1430+
let firstColumnGroup = grid.columnList.first;
1431+
let expectedColumnName = 'First';
1432+
let expectedColumnListLength = 10;
1433+
1434+
expect(firstColumnGroup.header).toEqual(expectedColumnName);
1435+
expect(expectedColumnListLength).toEqual(columnLength);
1436+
1437+
expect(() => {
1438+
// Delete first column group
1439+
button.nativeElement.dispatchEvent(new Event('click'));
1440+
fixture.detectChanges();
1441+
1442+
// Delete first column group
1443+
button.nativeElement.dispatchEvent(new Event('click'));
1444+
fixture.detectChanges();
1445+
}).not.toThrow();
1446+
1447+
firstColumnGroup = grid.columnList.first;
1448+
expectedColumnName = 'Third';
1449+
columnLength = grid.columnList.length;
1450+
expectedColumnListLength = 3;
1451+
1452+
expect(firstColumnGroup.header).toEqual(expectedColumnName);
1453+
expect(expectedColumnListLength).toEqual(columnLength);
1454+
});
14191455
});
14201456

14211457
@Component({
@@ -1766,6 +1802,54 @@ export class NestedColGroupsGridComponent {
17661802
data = SampleTestData.contactInfoDataFull();
17671803
}
17681804

1805+
@Component({
1806+
template: `
1807+
<igx-grid [data]="data" [allowFiltering]="true">
1808+
<igx-column-group *ngFor="let colGroup of columnGroups" [header]="colGroup.columnHeader">
1809+
<igx-column *ngFor="let column of colGroup.columns" [field]="column.field" [dataType]="column.type"
1810+
[filterable]="true"></igx-column>
1811+
</igx-column-group>
1812+
</igx-grid>
1813+
<article>
1814+
<button #removeFirstColGroup (click)="removeFirstColumnGroup()">Remove first column group</button>
1815+
</article>
1816+
`
1817+
})
1818+
export class DynamicColGroupsGridComponent {
1819+
1820+
@ViewChild(IgxGridComponent, { static: true })
1821+
public grid: IgxGridComponent;
1822+
1823+
@ViewChild('removeFirstColGroup', { static: true })
1824+
public removeBtn: ElementRef;
1825+
1826+
public columnGroups: Array<any>;
1827+
public data = SampleTestData.contactInfoDataFull();
1828+
1829+
constructor() {
1830+
this.columnGroups = [
1831+
{ columnHeader: 'First', columns: [
1832+
{ field: 'ID', type: 'string' },
1833+
{ field: 'CompanyName', type: 'string' },
1834+
{ field: 'ContactName', type: 'string' },
1835+
]},
1836+
{ columnHeader: 'Second', columns: [
1837+
{ field: 'ContactTitle', type: 'string' },
1838+
{ field: 'Address', type: 'string' },
1839+
]},
1840+
{ columnHeader: 'Third', columns: [
1841+
{ field: 'PostlCode', type: 'string' },
1842+
{ field: 'Contry', type: 'string' },
1843+
]},
1844+
];
1845+
}
1846+
1847+
public removeFirstColumnGroup() {
1848+
this.columnGroups = this.columnGroups.splice(1, this.columnGroups.length - 1);
1849+
}
1850+
1851+
}
1852+
17691853
@Component({
17701854
template: `
17711855
<igx-grid #grid [data]="data" height="600px" width="1000px" columnWidth="100px">

0 commit comments

Comments
 (0)