Skip to content

Commit e0c6f77

Browse files
authored
Merge branch '8.2.x' into mkirova/fix-5803
2 parents d88b679 + 277862b commit e0c6f77

File tree

9 files changed

+161
-77
lines changed

9 files changed

+161
-77
lines changed

projects/igniteui-angular/src/lib/combo/combo.component.spec.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,8 @@ describe('igxCombo', () => {
960960
// Combo selection is now based on valueKey:
961961
// if valueKey is specified, only the key will be written in the selection (not the whole data entry)
962962
const itemID = combo.valueKey !== null && combo.value !== undefined ?
963-
combo.data[itemIndex][combo.valueKey] :
964-
combo.data[itemIndex];
963+
combo.data[itemIndex][combo.valueKey] :
964+
combo.data[itemIndex];
965965
expect(combo.isItemSelected(itemID)).toBeTruthy();
966966
expect(combo.selectedItems()[selectedItemIndex]).toEqual(itemID);
967967
}
@@ -971,8 +971,8 @@ describe('igxCombo', () => {
971971
itemIndex: number) {
972972
const checkbox = getCheckbox(dropdownElement, itemIndex);
973973
const itemID = combo.valueKey !== null && combo.value !== undefined ?
974-
combo.data[itemIndex][combo.valueKey] :
975-
combo.data[itemIndex];
974+
combo.data[itemIndex][combo.valueKey] :
975+
combo.data[itemIndex];
976976
expect(checkbox.classList.contains(CSS_CLASS_CHECKED)).toBeFalsy();
977977
expect(combo.isItemSelected(itemID)).toBeFalsy();
978978
}
@@ -2286,6 +2286,37 @@ describe('igxCombo', () => {
22862286
}, 20);
22872287
}, 10);
22882288
});
2289+
2290+
it('Should bind combo data to remote data and clear selection properly', async (done) => {
2291+
const fixture = TestBed.createComponent(IgxComboRemoteDataComponent);
2292+
fixture.detectChanges();
2293+
const combo = fixture.componentInstance.instance;
2294+
let selectedItems = [combo.data[0], combo.data[1]];
2295+
const spyObj = jasmine.createSpyObj('event', ['stopPropagation']);
2296+
combo.toggle();
2297+
combo.selectItems([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2298+
expect(combo.value).toEqual(`${selectedItems[0][combo.displayKey]}, ${selectedItems[1][combo.displayKey]}`);
2299+
expect(combo.selectedItems()).toEqual([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2300+
// Clear items while they are in view
2301+
combo.handleClearItems(spyObj);
2302+
expect(combo.selectedItems()).toEqual([]);
2303+
expect(combo.value).toBe('');
2304+
selectedItems = [combo.data[2], combo.data[3]];
2305+
combo.selectItems([selectedItems[0][combo.valueKey], selectedItems[1][combo.valueKey]]);
2306+
expect(combo.value).toEqual(`${selectedItems[0][combo.displayKey]}, ${selectedItems[1][combo.displayKey]}`);
2307+
2308+
// Scroll selected items out of view
2309+
combo.virtualScrollContainer.scrollTo(40);
2310+
await wait(60);
2311+
fixture.detectChanges();
2312+
combo.handleClearItems(spyObj);
2313+
expect(combo.selectedItems()).toEqual([]);
2314+
expect(combo.value).toBe('');
2315+
combo.selectItems([combo.data[7][combo.valueKey]]);
2316+
expect(combo.value).toBe(combo.data[7][combo.displayKey]);
2317+
done();
2318+
});
2319+
22892320
it('Should render empty template when combo data source is not set', fakeAsync(() => {
22902321
const fixture = TestBed.createComponent(IgxComboEmptyTestComponent);
22912322
fixture.detectChanges();
@@ -3214,7 +3245,7 @@ describe('igxCombo', () => {
32143245
expect(fixture.componentInstance.comboSelectedItems).toEqual([...data].splice(1, 3));
32153246
}));
32163247

3217-
it('Should properly initialize when used in a Template form control', fakeAsync (() => {
3248+
it('Should properly initialize when used in a Template form control', fakeAsync(() => {
32183249
const fix = TestBed.createComponent(IgxComboInTemplatedFormComponent);
32193250
fix.detectChanges();
32203251
tick();

projects/igniteui-angular/src/lib/combo/combo.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,14 +1108,14 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
11081108

11091109
/** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */
11101110
private registerRemoteEntries(ids: any[], add = true) {
1111-
const selection = this.getValueDisplayPairs(ids);
11121111
if (add) {
1112+
const selection = this.getValueDisplayPairs(ids);
11131113
for (const entry of selection) {
11141114
this._remoteSelection[entry[this.valueKey]] = entry[this.displayKey];
11151115
}
11161116
} else {
1117-
for (const entry of selection) {
1118-
delete this._remoteSelection[entry[this.valueKey]];
1117+
for (const entry of ids) {
1118+
delete this._remoteSelection[entry];
11191119
}
11201120
}
11211121
}

projects/igniteui-angular/src/lib/core/styles/components/grid/_excel-filtering-theme.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
/// @requires --var
1313
@mixin _excel-filtering($theme, $palette) {
1414
%grid-excel-filter {
15-
height: rem(15px);
1615
display: block;
1716
}
1817

projects/igniteui-angular/src/lib/grids/column.component.ts

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
QueryList,
1010
TemplateRef,
1111
forwardRef,
12+
OnDestroy,
1213
Output,
1314
EventEmitter
1415
} from '@angular/core';
@@ -35,6 +36,8 @@ import { DeprecateProperty } from '../core/deprecateDecorators';
3536
import { MRLColumnSizeInfo, MRLResizeColumnInfo } from '../data-operations/multi-row-layout.interfaces';
3637
import { DisplayDensity } from '../core/displayDensity';
3738
import { notifyChanges } from './watch-changes';
39+
import { Subject } from 'rxjs';
40+
import { takeUntil } from 'rxjs/operators';
3841
import {
3942
IgxCellTemplateDirective,
4043
IgxCellHeaderTemplateDirective,
@@ -56,7 +59,7 @@ import {
5659
selector: 'igx-column',
5760
template: ``
5861
})
59-
export class IgxColumnComponent implements AfterContentInit {
62+
export class IgxColumnComponent implements AfterContentInit, OnDestroy {
6063
/**
6164
* Sets/gets the `field` value.
6265
* ```typescript
@@ -874,13 +877,13 @@ export class IgxColumnComponent implements AfterContentInit {
874877
return false;
875878
}
876879

877-
/**
878-
* Returns a boolean indicating if the column is a child of a `ColumnLayout` for multi-row layout.
879-
* ```typescript
880-
* let columnLayoutChild = this.column.columnLayoutChild;
881-
* ```
882-
* @memberof IgxColumnComponent
883-
*/
880+
/**
881+
* Returns a boolean indicating if the column is a child of a `ColumnLayout` for multi-row layout.
882+
* ```typescript
883+
* let columnLayoutChild = this.column.columnLayoutChild;
884+
* ```
885+
* @memberof IgxColumnComponent
886+
*/
884887
get columnLayoutChild() {
885888
return this.parent && this.parent.columnLayout;
886889
}
@@ -1015,6 +1018,11 @@ export class IgxColumnComponent implements AfterContentInit {
10151018
* @memberof IgxColumnComponent
10161019
*/
10171020
children: QueryList<IgxColumnComponent>;
1021+
/**
1022+
* @hidden
1023+
*/
1024+
protected destroy$ = new Subject<boolean>();
1025+
10181026
/**
10191027
*@hidden
10201028
*/
@@ -1198,7 +1206,7 @@ export class IgxColumnComponent implements AfterContentInit {
11981206
if (!col.colStart) {
11991207
return;
12001208
}
1201-
const newWidthSet = col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
1209+
const newWidthSet = col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
12021210
const newSpanSmaller = columnSizes[col.colStart - 1] && columnSizes[col.colStart - 1].colSpan > col.gridColumnSpan;
12031211
const bothWidthsSet = col.widthSetByUser && columnSizes[col.colStart - 1] && columnSizes[col.colStart - 1].widthSetByUser;
12041212
const bothWidthsNotSet = !col.widthSetByUser && columnSizes[col.colStart - 1] && !columnSizes[col.colStart - 1].widthSetByUser;
@@ -1270,8 +1278,8 @@ export class IgxColumnComponent implements AfterContentInit {
12701278
for (; j < columnSizes[i].colSpan && i + j + 1 < columnSizes[i].colEnd; j++) {
12711279
if (columnSizes[i + j] &&
12721280
((!columnSizes[i].width && columnSizes[i + j].width) ||
1273-
(!columnSizes[i].width && !columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan) ||
1274-
(!!columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan))) {
1281+
(!columnSizes[i].width && !columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan) ||
1282+
(!!columnSizes[i + j].width && columnSizes[i + j].colSpan <= columnSizes[i].colSpan))) {
12751283
// If we reach an already defined column that has width and the current doesn't have or
12761284
// if the reached column has bigger colSpan we stop.
12771285
break;
@@ -1319,8 +1327,8 @@ export class IgxColumnComponent implements AfterContentInit {
13191327
}
13201328

13211329
protected getColumnSizesString(children: QueryList<IgxColumnComponent>): string {
1322-
const res = this.getFilledChildColumnSizes(children);
1323-
return res.join(' ');
1330+
const res = this.getFilledChildColumnSizes(children);
1331+
return res.join(' ');
13241332
}
13251333

13261334
public getResizableColUnderEnd(): MRLResizeColumnInfo[] {
@@ -1334,7 +1342,7 @@ export class IgxColumnComponent implements AfterContentInit {
13341342

13351343
for (let i = 0; i < columnSized.length; i++) {
13361344
if (this.colStart <= i + 1 && i + 1 < colEnd) {
1337-
targets.push({ target: columnSized[i].ref, spanUsed: 1});
1345+
targets.push({ target: columnSized[i].ref, spanUsed: 1 });
13381346
}
13391347
}
13401348

@@ -1414,7 +1422,7 @@ export class IgxColumnComponent implements AfterContentInit {
14141422
grid.resetCaches();
14151423
grid.notifyChanges();
14161424
if (this.columnLayoutChild) {
1417-
this.grid.columns.filter(x => x.columnLayout).forEach( x => x.populateVisibleIndexes());
1425+
this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes());
14181426
}
14191427
this.grid.filteringService.refreshExpressions();
14201428
// this.grid.refreshSearch(true);
@@ -1478,7 +1486,7 @@ export class IgxColumnComponent implements AfterContentInit {
14781486

14791487
grid.notifyChanges();
14801488
if (this.columnLayoutChild) {
1481-
this.grid.columns.filter(x => x.columnLayout).forEach( x => x.populateVisibleIndexes());
1489+
this.grid.columns.filter(x => x.columnLayout).forEach(x => x.populateVisibleIndexes());
14821490
}
14831491
this.grid.filteringService.refreshExpressions();
14841492
// this.grid.refreshSearch(true);
@@ -1678,6 +1686,14 @@ export class IgxColumnComponent implements AfterContentInit {
16781686
* @hidden
16791687
*/
16801688
public populateVisibleIndexes() { }
1689+
1690+
/**
1691+
* @hidden
1692+
*/
1693+
public ngOnDestroy() {
1694+
this.destroy$.next(true);
1695+
this.destroy$.complete();
1696+
}
16811697
}
16821698

16831699

@@ -1687,8 +1703,7 @@ export class IgxColumnComponent implements AfterContentInit {
16871703
selector: 'igx-column-group',
16881704
template: ``
16891705
})
1690-
export class IgxColumnGroupComponent extends IgxColumnComponent implements AfterContentInit {
1691-
1706+
export class IgxColumnGroupComponent extends IgxColumnComponent implements AfterContentInit, OnDestroy {
16921707
@ContentChildren(IgxColumnComponent, { read: IgxColumnComponent })
16931708
children = new QueryList<IgxColumnComponent>();
16941709
/**
@@ -1832,7 +1847,21 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18321847
this.children.forEach(child => {
18331848
child.parent = this;
18341849
});
1850+
/*
1851+
TO DO: In Angular 9 this need to be removed, because the @ContentChildren will not return the `parent`
1852+
component in the query list.
1853+
*/
1854+
this.children.changes.pipe(takeUntil(this.destroy$))
1855+
.subscribe((change) => {
1856+
if (change.length > 1 && change.first === this) {
1857+
this.children.reset(this.children.toArray().slice(1));
1858+
this.children.forEach(child => {
1859+
child.parent = this;
1860+
});
1861+
}
1862+
});
18351863
}
1864+
18361865
/**
18371866
* Returns the children columns collection.
18381867
* ```typescript
@@ -1877,7 +1906,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18771906
return acc;
18781907
}
18791908
if (typeof val.width === 'string' && val.width.indexOf('%') !== -1) {
1880-
isChildrenWidthInPercent = true;
1909+
isChildrenWidthInPercent = true;
18811910
}
18821911
return acc + parseInt(val.width, 10);
18831912
}, 0)}`;
@@ -1898,7 +1927,7 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
18981927
selector: 'igx-column-layout',
18991928
template: ``
19001929
})
1901-
export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements AfterContentInit {
1930+
export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements AfterContentInit, OnDestroy {
19021931
public childrenVisibleIndexes = [];
19031932
/**
19041933
* Gets the width of the column layout.
@@ -1983,7 +2012,7 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements
19832012
this.children.forEach(child => child.hidden = value);
19842013
if (this.grid && this.grid.columns && this.grid.columns.length > 0) {
19852014
// reset indexes in case columns are hidden/shown runtime
1986-
this.grid.columns.filter(x => x.columnGroup).forEach( x => x.populateVisibleIndexes());
2015+
this.grid.columns.filter(x => x.columnGroup).forEach(x => x.populateVisibleIndexes());
19872016
}
19882017
}
19892018

@@ -2022,17 +2051,16 @@ export class IgxColumnLayoutComponent extends IgxColumnGroupComponent implements
20222051
const grid = this.gridAPI.grid;
20232052
const columns = grid && grid.pinnedColumns && grid.unpinnedColumns ? grid.pinnedColumns.concat(grid.unpinnedColumns) : [];
20242053
const orderedCols = columns
2025-
.filter(x => !x.columnGroup && !x.hidden)
2026-
.sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent) - columns.indexOf(b.parent) || a.colStart - b.colStart);
2054+
.filter(x => !x.columnGroup && !x.hidden)
2055+
.sort((a, b) => a.rowStart - b.rowStart || columns.indexOf(a.parent) - columns.indexOf(b.parent) || a.colStart - b.colStart);
20272056
this.children.forEach(child => {
20282057
const rs = child.rowStart || 1;
20292058
let vIndex = 0;
20302059
// filter out all cols with larger rowStart
20312060
const cols = orderedCols.filter(c =>
20322061
!c.columnGroup && (c.rowStart || 1) <= rs);
20332062
vIndex = cols.indexOf(child);
2034-
this.childrenVisibleIndexes.push({column: child, index: vIndex});
2063+
this.childrenVisibleIndexes.push({ column: child, index: vIndex });
20352064
});
20362065
}
2037-
20382066
}

projects/igniteui-angular/src/lib/grids/filtering/excel-style/grid.excel-style-filtering.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import {
1414
import {
1515
HorizontalAlignment,
1616
VerticalAlignment,
17-
ConnectedPositioningStrategy,
1817
OverlaySettings,
1918
IgxOverlayService,
20-
AbsoluteScrollStrategy
19+
AbsoluteScrollStrategy,
20+
AutoPositionStrategy
2121
} from '../../../services/index';
2222
import { IgxFilteringService, ExpressionUI } from '../grid-filtering.service';
2323
import {
@@ -114,7 +114,7 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, OnInit, A
114114
private _subMenuOverlaySettings: OverlaySettings = {
115115
closeOnOutsideClick: true,
116116
modal: false,
117-
positionStrategy: new ConnectedPositioningStrategy(this._subMenuPositionSettings),
117+
positionStrategy: new AutoPositionStrategy(this._subMenuPositionSettings),
118118
scrollStrategy: new AbsoluteScrollStrategy()
119119
};
120120

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,39 @@ describe('IgxGrid - multi-column headers #grid', () => {
15531553
expect(firstColumnGroup.header).toEqual(expectedColumnName);
15541554
expect(expectedColumnListLength).toEqual(columnLength);
15551555
});
1556+
1557+
it('There shouldn\'t be any errors when dynamically removing or adding a column in column group', () => {
1558+
const fixture = TestBed.createComponent(DynamicColGroupsGridComponent);
1559+
fixture.detectChanges();
1560+
1561+
const grid = fixture.componentInstance.grid;
1562+
1563+
expect(grid.columnList.length).toEqual(10);
1564+
1565+
expect(() => {
1566+
// Delete column
1567+
fixture.componentInstance.columnGroups[0].columns.splice(0, 1);
1568+
fixture.detectChanges();
1569+
}).not.toThrow();
1570+
1571+
expect(grid.columnList.length).toEqual(9);
1572+
1573+
expect(() => {
1574+
// Add column
1575+
fixture.componentInstance.columnGroups[0].columns.push({ field: 'Fax', type: 'string' });
1576+
fixture.detectChanges();
1577+
}).not.toThrow();
1578+
1579+
expect(grid.columnList.length).toEqual(10);
1580+
1581+
expect(() => {
1582+
// Update column
1583+
fixture.componentInstance.columnGroups[0].columns[1] = { field: 'City', type: 'string' };
1584+
fixture.detectChanges();
1585+
}).not.toThrow();
1586+
1587+
expect(grid.columnList.length).toEqual(10);
1588+
});
15561589
});
15571590

15581591
@Component({

projects/igniteui-angular/src/lib/slider/slider.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<igx-thumb-label
77
*ngIf="isRange"
88
[type]="0"
9-
[value]="value"
9+
[value]="lowerLabel"
1010
[templateRef]="thumbFromTemplateRef"
1111
[continuous]="continuous"
1212
[context]="context"></igx-thumb-label>
@@ -27,7 +27,7 @@
2727
[thumbLabelVisibilityDuration]="thumbLabelVisibilityDuration"></igx-thumb>
2828

2929
<igx-thumb-label
30-
[value]="value"
30+
[value]="upperLabel"
3131
[type]="1"
3232
[templateRef]="thumbToTemplateRef"
3333
[continuous]="continuous"

0 commit comments

Comments
 (0)