Skip to content

Commit 646b964

Browse files
committed
chore(combo): fix combo provider error, update combo tests
1 parent 4b8ee7d commit 646b964

File tree

4 files changed

+43
-104
lines changed

4 files changed

+43
-104
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
@@ -42,7 +42,7 @@
4242
<div #dropdownItemContainer class="igx-combo__content" [style.overflow]="'hidden'"
4343
[style.maxHeight.px]="itemsMaxHeight" [igxDropDownItemNavigation]="dropdown" (focus)="dropdown.onFocus()"
4444
[tabindex]="dropdown.collapsed ? -1 : 0" role="listbox" [attr.id]="dropdown.id">
45-
<igx-combo-item *igxFor="let item of data | comboFiltering:filteringExpressions:filteringLogic
45+
<igx-combo-item *igxFor="let item of data | comboFiltering:searchValue:displayKey
4646
| comboSorting:sortingExpressions
4747
| comboGrouping:groupKey:valueKey;
4848
index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight"

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { IgxDropDownItemBaseDirective } from '../drop-down/drop-down-item.base';
1818
import { DisplayDensity, DisplayDensityToken } from '../core/density';
1919
import { AbsoluteScrollStrategy, ConnectedPositioningStrategy } from '../services/index';
2020
import { IgxInputState } from '../directives/input/input.directive';
21+
import { IgxComboFilteringPipe } from './combo.pipes';
2122

2223
const CSS_CLASS_COMBO = 'igx-combo';
2324
const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down';
@@ -2408,12 +2409,12 @@ describe('igxCombo', () => {
24082409
expect(combo.collapsed).toBeFalsy();
24092410
expect(combo.dropdown.headers).toBeDefined();
24102411
expect(combo.dropdown.headers.length).toEqual(2);
2411-
combo.dropdown.headers[0].clicked(null);
2412+
(combo.dropdown.headers[0] as IgxComboItemComponent).clicked(null);
24122413
fix.detectChanges();
24132414

24142415
const mockObj = jasmine.createSpyObj('nativeElement', ['focus']);
24152416
spyOnProperty(combo.dropdown, 'focusedItem', 'get').and.returnValue({ element: { nativeElement: mockObj } });
2416-
combo.dropdown.headers[0].clicked(null);
2417+
(combo.dropdown.headers[0] as IgxComboItemComponent).clicked(null);
24172418
fix.detectChanges();
24182419
expect(mockObj.focus).not.toHaveBeenCalled(); // Focus only if `allowItemFocus === true`
24192420

@@ -2465,32 +2466,32 @@ describe('igxCombo', () => {
24652466
const initialData = [...combo.filteredData];
24662467
let firstFilter;
24672468
expect(combo.searchValue).toEqual('');
2468-
spyOn(combo, 'filter').and.callThrough();
2469+
const filterSpy = spyOn(IgxComboFilteringPipe.prototype, 'transform').and.callThrough();
24692470
combo.searchValue = 'New ';
24702471
combo.handleInputChange();
24712472
tick();
24722473
fix.detectChanges();
2473-
expect(combo.filter).toHaveBeenCalledTimes(1);
2474+
expect(filterSpy).toHaveBeenCalledTimes(1);
24742475
expect(combo.filteredData.length).toBeLessThan(initialData.length);
24752476
firstFilter = [...combo.filteredData];
24762477
combo.searchValue += ' ';
24772478
combo.handleInputChange();
24782479
tick();
24792480
fix.detectChanges();
24802481
expect(combo.filteredData.length).toBeLessThan(initialData.length);
2481-
expect(combo.filter).toHaveBeenCalledTimes(2);
2482+
expect(filterSpy).toHaveBeenCalledTimes(2);
24822483
combo.searchValue = '';
24832484
combo.handleInputChange();
24842485
tick();
24852486
fix.detectChanges();
24862487
expect(combo.filteredData.length).toEqual(initialData.length);
24872488
expect(combo.filteredData.length).toBeGreaterThan(firstFilter.length);
2488-
expect(combo.filter).toHaveBeenCalledTimes(3);
2489+
expect(filterSpy).toHaveBeenCalledTimes(3);
24892490
combo.filteringExpressions = [];
24902491
tick();
24912492
fix.detectChanges();
24922493
expect(combo.filteredData.length).toEqual(initialData.length);
2493-
expect(combo.filter).toHaveBeenCalledTimes(3);
2494+
expect(filterSpy).toHaveBeenCalledTimes(3);
24942495
}));
24952496
it('Should properly select/deselect filteredData', fakeAsync(() => {
24962497
const fix = TestBed.createComponent(IgxComboSampleComponent);
@@ -2502,12 +2503,12 @@ describe('igxCombo', () => {
25022503
const initialData = [...combo.filteredData];
25032504

25042505
expect(combo.searchValue).toEqual('');
2505-
spyOn(combo, 'filter').and.callThrough();
2506+
const filterSpy = spyOn(IgxComboFilteringPipe.prototype, 'transform').and.callThrough();
25062507
combo.searchValue = 'New ';
25072508
combo.handleInputChange();
25082509
tick();
25092510
fix.detectChanges();
2510-
expect(combo.filter).toHaveBeenCalledTimes(1);
2511+
expect(filterSpy).toHaveBeenCalledTimes(1);
25112512
expect(combo.filteredData.length).toBeLessThan(initialData.length);
25122513
expect(combo.filteredData.length).toEqual(4);
25132514

@@ -2564,33 +2565,33 @@ describe('igxCombo', () => {
25642565
const fix = TestBed.createComponent(IgxComboSampleComponent);
25652566
fix.detectChanges();
25662567
const combo = fix.componentInstance.combo;
2567-
spyOn(combo, 'filter');
2568+
const filterSpy = spyOn(IgxComboFilteringPipe.prototype, 'transform').and.callThrough();
25682569
spyOn(combo.onSearchInput, 'emit');
25692570

25702571
combo.handleInputChange();
25712572

25722573
fix.detectChanges();
2573-
expect(combo.filter).toHaveBeenCalledTimes(1);
2574+
expect(filterSpy).toHaveBeenCalledTimes(1);
25742575
expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(0);
25752576

25762577
combo.handleInputChange('Fake');
25772578

25782579
fix.detectChanges();
2579-
expect(combo.filter).toHaveBeenCalledTimes(2);
2580+
expect(filterSpy).toHaveBeenCalledTimes(2);
25802581
expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(1);
25812582
expect(combo.onSearchInput.emit).toHaveBeenCalledWith('Fake');
25822583

25832584
combo.handleInputChange('');
25842585
fix.detectChanges();
2585-
expect(combo.filter).toHaveBeenCalledTimes(3);
2586+
expect(filterSpy).toHaveBeenCalledTimes(3);
25862587
expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2);
25872588
expect(combo.onSearchInput.emit).toHaveBeenCalledWith('');
25882589

25892590
combo.filterable = false;
25902591
fix.detectChanges();
25912592

25922593
combo.handleInputChange();
2593-
expect(combo.filter).toHaveBeenCalledTimes(3);
2594+
expect(filterSpy).toHaveBeenCalledTimes(3);
25942595
expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2);
25952596
});
25962597
it('Should properly handle addItemToCollection calls (Complex data)', fakeAsync(() => {

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

Lines changed: 14 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -826,18 +826,18 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
826826
* let valid = this.combo.valid;
827827
* ```
828828
* */
829-
public get valid(): IgxComboState {
829+
public get valid(): IgxComboState {
830830
return this._valid;
831831
}
832832

833-
/**
834-
* Sets if control is valid, when used in a form
835-
*
836-
* ```typescript
837-
* // set
838-
* this.combo.valid = IgxComboState.INVALID;
839-
* ```
840-
*/
833+
/**
834+
* Sets if control is valid, when used in a form
835+
*
836+
* ```typescript
837+
* // set
838+
* this.combo.valid = IgxComboState.INVALID;
839+
* ```
840+
*/
841841
public set valid(valid: IgxComboState) {
842842
this._valid = valid;
843843
this.comboInput.valid = IgxInputState[IgxComboState[valid]];
@@ -1022,36 +1022,8 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
10221022
* @hidden @internal
10231023
*/
10241024
public handleInputChange(event?: string) {
1025-
let cdrFlag = false;
1026-
const vContainer = this.virtDir;
1027-
if (event !== undefined && this._prevInputValue === event) {
1028-
// Nothing has changed
1029-
return;
1030-
} else {
1031-
this._prevInputValue = event !== undefined ? event : '';
1032-
}
1033-
if (event !== undefined) {
1034-
// Do not scroll if not scrollable
1035-
if (vContainer.isScrollable()) {
1036-
vContainer.scrollTo(0);
1037-
} else {
1038-
cdrFlag = true;
1039-
}
1040-
this.onSearchInput.emit(event);
1041-
} else {
1042-
cdrFlag = true;
1043-
}
1025+
this.onSearchInput.emit(event);
10441026
if (this.filterable) {
1045-
this.filter();
1046-
// If there was no scroll before filtering, check if there is after and detect changes
1047-
if (cdrFlag) {
1048-
vContainer.onChunkLoad.pipe(take(1)).subscribe(() => {
1049-
if (vContainer.isScrollable()) {
1050-
this.cdr.detectChanges();
1051-
}
1052-
});
1053-
}
1054-
} else {
10551027
this.checkMatch();
10561028
}
10571029
}
@@ -1195,7 +1167,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
11951167
this.customValueFlag = false;
11961168
this.searchInput.nativeElement.focus();
11971169
this.dropdown.focusedItem = null;
1198-
this.handleInputChange();
1170+
this.virtDir.scrollTo(0);
11991171
}
12001172

12011173
/**
@@ -1214,35 +1186,10 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12141186
}
12151187
}
12161188

1217-
1218-
protected prepare_filtering_expression(searchVal, condition, ignoreCase, fieldName?) {
1219-
const newArray = [...this.filteringExpressions];
1220-
const expression = newArray.find((expr) => expr.fieldName === fieldName);
1221-
const newExpression = { fieldName, searchVal, condition, ignoreCase };
1222-
if (!expression) {
1223-
newArray.push(newExpression);
1224-
} else {
1225-
Object.assign(expression, newExpression);
1226-
}
1227-
if (this.groupKey) {
1228-
const expression2 = newArray.find((expr) => expr.fieldName === 'isHeader');
1229-
const headerExpression = {
1230-
fieldName: 'isHeader', searchVale: '',
1231-
condition: IgxBooleanFilteringOperand.instance().condition('true'), ignoreCase: true
1232-
};
1233-
if (!expression2) {
1234-
newArray.push(headerExpression);
1235-
} else {
1236-
Object.assign(expression2, headerExpression);
1237-
}
1238-
}
1239-
this.filteringExpressions = newArray;
1240-
}
1241-
12421189
protected onStatusChanged = () => {
12431190
if ((this.ngControl.control.touched || this.ngControl.control.dirty) &&
12441191
(this.ngControl.control.validator || this.ngControl.control.asyncValidator)) {
1245-
this.valid = this.ngControl.valid ? IgxComboState.VALID : IgxComboState.INVALID;
1192+
this.valid = this.ngControl.valid ? IgxComboState.VALID : IgxComboState.INVALID;
12461193
}
12471194
this.manageRequiredAsterisk();
12481195
}
@@ -1262,20 +1209,12 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12621209
if (this.collapsed) {
12631210
if (this.ngControl && !this.ngControl.valid) {
12641211
this.valid = IgxComboState.INVALID;
1265-
} else {
1212+
} else {
12661213
this.valid = IgxComboState.INITIAL;
1267-
}
1214+
}
12681215
}
12691216
}
12701217

1271-
/**
1272-
* @hidden @internal
1273-
*/
1274-
public filter() {
1275-
this.prepare_filtering_expression(this.searchValue.trim(), IgxStringFilteringOperand.instance().condition('contains'),
1276-
true, this.dataType === DataTypes.PRIMITIVE ? undefined : this.displayKey);
1277-
}
1278-
12791218
/**
12801219
* @hidden @internal
12811220
*/
@@ -1581,7 +1520,6 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
15811520
if (event.cancel) {
15821521
return;
15831522
}
1584-
this.handleInputChange();
15851523
}
15861524

15871525
/**

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { Pipe, PipeTransform, Inject } from '@angular/core';
22
import { cloneArray } from '../core/utils';
33
import { DataUtil } from '../data-operations/data-util';
4-
import { FilteringLogic, IFilteringExpression } from '../data-operations/filtering-expression.interface';
4+
import { IFilteringExpression } from '../data-operations/filtering-expression.interface';
55
import { ISortingExpression } from '../data-operations/sorting-expression.interface';
6-
import { IFilteringState } from '../data-operations/filtering-state.interface';
76
import { FilteringStrategy } from '../data-operations/filtering-strategy';
8-
import { FilteringExpressionsTree } from '../data-operations/filtering-expressions-tree';
97
import { IGX_COMBO_COMPONENT, IgxComboBase } from './combo.common';
108

119

@@ -16,18 +14,20 @@ import { IGX_COMBO_COMPONENT, IgxComboBase } from './combo.common';
1614
name: 'comboFiltering'
1715
})
1816
export class IgxComboFilteringPipe implements PipeTransform {
19-
public transform(collection: any[], expressions: IFilteringExpression[],
20-
logic: FilteringLogic) {
21-
const filteringExpressionsTree = new FilteringExpressionsTree(logic);
22-
filteringExpressionsTree.filteringOperands = expressions;
23-
const state: IFilteringState = { expressionsTree: filteringExpressionsTree, strategy: new SimpleFilteringStrategy()};
24-
25-
if (!state.expressionsTree.filteringOperands.length) {
17+
public transform(collection: any[], searchValue: any, displayKey: any) {
18+
if (!collection) {
19+
return [];
20+
}
21+
if (!searchValue) {
2622
return collection;
23+
} else {
24+
const searchTerm = searchValue.toLowerCase().trim();
25+
if (displayKey != null) {
26+
return collection.filter(e => e[displayKey].toLowerCase().includes(searchTerm));
27+
} else {
28+
return collection.filter(e => e.includes(searchTerm));
29+
}
2730
}
28-
29-
const result = DataUtil.filter(cloneArray(collection), state);
30-
return result;
3131
}
3232
}
3333

0 commit comments

Comments
 (0)