Skip to content

Commit 6e36901

Browse files
refactor(combo.common): update common API
1 parent 92f9f1b commit 6e36901

File tree

6 files changed

+136
-107
lines changed

6 files changed

+136
-107
lines changed

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

Lines changed: 49 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
250250
* ```
251251
*/
252252
@Input()
253-
public placeholder;
253+
public placeholder: string;
254254

255255
/**
256256
* Combo data source.
@@ -335,15 +335,6 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
335335
return this._groupKey;
336336
}
337337

338-
/**
339-
* An @Input property that enabled/disables filtering in the list. The default is `true`.
340-
* ```html
341-
* <igx-combo [filterable]="false">
342-
* ```
343-
*/
344-
@Input()
345-
public filterable = true;
346-
347338
/**
348339
* An @Input property that sets groups sorting order.
349340
*
@@ -712,22 +703,6 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
712703
@ViewChild('complex', { read: TemplateRef, static: true })
713704
protected complexTemplate: TemplateRef<any>;
714705

715-
/** @hidden @internal */
716-
public get displaySearchInput(): boolean {
717-
return this.filterable || this.allowCustomValues;
718-
}
719-
720-
/** @hidden @internal */
721-
public get filteredData(): any[] | null {
722-
return this.filterable ? this._filteredData : this.data;
723-
}
724-
725-
/** @hidden @internal */
726-
public set filteredData(val: any[] | null) {
727-
this._filteredData = this.groupKey ? (val || []).filter((e) => e.isHeader !== true) : val;
728-
this.checkMatch();
729-
}
730-
731706
/** @hidden @internal */
732707
public get searchValue(): string {
733708
return this._searchValue;
@@ -789,6 +764,29 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
789764
return this._value;
790765
}
791766

767+
/**
768+
* Defines the current state of the virtualized data. It contains `startIndex` and `chunkSize`
769+
*
770+
* ```typescript
771+
* // get
772+
* let state = this.combo.virtualizationState;
773+
* ```
774+
*/
775+
public get virtualizationState(): IForOfState {
776+
return this.virtDir.state;
777+
}
778+
/**
779+
* Sets the current state of the virtualized data.
780+
*
781+
* ```typescript
782+
* // set
783+
* this.combo.virtualizationState(state);
784+
* ```
785+
*/
786+
public set virtualizationState(state: IForOfState) {
787+
this.virtDir.state = state;
788+
}
789+
792790
/**
793791
* Gets drop down state.
794792
*
@@ -849,7 +847,9 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
849847
protected _data = [];
850848
protected _value = '';
851849
protected _groupKey = '';
850+
protected _filteredData = [];
852851
protected _displayKey: string;
852+
protected _remoteSelection = {};
853853
protected _valid = IgxComboState.INITIAL;
854854
protected ngControl: NgControl = null;
855855
protected destroy$ = new Subject<any>();
@@ -859,9 +859,7 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
859859
private _type = null;
860860
private _dataType = '';
861861
private _searchValue = '';
862-
private _filteredData = [];
863862
private _itemHeight = null;
864-
private _remoteSelection = {};
865863
private _itemsMaxHeight = null;
866864
private _overlaySettings: OverlaySettings;
867865
private _groupSortingDirection: SortingDirection = SortingDirection.Asc;
@@ -996,20 +994,6 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
996994
return this.selectionService.is_item_selected(this.id, item);
997995
}
998996

999-
/** @hidden @internal */
1000-
public focusSearchInput(opening?: boolean): void {
1001-
if (this.displaySearchInput && this.searchInput) {
1002-
this.searchInput.nativeElement.focus();
1003-
} else {
1004-
if (opening) {
1005-
this.dropdownContainer.nativeElement.focus();
1006-
} else {
1007-
this.comboInput.nativeElement.focus();
1008-
this.toggle();
1009-
}
1010-
}
1011-
}
1012-
1013997
/** @hidden @internal */
1014998
public addItemToCollection() {
1015999
if (!this.searchValue) {
@@ -1157,28 +1141,13 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
11571141
this.manageRequiredAsterisk();
11581142
};
11591143

1160-
/**
1161-
* Constructs the combo display value
1162-
* If remote, caches the key displayText
1163-
* If not, just combine the object.displayKeys
1164-
*/
1165-
protected createDisplayText(newSelection: any[], oldSelection: any[]) {
1166-
let value = '';
1167-
if (this.isRemote) {
1168-
if (newSelection.length) {
1169-
const removedItems = oldSelection.filter(e => newSelection.indexOf(e) < 0);
1170-
const addedItems = newSelection.filter(e => oldSelection.indexOf(e) < 0);
1171-
this.registerRemoteEntries(addedItems);
1172-
this.registerRemoteEntries(removedItems, false);
1173-
value = Object.keys(this._remoteSelection).map(e => this._remoteSelection[e]).join(', ');
1174-
} else {
1175-
// If new selection is empty, clear all items
1176-
this.registerRemoteEntries(oldSelection, false);
1177-
}
1178-
} else {
1179-
value = this.concatDisplayText(newSelection);
1144+
/** if there is a valueKey - map the keys to data items, else - just return the keys */
1145+
protected convertKeysToItems(keys: any[]) {
1146+
if (this.comboAPI.valueKey === null) {
1147+
return keys;
11801148
}
1181-
return value;
1149+
// map keys vs. filter data to retain the order of the selected items
1150+
return keys.map(key => this.data.find(entry => entry[this.valueKey] === key)).filter(e => e !== undefined);
11821151
}
11831152

11841153
protected checkMatch(): void {
@@ -1200,7 +1169,7 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
12001169
}
12011170

12021171
/** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */
1203-
private registerRemoteEntries(ids: any[], add = true) {
1172+
protected registerRemoteEntries(ids: any[], add = true) {
12041173
if (add) {
12051174
const selection = this.getValueDisplayPairs(ids);
12061175
for (const entry of selection) {
@@ -1216,31 +1185,31 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
12161185
/**
12171186
* For `id: any[]` returns a mapped `{ [combo.valueKey]: any, [combo.displayKey]: any }[]`
12181187
*/
1219-
private getValueDisplayPairs(ids: any[]) {
1188+
protected getValueDisplayPairs(ids: any[]) {
12201189
return this.data.filter(entry => ids.indexOf(entry[this.valueKey]) > -1).map(e => ({
12211190
[this.valueKey]: e[this.valueKey],
12221191
[this.displayKey]: e[this.displayKey]
12231192
}));
12241193
}
12251194

1226-
/** Returns a string that should be populated in the combo's text box */
1227-
private concatDisplayText(selection: any[]): string {
1228-
const value = this.displayKey !== null && this.displayKey !== undefined ?
1229-
this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') :
1230-
selection.join(', ');
1231-
return value;
1232-
}
1233-
1234-
/** if there is a valueKey - map the keys to data items, else - just return the keys */
1235-
private convertKeysToItems(keys: any[]) {
1236-
if (this.comboAPI.valueKey === null) {
1237-
return keys;
1195+
protected getRemoteSelection(newSelection: any[], oldSelection: any[]): string {
1196+
if (!newSelection.length) {
1197+
// If new selection is empty, clear all items
1198+
this.registerRemoteEntries(oldSelection, false);
1199+
return '';
12381200
}
1239-
// map keys vs. filter data to retain the order of the selected items
1240-
return keys.map(key => this.data.find(entry => entry[this.valueKey] === key)).filter(e => e !== undefined);
1201+
const removedItems = oldSelection.filter(e => newSelection.indexOf(e) < 0);
1202+
const addedItems = newSelection.filter(e => oldSelection.indexOf(e) < 0);
1203+
this.registerRemoteEntries(addedItems);
1204+
this.registerRemoteEntries(removedItems, false);
1205+
return Object.keys(this._remoteSelection).map(e => this._remoteSelection[e]).join(', ');
12411206
}
12421207

1208+
public abstract get filteredData(): any[] | null;
1209+
public abstract set filteredData(val: any[] | null);
1210+
12431211
public abstract handleOpened();
1212+
public abstract focusSearchInput(opening?: boolean);
12441213

12451214
public abstract select(newItem: any): void;
12461215
public abstract select(newItems: Array<any> | any, clearCurrentSelection?: boolean, event?: Event): void;
@@ -1251,4 +1220,5 @@ export abstract class IgxComboBaseDirective extends DisplayDensityBase implement
12511220
public abstract writeValue(value: any): void;
12521221

12531222
protected abstract setSelection(newSelection: Set<any>, event?: Event): void;
1223+
protected abstract createDisplayText(newSelection: any[], oldSelection: any[]);
12541224
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
[style.maxHeight.px]="itemsMaxHeight" [igxDropDownItemNavigation]="dropdown" (focus)="dropdown.onFocus()"
5252
[tabindex]="dropdown.collapsed ? -1 : 0" role="listbox" [attr.id]="dropdown.id">
5353
<igx-combo-item role="option" [itemHeight]='itemHeight' *igxFor="let item of data
54-
| comboFiltering:filterValue:displayKey:filterable:filteringOptions
54+
| comboFiltering:filterValue:displayKey:filteringOptions:filterable
5555
| comboGrouping:groupKey:valueKey:groupSortingDirection;
5656
index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight"
5757
[value]="item" [isHeader]="item.isHeader" [index]="rowIndex">

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

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,15 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
138138
@Input()
139139
public autoFocusSearch = true;
140140

141+
/**
142+
* An @Input property that enabled/disables filtering in the list. The default is `true`.
143+
* ```html
144+
* <igx-combo [filterable]="false">
145+
* ```
146+
*/
147+
@Input()
148+
public filterable = true;
149+
141150
/**
142151
* Defines the placeholder value for the combo dropdown search field
143152
*
@@ -165,6 +174,16 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
165174
return !this.value && !this.placeholder;
166175
}
167176

177+
/** @hidden @internal */
178+
public get filteredData(): any[] | null {
179+
return this.filterable ? this._filteredData : this.data;
180+
}
181+
/** @hidden @internal */
182+
public set filteredData(val: any[] | null) {
183+
this._filteredData = this.groupKey ? (val || []).filter((e) => e.isHeader !== true) : val;
184+
this.checkMatch();
185+
}
186+
168187
/**
169188
* @hidden @internal
170189
*/
@@ -187,27 +206,9 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
187206
this.comboAPI.register(this);
188207
}
189208

190-
/**
191-
* Defines the current state of the virtualized data. It contains `startIndex` and `chunkSize`
192-
*
193-
* ```typescript
194-
* // get
195-
* let state = this.combo.virtualizationState;
196-
* ```
197-
*/
198-
public get virtualizationState(): IForOfState {
199-
return this.virtDir.state;
200-
}
201-
/**
202-
* Sets the current state of the virtualized data.
203-
*
204-
* ```typescript
205-
* // set
206-
* this.combo.virtualizationState(state);
207-
* ```
208-
*/
209-
public set virtualizationState(state: IForOfState) {
210-
this.virtDir.state = state;
209+
/** @hidden @internal */
210+
public get displaySearchInput(): boolean {
211+
return this.filterable || this.allowCustomValues;
211212
}
212213

213214
/**
@@ -390,6 +391,20 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
390391
this.opened.emit({ owner: this });
391392
}
392393

394+
/** @hidden @internal */
395+
public focusSearchInput(opening?: boolean): void {
396+
if (this.displaySearchInput && this.searchInput) {
397+
this.searchInput.nativeElement.focus();
398+
} else {
399+
if (opening) {
400+
this.dropdownContainer.nativeElement.focus();
401+
} else {
402+
this.comboInput.nativeElement.focus();
403+
this.toggle();
404+
}
405+
}
406+
}
407+
393408
protected setSelection(newSelection: Set<any>, event?: Event): void {
394409
const removed = diffInSets(this.selectionService.get(this.id), newSelection);
395410
const added = diffInSets(newSelection, this.selectionService.get(this.id));
@@ -417,6 +432,20 @@ export class IgxComboComponent extends IgxComboBaseDirective implements AfterVie
417432
this._onChangeCallback(args.newSelection);
418433
}
419434
}
435+
436+
protected createDisplayText(newSelection: any[], oldSelection: any[]) {
437+
return this.isRemote
438+
? this.getRemoteSelection(newSelection, oldSelection)
439+
: this.concatDisplayText(newSelection);
440+
}
441+
442+
/** Returns a string that should be populated in the combo's text box */
443+
private concatDisplayText(selection: any[]): string {
444+
const value = this.displayKey !== null && this.displayKey !== undefined ?
445+
this.convertKeysToItems(selection).map(entry => entry[this.displayKey]).join(', ') :
446+
selection.join(', ');
447+
return value;
448+
}
420449
}
421450

422451
/**

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Inject, Pipe, PipeTransform} from '@angular/core';
1+
import { Inject, Pipe, PipeTransform } from '@angular/core';
22
import { cloneArray } from '../core/utils';
33
import { DataUtil } from '../data-operations/data-util';
44
import { SortingDirection } from '../data-operations/sorting-expression.interface';
@@ -15,7 +15,7 @@ import { IComboFilteringOptions } from './combo.component';
1515
})
1616
export class IgxComboFilteringPipe implements PipeTransform {
1717
public transform(collection: any[], searchValue: any, displayKey: any,
18-
shouldFilter: boolean, filteringOptions: IComboFilteringOptions) {
18+
filteringOptions: IComboFilteringOptions, shouldFilter = false) {
1919
if (!collection) {
2020
return [];
2121
}
@@ -25,10 +25,10 @@ export class IgxComboFilteringPipe implements PipeTransform {
2525
const searchTerm = filteringOptions.caseSensitive ? searchValue.trim() : searchValue.toLowerCase().trim();
2626
if (displayKey != null) {
2727
return collection.filter(e => filteringOptions.caseSensitive ? e[displayKey].includes(searchTerm) :
28-
e[displayKey].toString().toLowerCase().includes(searchTerm));
28+
e[displayKey].toString().toLowerCase().includes(searchTerm));
2929
} else {
3030
return collection.filter(e => filteringOptions.caseSensitive ? e.includes(searchTerm) :
31-
e.toString().toLowerCase().includes(searchTerm));
31+
e.toString().toLowerCase().includes(searchTerm));
3232
}
3333
}
3434
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
[style.maxHeight.px]="itemsMaxHeight" [igxDropDownItemNavigation]="dropdown" (focus)="dropdown.onFocus()"
4646
[tabindex]="dropdown.collapsed ? -1 : 0" role="listbox" [attr.id]="dropdown.id">
4747
<igx-combo-item role="option" [singleMode]="true" [itemHeight]='itemHeight' (click)="close()" *igxFor="let item of data
48-
| comboFiltering:filterValue:displayKey:filterable:filteringOptions
48+
| comboFiltering:filterValue:displayKey:filteringOptions:true
4949
| comboGrouping:groupKey:valueKey:groupSortingDirection;
5050
index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight"
5151
[value]="item" [isHeader]="item.isHeader" [index]="rowIndex">

0 commit comments

Comments
 (0)