Skip to content

Commit

Permalink
Merge pull request #11113 from IgniteUI/bpenkov/simple-combo-selection
Browse files Browse the repository at this point in the history
Simple combo retains selection on blur
  • Loading branch information
Lipata authored Mar 9, 2022
2 parents 1e42e27 + 35b2f71 commit 9315549
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,21 @@ describe('IgxSimpleCombo', () => {
expect(combo.close).toHaveBeenCalledTimes(1);
});

it('should retain selection after blurring', () => {
combo.open();
fixture.detectChanges();
const item1 = fixture.debugElement.query(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`));
expect(item1).toBeDefined();

item1.triggerEventHandler('click', UIInteractions.getMouseEvent('click'));
fixture.detectChanges();

UIInteractions.triggerEventHandlerKeyDown('Tab', input);
fixture.detectChanges();

expect(combo.selection.length).toBe(1);
});

it('should scroll to top when opened and there is no selection', () => {
combo.deselect();
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
public composing = false;

private _updateInput = true;

// stores the last filtered value - move to common?
private _internalFilter = '';

Expand All @@ -109,7 +110,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
this._searchValue = val;
}

private get selectedItem() {
private get selectedItem(): any {
return this.selectionService.get(this.id).values().next().value;
}

Expand All @@ -130,7 +131,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
/** @hidden @internal */
@HostListener('keydown.ArrowDown', ['$event'])
@HostListener('keydown.Alt.ArrowDown', ['$event'])
public onArrowDown(event: Event) {
public onArrowDown(event: Event): void {
if (this.collapsed) {
event.preventDefault();
event.stopPropagation();
Expand Down Expand Up @@ -173,15 +174,15 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public writeValue(value: any) {
public writeValue(value: any): void {
const oldSelection = this.selection;
this.selectionService.select_items(this.id, value ? [value] : [], true);
this.cdr.markForCheck();
this._value = this.createDisplayText(this.selection, oldSelection);
}

/** @hidden @internal */
public ngAfterViewInit() {
public ngAfterViewInit(): void {
this.virtDir.contentSizeChange.pipe(takeUntil(this.destroy$)).subscribe(() => {
if (this.selection.length > 0) {
const index = this.virtDir.igxForOf.findIndex(e => {
Expand All @@ -200,13 +201,13 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
this.filterValue = this.searchValue = this.comboInput.value;
return;
}
this._internalFilter = this.filterValue;
this.filterValue = this.searchValue = '';
});
this.dropdown.opened.pipe(takeUntil(this.destroy$)).subscribe(() => {
if (this.composing) {
this.comboInput.focus();
}
this._internalFilter = this.comboInput.value;
});
this.dropdown.closing.pipe(takeUntil(this.destroy$)).subscribe((args) => {
if (this.getEditElement() && !args.event) {
Expand All @@ -224,7 +225,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleInputChange(event?: any) {
public handleInputChange(event?: any): void {
if (event !== undefined) {
this.filterValue = this._internalFilter = this.searchValue = typeof event === 'string' ? event : event.target.value;
}
Expand All @@ -246,7 +247,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleKeyDown(event: KeyboardEvent) {
public handleKeyDown(event: KeyboardEvent): void {
if (event.key === this.platformUtil.KEYMAP.ENTER) {
const filtered = this.filteredData.find(this.findMatch);
if (filtered === null || filtered === undefined) {
Expand Down Expand Up @@ -274,7 +275,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleKeyUp(event: KeyboardEvent) {
public handleKeyUp(event: KeyboardEvent): void {
if (event.key === this.platformUtil.KEYMAP.ARROW_DOWN) {
const firstItem = this.selectionService.first_item(this.id);
this.dropdown.focusedItem = firstItem && this.filteredData.length > 0
Expand All @@ -285,7 +286,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleItemKeyDown(event: KeyboardEvent) {
public handleItemKeyDown(event: KeyboardEvent): void {
if (event.key === this.platformUtil.KEYMAP.ARROW_UP && event.altKey) {
this.close();
this.comboInput.focus();
Expand All @@ -297,13 +298,13 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleItemClick() {
public handleItemClick(): void {
this.close();
this.comboInput.focus();
}

/** @hidden @internal */
public onBlur() {
public onBlur(): void {
if (this.collapsed) {
this.clearOnBlur();
}
Expand All @@ -316,7 +317,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleClear(event: Event) {
public handleClear(event: Event): void {
if (this.disabled) {
return;
}
Expand All @@ -336,14 +337,14 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public handleOpened() {
public handleOpened(): void {
this.triggerCheck();
this.dropdownContainer.nativeElement.focus();
this.opened.emit({ owner: this });
}

/** @hidden @internal */
public handleClosing(e: IBaseCancelableBrowserEventArgs) {
public handleClosing(e: IBaseCancelableBrowserEventArgs): void {
const args: IBaseCancelableBrowserEventArgs = { owner: this, event: e.event, cancel: e.cancel };
this.closing.emit(args);
e.cancel = args.cancel;
Expand All @@ -368,7 +369,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}

/** @hidden @internal */
public onClick(event: Event) {
public onClick(event: Event): void {
super.onClick(event);
if (this.comboInput.value.length === 0) {
this.virtDir.scrollTo(0);
Expand Down Expand Up @@ -401,7 +402,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
argsSelection = Array.isArray(argsSelection) ? argsSelection : [argsSelection];
this.selectionService.select_items(this.id, argsSelection, true);
if (this._updateInput) {
this.comboInput.value = this._value = displayText !== args.displayText
this.comboInput.value = this._internalFilter = this._value = displayText !== args.displayText
? args.displayText
: this.createDisplayText(argsSelection, [args.oldSelection]);
}
Expand All @@ -410,7 +411,7 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
}
}

protected createDisplayText(newSelection: any[], oldSelection: any[]) {
protected createDisplayText(newSelection: any[], oldSelection: any[]): any {
if (this.isRemote) {
return this.getRemoteSelection(newSelection, oldSelection);
}
Expand All @@ -431,13 +432,13 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
this.setSelection(newSelection);
}

private clearOnBlur() {
private clearOnBlur(): void {
const filtered = this.filteredData.find(this.findMatch);
if (filtered === undefined || filtered === null || !this.selectedItem) {
this.clearAndClose();
return;
}
if (this.isPartialMatch(filtered) || this.selectedItem !== this._internalFilter) {
if (this.isPartialMatch(filtered) || this.getElementVal(filtered) !== this._internalFilter) {
this.clearAndClose();
}
}
Expand All @@ -446,11 +447,15 @@ export class IgxSimpleComboComponent extends IgxComboBaseDirective implements Co
return !!this._internalFilter && this._internalFilter.length !== this.getElementVal(filtered).length;
}

private getElementVal(element: any) {
private getElementVal(element: any): any | null {
if (!element) {
return null;
}

return this.displayKey ? element[this.displayKey] : element;
}

private clearAndClose() {
private clearAndClose(): void {
this.clearSelection(true);
this._internalFilter = '';
this.searchValue = '';
Expand Down

0 comments on commit 9315549

Please sign in to comment.