Skip to content

Commit 22bc8dd

Browse files
authored
Merge branch '10.1.x' into ibarakov/fix-7090-10.1.x
2 parents 2330852 + 4bf4d37 commit 22bc8dd

File tree

6 files changed

+97
-43
lines changed

6 files changed

+97
-43
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<ng-content select="igx-hint, [igxHint]"></ng-content>
1010
</ng-container>
1111
<input igxInput #comboInput name="comboInput" type="text" [value]="value" readonly [attr.placeholder]="placeholder"
12-
[disabled]="disabled" (blur)="onBlur()" (focus)="onFocus()" />
12+
[disabled]="disabled" (blur)="onBlur()" />
1313
<ng-container ngProjectAs="igx-suffix">
1414
<ng-content select="igx-suffix"></ng-content>
1515
</ng-container>

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

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { AfterViewInit, ChangeDetectorRef, Component, Injectable, OnInit, ViewChild, OnDestroy, DebugElement } from '@angular/core';
2-
import { async, TestBed, tick, fakeAsync } from '@angular/core/testing';
2+
import { async, TestBed, tick, fakeAsync, ComponentFixture } from '@angular/core/testing';
33
import { By } from '@angular/platform-browser';
44
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
5-
import { FormGroup, FormControl, Validators, FormBuilder, ReactiveFormsModule, FormsModule, NgControl } from '@angular/forms';
5+
import { FormGroup, FormControl, Validators, FormBuilder, ReactiveFormsModule, FormsModule, NgControl, NgModel } from '@angular/forms';
66
import { IgxComboComponent, IgxComboModule, IComboSelectionChangeEventArgs, IgxComboState, IComboSearchInputEventArgs } from './combo.component';
77
import { IgxComboItemComponent } from './combo-item.component';
88
import { IgxComboDropDownComponent } from './combo-dropdown.component';
@@ -60,7 +60,7 @@ const defaultDropdownItemHeight = 40;
6060
const defaultDropdownItemMaxHeight = 400;
6161

6262
describe('igxCombo', () => {
63-
let fixture;
63+
let fixture: ComponentFixture<any>;
6464
let combo: IgxComboComponent;
6565
let input: DebugElement;
6666

@@ -97,12 +97,10 @@ describe('igxCombo', () => {
9797

9898
// writeValue
9999
expect(combo.value).toBe('');
100-
mockSelection.add_items.and.returnValue(new Set(['test']));
100+
mockSelection.get.and.returnValue(new Set(['test']));
101101
spyOnProperty(combo, 'isRemote').and.returnValue(false);
102102
combo.writeValue(['test']);
103-
// TODO: Uncomment after fix for write value going through entire selection process
104-
// expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled();
105-
expect(mockSelection.add_items).toHaveBeenCalledWith(combo.id, ['test'], true);
103+
expect(mockNgControl.registerOnChangeCb).not.toHaveBeenCalled();
106104
expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['test'], true);
107105
expect(combo.value).toBe('test');
108106

@@ -123,11 +121,8 @@ describe('igxCombo', () => {
123121
spyOnProperty(combo, 'collapsed').and.returnValue(true);
124122
spyOnProperty(combo, 'valid', 'set');
125123

126-
combo.onFocus();
127-
expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1);
128-
129124
combo.onBlur();
130-
expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(2);
125+
expect(mockNgControl.registerOnTouchedCb).toHaveBeenCalledTimes(1);
131126
});
132127
it('should correctly handle ngControl validity', () => {
133128
pending('Convert existing form test here');
@@ -207,17 +202,18 @@ describe('igxCombo', () => {
207202
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
208203
combo.ngOnInit();
209204
combo.data = data;
210-
spyOn(combo, 'selectItems');
205+
mockSelection.select_items.calls.reset();
206+
spyOnProperty(combo, 'isRemote').and.returnValue(false);
211207
combo.writeValue(['EXAMPLE']);
212-
expect(combo.selectItems).toHaveBeenCalledTimes(1);
208+
expect(mockSelection.select_items).toHaveBeenCalledTimes(1);
213209

214-
// Calling "SelectItems" through the writeValue accessor should clear the previous values;
210+
// Calling "select_items" through the writeValue accessor should clear the previous values;
215211
// Select items is called with the invalid value and it is written in selection, though no item is selected
216212
// Controlling the selection is up to the user
217-
expect(combo.selectItems).toHaveBeenCalledWith(['EXAMPLE'], true);
213+
expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, ['EXAMPLE'], true);
218214
combo.writeValue(combo.data[0]);
219215
// When value key is specified, the item's value key is stored in the selection
220-
expect(combo.selectItems).toHaveBeenCalledWith(combo.data[0], true);
216+
expect(mockSelection.select_items).toHaveBeenCalledWith(combo.id, [], true);
221217
});
222218
it('should select items through setSelctedItem method', () => {
223219
const selectionService = new IgxSelectionAPIService();
@@ -2632,6 +2628,7 @@ describe('igxCombo', () => {
26322628
expect(combo.valid).toEqual(IgxComboState.INVALID);
26332629
expect(combo.comboInput.valid).toEqual(IgxInputState.INVALID);
26342630

2631+
input.triggerEventHandler('focus', {});
26352632
combo.selectAllItems();
26362633
fixture.detectChanges();
26372634
expect(combo.valid).toEqual(IgxComboState.VALID);
@@ -2643,17 +2640,72 @@ describe('igxCombo', () => {
26432640
expect(combo.valid).toEqual(IgxComboState.INVALID);
26442641
expect(combo.comboInput.valid).toEqual(IgxInputState.INVALID);
26452642
});
2646-
it('should have correctly bound focus and blur handlers', () => {
2647-
spyOn(combo, 'onFocus');
2648-
spyOn(combo, 'onBlur');
2643+
it('should properly init with empty array and handle consecutive model changes', fakeAsync(() => {
2644+
const model = fixture.debugElement.query(By.directive(NgModel)).injector.get(NgModel);
2645+
fixture.componentInstance.values = [];
2646+
fixture.detectChanges();
2647+
tick();
2648+
expect(combo.valid).toEqual(IgxComboState.INITIAL);
2649+
expect(combo.comboInput.valid).toEqual(IgxInputState.INITIAL);
2650+
expect(model.valid).toBeFalse();
2651+
expect(model.dirty).toBeFalse();
2652+
expect(model.touched).toBeFalse();
26492653

2650-
input.triggerEventHandler('focus', {});
2651-
expect(combo.onFocus).toHaveBeenCalled();
2652-
expect(combo.onFocus).toHaveBeenCalledWith();
2654+
fixture.componentInstance.values = ['Missouri'];
2655+
fixture.detectChanges();
2656+
tick();
2657+
expect(combo.valid).toEqual(IgxComboState.INITIAL);
2658+
expect(combo.comboInput.valid).toEqual(IgxInputState.INITIAL);
2659+
expect(combo.selectedItems()).toEqual(['Missouri']);
2660+
expect(combo.value).toEqual('Missouri');
2661+
expect(model.valid).toBeTrue();
2662+
expect(model.touched).toBeFalse();
2663+
2664+
fixture.componentInstance.values = ['Missouri', 'Missouri'];
2665+
fixture.detectChanges();
2666+
expect(combo.valid).toEqual(IgxComboState.INITIAL);
2667+
expect(combo.comboInput.valid).toEqual(IgxInputState.INITIAL);
2668+
expect(combo.selectedItems()).toEqual(['Missouri']);
2669+
expect(combo.value).toEqual('Missouri');
2670+
expect(model.valid).toBeTrue();
2671+
expect(model.touched).toBeFalse();
2672+
2673+
fixture.componentInstance.values = null;
2674+
fixture.detectChanges();
2675+
tick();
2676+
expect(combo.valid).toEqual(IgxComboState.INITIAL);
2677+
expect(combo.comboInput.valid).toEqual(IgxInputState.INITIAL);
2678+
expect(combo.selectedItems()).toEqual([]);
2679+
expect(combo.value).toEqual('');
2680+
expect(model.valid).toBeFalse();
2681+
expect(model.touched).toBeFalse();
2682+
expect(model.dirty).toBeFalse();
2683+
2684+
combo.onBlur();
2685+
fixture.detectChanges();
2686+
expect(combo.valid).toEqual(IgxComboState.INVALID);
2687+
expect(combo.comboInput.valid).toEqual(IgxInputState.INVALID);
2688+
expect(model.valid).toBeFalse();
2689+
expect(model.touched).toBeTrue();
2690+
expect(model.dirty).toBeFalse();
2691+
2692+
fixture.componentInstance.values = ['New Jersey'];
2693+
fixture.detectChanges();
2694+
tick();
2695+
expect(combo.valid).toEqual(IgxComboState.INITIAL);
2696+
expect(combo.comboInput.valid).toEqual(IgxInputState.INITIAL);
2697+
expect(combo.selectedItems()).toEqual(['New Jersey']);
2698+
expect(combo.value).toEqual('New Jersey');
2699+
expect(model.valid).toBeTrue();
2700+
expect(model.touched).toBeTrue();
2701+
expect(model.dirty).toBeFalse();
2702+
}));
2703+
it('should have correctly bound blur handler', () => {
2704+
spyOn(combo, 'onBlur');
26532705

26542706
input.triggerEventHandler('blur', {});
26552707
expect(combo.onBlur).toHaveBeenCalled();
2656-
expect(combo.onFocus).toHaveBeenCalledWith();
2708+
expect(combo.onBlur).toHaveBeenCalledWith();
26572709
});
26582710
});
26592711
});

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,11 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
11841184
protected onStatusChanged = () => {
11851185
if ((this.ngControl.control.touched || this.ngControl.control.dirty) &&
11861186
(this.ngControl.control.validator || this.ngControl.control.asyncValidator)) {
1187-
this.valid = this.ngControl.valid ? IgxComboState.VALID : IgxComboState.INVALID;
1187+
if (!this.collapsed || this.inputGroup.isFocused) {
1188+
this.valid = this.ngControl.valid ? IgxComboState.VALID : IgxComboState.INVALID;
1189+
} else {
1190+
this.valid = this.ngControl.valid ? IgxComboState.INITIAL : IgxComboState.INVALID;
1191+
}
11881192
}
11891193
this.manageRequiredAsterisk();
11901194
}
@@ -1211,13 +1215,6 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12111215
}
12121216
}
12131217

1214-
/** @hidden @internal */
1215-
public onFocus() {
1216-
if (this.collapsed) {
1217-
this._onTouchedCallback();
1218-
}
1219-
}
1220-
12211218
/**
12221219
* @hidden @internal
12231220
*/
@@ -1258,8 +1255,10 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12581255
* @hidden @internal
12591256
*/
12601257
public writeValue(value: any[]): void {
1261-
this.selectItems(value, true);
1262-
this.cdr.markForCheck();
1258+
const selection = Array.isArray(value) ? value : [];
1259+
const oldSelection = this.selectedItems();
1260+
this.selection.select_items(this.id, selection, true);
1261+
this._value = this.createDisplayText(this.selectedItems(), oldSelection);
12631262
}
12641263

12651264
/**

src/app/action-strip/action-strip.sample.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ export class ActionStripSampleComponent implements OnInit {
1313
public result: string;
1414
public isVisible = false;
1515
private counter = 0;
16-
public comfortable = DisplayDensity.comfortable;
17-
public cosy = DisplayDensity.cosy;
18-
public compact = DisplayDensity.compact;
16+
public comfortable: DisplayDensity = DisplayDensity.comfortable;
17+
public cosy: DisplayDensity = DisplayDensity.cosy;
18+
public compact: DisplayDensity = DisplayDensity.compact;
1919
public displayDensity = this.comfortable;
2020

2121
data: any[];

src/app/combo/combo.sample.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
<div>
1919
<h5 class="sample-title">Template Form</h5>
2020
<form>
21-
<igx-combo class="input-container" [placeholder]="'Locations'" name="anyName" required
22-
[(ngModel)]="values1" [ngModelOptions]="{ updateOn: 'blur' }" #comboModel="ngModel"
21+
<igx-combo class="input-container" [placeholder]="'Locations'" name="anyName" #comboModel="ngModel"
22+
[(ngModel)]="values1" [ngModelOptions]="{ updateOn: 'blur' }" minlength="2" required
2323
[data]="items" [filterable]="filterableFlag" [displayKey]="valueKeyVar"
2424
[valueKey]="valueKeyVar" [groupKey]="valueKeyVar ? 'region' : ''" [width]="'100%'">
25+
<label igxLabel>States</label>
2526
<igx-hint>Please select the states you've visited</igx-hint>
2627
</igx-combo>
2728
</form>
29+
<button igxButton (click)="values1 = values1.concat(['Missouri'])">Add Missouri</button>
30+
<button igxButton (click)="values1 = []">Clear values </button>
2831
</div>
2932
<div>
3033
<h5 class="sample-title">Reactive Form</h5>

src/app/combo/combo.sample.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export class ComboSampleComponent implements OnInit, AfterViewInit {
4444
public customValuesFlag = true;
4545
public autoFocusSearch = true;
4646
public items: any[] = [];
47-
public values1: Array<any>;
47+
public values1: Array<any> = ['Arizona'];
4848
public values2: Array<any>;
4949

5050
public valueKeyVar = 'field';
@@ -53,9 +53,9 @@ export class ComboSampleComponent implements OnInit, AfterViewInit {
5353
private customItemTemplate;
5454
private initialItemTemplate: TemplateRef<any> = null;
5555

56-
comfortable = DisplayDensity.comfortable;
57-
cosy = DisplayDensity.cosy;
58-
compact = DisplayDensity.compact;
56+
public comfortable: DisplayDensity = DisplayDensity.comfortable;
57+
public cosy: DisplayDensity = DisplayDensity.cosy;
58+
public compact: DisplayDensity = DisplayDensity.compact;
5959

6060
public genres = [];
6161
public user: FormGroup;

0 commit comments

Comments
 (0)