Skip to content

Commit e00fba3

Browse files
authored
Merge branch '15.0.x' into vkombov/fix-12391-15.0.x
2 parents 72585b8 + 5bf47c1 commit e00fba3

File tree

9 files changed

+259
-21
lines changed

9 files changed

+259
-21
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -986,12 +986,12 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
986986
});
987987
}
988988

989-
/** @hidden @internal */
990-
public ngDoCheck() {
991-
if (this.data?.length && this.selection.length) {
992-
this._value = this.createDisplayText(this.selection, []);
993-
}
989+
/** @hidden @internal */
990+
public ngDoCheck() {
991+
if (this.data?.length && this.selection.length && !this._value) {
992+
this._value = this.createDisplayText(this.selection, []);
994993
}
994+
}
995995

996996
/** @hidden @internal */
997997
public ngOnDestroy() {

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,29 @@ describe('igxCombo', () => {
22432243
const expectedOutput = 'One';
22442244
expect(input.nativeElement.value).toEqual(expectedOutput);
22452245
}));
2246+
it('should display custom displayText on selection/deselection', () => {
2247+
combo.valueKey = 'key';
2248+
combo.displayKey = 'value';
2249+
combo.data = [
2250+
{ key: 1, value: 'One' },
2251+
{ key: 2, value: 'Two' },
2252+
{ key: 3, value: 'Three' },
2253+
];
2254+
2255+
spyOn(combo.selectionChanging, 'emit').and.callFake(
2256+
(event: IComboSelectionChangingEventArgs) => event.displayText = `Selected Count: ${event.newSelection.length}`);
2257+
2258+
combo.select([1]);
2259+
fixture.detectChanges();
2260+
2261+
expect(combo.selection).toEqual([1]);
2262+
expect(combo.value).toBe('Selected Count: 1');
2263+
2264+
combo.deselect([1]);
2265+
2266+
expect(combo.selection).toEqual([]);
2267+
expect(combo.value).toBe('Selected Count: 0');
2268+
});
22462269
});
22472270
describe('Grouping tests: ', () => {
22482271
configureTestSuite();

projects/igniteui-angular/src/lib/core/styles/themes/generators/_bootstrap.scss

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
$primary: color($palette, 'primary');
1717
$secondary: color($palette, 'secondary');
1818
$surface: color($palette, 'surface');
19+
$info: color($palette, 'info');
20+
$success: color($palette, 'success');
21+
$warn: color($palette, 'warn');
22+
$error: color($palette, 'error');
1923

2024
@include theme(
2125
$palette: palette(
2226
$primary,
2327
$secondary,
2428
$surface: if($surface != #f8f9fa, $surface, #f8f9fa),
25-
$gray: #212529
29+
$gray: #212529,
30+
$info: $info,
31+
$success: $success,
32+
$warn: $warn,
33+
$error: $error
2634
),
2735
$schema: $light-bootstrap-schema,
2836
$exclude: $exclude,
@@ -45,13 +53,21 @@
4553
$primary: color($palette, 'primary');
4654
$secondary: color($palette, 'secondary');
4755
$surface: color($palette, 'surface');
56+
$info: color($palette, 'info');
57+
$success: color($palette, 'success');
58+
$warn: color($palette, 'warn');
59+
$error: color($palette, 'error');
4860

4961
@include theme(
5062
$palette: palette(
5163
$primary,
5264
$secondary,
5365
$surface: if($surface != white, $surface, #222),
54-
$gray: #fff
66+
$gray: #fff,
67+
$info: $info,
68+
$success: $success,
69+
$warn: $warn,
70+
$error: $error
5571
),
5672
$schema: $dark-bootstrap-schema,
5773
$exclude: $exclude,

projects/igniteui-angular/src/lib/core/styles/themes/generators/_fluent.scss

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
$primary: color($palette, 'primary');
1717
$secondary: color($palette, 'secondary');
1818
$surface: color($palette, 'surface');
19+
$info: color($palette, 'info');
20+
$success: color($palette, 'success');
21+
$warn: color($palette, 'warn');
22+
$error: color($palette, 'error');
1923

2024
@include theme(
2125
$palette: palette(
2226
$primary,
2327
$secondary,
2428
$surface: if($surface != #fff, $surface, #fff),
25-
$gray: #000
29+
$gray: #000,
30+
$info: $info,
31+
$success: $success,
32+
$warn: $warn,
33+
$error: $error
2634
),
2735
$schema: $light-fluent-schema,
2836
$exclude: $exclude,
@@ -45,13 +53,21 @@
4553
$primary: color($palette, 'primary');
4654
$secondary: color($palette, 'secondary');
4755
$surface: color($palette, 'surface');
56+
$info: color($palette, 'info');
57+
$success: color($palette, 'success');
58+
$warn: color($palette, 'warn');
59+
$error: color($palette, 'error');
4860

4961
@include theme(
5062
$palette: palette(
5163
$primary,
5264
$secondary,
5365
$surface: if($surface != #fff, $surface, #222),
54-
$gray: #fff
66+
$gray: #fff,
67+
$info: $info,
68+
$success: $success,
69+
$warn: $warn,
70+
$error: $error
5571
),
5672
$schema: $dark-fluent-schema,
5773
$exclude: $exclude,

projects/igniteui-angular/src/lib/core/styles/themes/generators/_indigo.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
$primary: color($palette, 'primary');
1717
$secondary: color($palette, 'secondary');
1818
$surface: color($palette, 'surface');
19+
$info: color($palette, 'info');
20+
$success: color($palette, 'success');
21+
$warn: color($palette, 'warn');
22+
$error: color($palette, 'error');
1923

2024
@include theme(
2125
$palette: palette(
2226
$primary,
2327
$secondary,
2428
$surface: if($surface != #fff, $surface, #fff),
2529
$gray: #060716,
30+
$info: $info,
31+
$success: $success,
32+
$warn: $warn,
33+
$error: $error
2634
),
2735
$schema: $light-indigo-schema,
2836
$exclude: $exclude,
@@ -45,13 +53,21 @@
4553
$primary: color($palette, 'primary');
4654
$secondary: color($palette, 'secondary');
4755
$surface: color($palette, 'surface');
56+
$info: color($palette, 'info');
57+
$success: color($palette, 'success');
58+
$warn: color($palette, 'warn');
59+
$error: color($palette, 'error');
4860

4961
@include theme(
5062
$palette: palette(
5163
$primary,
5264
$secondary,
5365
$surface: if($surface != white, $surface, #2a2b2f),
54-
$gray: #fff
66+
$gray: #fff,
67+
$info: $info,
68+
$success: $success,
69+
$warn: $warn,
70+
$error: $error
5571
),
5672
$schema: $dark-indigo-schema,
5773
$exclude: $exclude,

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

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('IgxSimpleCombo', () => {
5353
let fixture: ComponentFixture<any>;
5454
let combo: IgxSimpleComboComponent;
5555
let input: DebugElement;
56-
56+
5757
configureTestSuite();
5858

5959
describe('Unit tests: ', () => {
@@ -1291,7 +1291,7 @@ describe('IgxSimpleCombo', () => {
12911291

12921292
expect(toggleIcon.nativeElement.textContent).toBe('search');
12931293
expect(combo.collapsed).toBeTruthy();
1294-
1294+
12951295
toggleIcon.nativeElement.click();
12961296
tick();
12971297
fixture.detectChanges();
@@ -1304,6 +1304,20 @@ describe('IgxSimpleCombo', () => {
13041304

13051305
expect(combo.collapsed).toBeTruthy();
13061306
}));
1307+
1308+
it('should clear the selection when typing in the input', () => {
1309+
combo.select('Wisconsin');
1310+
fixture.detectChanges();
1311+
1312+
expect(combo.selection.length).toEqual(1);
1313+
1314+
input.triggerEventHandler('focus', {});
1315+
fixture.detectChanges();
1316+
1317+
UIInteractions.simulateTyping('L', input, 9, 10);
1318+
fixture.detectChanges();
1319+
expect(combo.selection.length).toEqual(0);
1320+
});
13071321
});
13081322

13091323
describe('Display density', () => {
@@ -1783,6 +1797,7 @@ describe('IgxSimpleCombo', () => {
17831797
fixture = TestBed.createComponent(IgxComboRemoteDataComponent);
17841798
fixture.detectChanges();
17851799
combo = fixture.componentInstance.instance;
1800+
input = fixture.debugElement.query(By.css(`.${CSS_CLASS_COMBO_INPUTGROUP}`));
17861801
});
17871802
it('should prevent registration of remote entries when selectionChanging is cancelled', () => {
17881803
spyOn(combo.selectionChanging, 'emit').and.callFake((event: IComboSelectionChangingEventArgs) => event.cancel = true);
@@ -1807,6 +1822,29 @@ describe('IgxSimpleCombo', () => {
18071822
const expectedOutput = 'One';
18081823
expect(input.nativeElement.value).toEqual(expectedOutput);
18091824
}));
1825+
it('should not clear selection when bound to remote data and item is out of view', (async () => {
1826+
expect(combo.valueKey).toBeDefined();
1827+
expect(combo.selection.length).toEqual(0);
1828+
1829+
let selectedItem = combo.data[1];
1830+
combo.toggle();
1831+
combo.select(combo.data[1][combo.valueKey]);
1832+
1833+
// Scroll selected item out of view
1834+
combo.virtualScrollContainer.scrollTo(40);
1835+
await wait();
1836+
fixture.detectChanges();
1837+
1838+
input.nativeElement.focus();
1839+
fixture.detectChanges();
1840+
1841+
UIInteractions.triggerEventHandlerKeyDown('Tab', input);
1842+
fixture.detectChanges();
1843+
1844+
expect(combo.selection.length).toEqual(1);
1845+
expect(combo.value).toEqual(`${selectedItem[combo.displayKey]}`);
1846+
expect(combo.selection).toEqual([selectedItem[combo.valueKey]]);
1847+
}));
18101848
});
18111849
});
18121850

@@ -1898,8 +1936,8 @@ export class IgxSimpleComboIconTemplatesComponent {
18981936
public combo: IgxSimpleComboComponent;
18991937

19001938
public data: any[] = [
1901-
{ name: 'Sofia', id: '1' },
1902-
{ name: 'London', id: '2' },
1939+
{ name: 'Sofia', id: '1' },
1940+
{ name: 'London', id: '2' },
19031941
];;
19041942
public name!: string;
19051943
}

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
261261
this.clearSelection();
262262
this._onChangeCallback(null);
263263
}
264+
if (this.selection.length) {
265+
this.selectionService.clear(this.id);
266+
}
264267
// when filtering the focused item should be the first item or the currently selected item
265268
if (!this.dropdown.focusedItem || this.dropdown.focusedItem.id !== this.dropdown.items[0].id) {
266269
this.dropdown.navigateFirst();
@@ -464,6 +467,28 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
464467
return newSelection[0]?.toString() || '';
465468
}
466469

470+
protected getRemoteSelection(newSelection: any[], oldSelection: any[]): string {
471+
if (!newSelection.length) {
472+
this.registerRemoteEntries(oldSelection, false);
473+
return '';
474+
}
475+
476+
this.registerRemoteEntries(oldSelection, false);
477+
this.registerRemoteEntries(newSelection);
478+
return Object.keys(this._remoteSelection).map(e => this._remoteSelection[e])[0];
479+
}
480+
481+
/** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */
482+
protected registerRemoteEntries(ids: any[], add = true) {
483+
const selection = this.getValueDisplayPairs(ids)[0];
484+
485+
if (add && selection) {
486+
this._remoteSelection[selection[this.valueKey]] = selection[this.displayKey].toString();
487+
} else {
488+
delete this._remoteSelection[ids[0]];
489+
}
490+
}
491+
467492
private clearSelection(ignoreFilter?: boolean): void {
468493
let newSelection = this.selectionService.get_empty();
469494
if (this.filteredData.length !== this.data.length && !ignoreFilter) {
@@ -473,11 +498,19 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
473498
}
474499

475500
private clearOnBlur(): void {
501+
if (this.isRemote) {
502+
const searchValue = this.searchValue || this.comboInput.value;
503+
const remoteValue = Object.keys(this._remoteSelection).map(e => this._remoteSelection[e])[0];
504+
if (remoteValue && searchValue !== remoteValue) {
505+
this.clear();
506+
}
507+
return;
508+
}
509+
476510
const filtered = this.filteredData.find(this.findMatch);
477511
// selecting null in primitive data returns undefined as the search text is '', but the item is null
478512
if (filtered === undefined && this.selectedItem !== null || !this.selection.length) {
479513
this.clear();
480-
return;
481514
}
482515
}
483516

@@ -488,8 +521,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
488521

489522
private clear(): void {
490523
this.clearSelection(true);
491-
this._internalFilter = '';
492-
this.searchValue = '';
524+
this.comboInput.value = this._internalFilter = this._value = this.searchValue = '';
493525
}
494526

495527
private isValid(value: any): boolean {

src/app/combo/combo.sample.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,22 @@ <h5 class="sample-title">Reactive Form</h5>
6868
<div>
6969
<h5 class="sample-title">Remote Binding</h5>
7070
<igx-combo #remoteCombo class="input-container" [itemsMaxHeight]="250" [itemHeight]="48"
71-
[data]="rData | async" [valueKey]="'ProductID'" [displayKey]="'ProductName'"
71+
[data]="rData | async" [valueKey]="'ProductID'" [displayKey]="'ProductName'" placeholder="Product(s)"
7272
(dataPreLoad)="dataLoading()" (searchInputUpdate)="searchInput($event)"
7373
(selectionChanging)="handleSelectionChanging($event)" (closing)="onClosing()"
74-
(opening)="onOpening()" placeholder="Location(s)">
74+
(opening)="onOpening()">
75+
<label igxLabel>Combo</label>
7576
</igx-combo>
7677
<igx-toast #loadingToast></igx-toast>
7778

79+
<igx-simple-combo #remoteSimpleCombo class="input-container" [itemsMaxHeight]="250" [itemHeight]="48"
80+
[data]="rData | async" [valueKey]="'ProductID'" [displayKey]="'ProductName'" placeholder="Product"
81+
(dataPreLoad)="onSimpleComboDataLoading()" (closing)="onSimpleComboClosing()"
82+
(opened)="onSimpleComboOpened()" (closed)="onSimpleComboClosed()"
83+
(selectionChanging)="onSimpleComboSelectionChanging($event)"
84+
(searchInputUpdate)="onSimpleComboSearchInputUpdate($event)">
85+
<label igxLabel>Simple Combo</label>
86+
</igx-simple-combo>
7887
</div>
7988

8089
<div class="input-row">

0 commit comments

Comments
 (0)