Skip to content

Commit 665bff6

Browse files
committed
fix(ibm-combo-box): open dropdown when new items are received that match search string
- removed setTimeout from updateList method inside the dropdown list component which was delaying the execution of the closeDropdown method inside the combo box component until after the openDropdown method was called - updated combo box component to filter dropdown list items by the current search string when new items are passed into the combo box component - updated dropdown component to run code inside the Angular zone to force a change detection cycle to take place rather than calling tick method on the application reference as the tick call was throwing an error after the change to the dropdown list was introduced Fix #2426
1 parent 842778a commit 665bff6

File tree

4 files changed

+54
-32
lines changed

4 files changed

+54
-32
lines changed

src/combobox/combobox.component.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,28 @@ describe("Combo box", () => {
160160
element = fixture.debugElement.query(By.css("input"));
161161
expect(element.nativeElement.getAttribute("placeholder")).toBe("placeholder");
162162
});
163+
164+
it("should display dropdown list when new items are passed that match the current search string", () => {
165+
fixture = TestBed.createComponent(ComboboxTest);
166+
wrapper = fixture.componentInstance;
167+
fixture.detectChanges();
168+
169+
element = fixture.debugElement.query(By.css("ibm-combo-box"));
170+
171+
const textInput = element.nativeElement.querySelector(".bx--text-input");
172+
textInput.value = "f";
173+
textInput.dispatchEvent(new Event("input"));
174+
175+
wrapper.items = [
176+
{content: "four", selected: false},
177+
{content: "five", selected: false},
178+
{content: "six", selected: false}
179+
];
180+
181+
fixture.detectChanges();
182+
183+
const itemEls = fixture.debugElement.queryAll(By.css(".bx--list-box__menu-item"));
184+
185+
expect(itemEls.length).toEqual(2);
186+
});
163187
});

src/combobox/combobox.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit, OnD
747747
if (!matches) {
748748
const selected = this.view.getSelected();
749749
if (!selected || !selected[0]) {
750-
this.view.filterBy("");
750+
this.view.filterBy(searchString);
751751
}
752752
}
753753
}

src/dropdown/dropdown.component.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
OnDestroy,
1313
HostBinding,
1414
TemplateRef,
15-
ApplicationRef,
16-
AfterViewInit
15+
AfterViewInit,
16+
NgZone
1717
} from "@angular/core";
1818
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
1919

@@ -357,7 +357,7 @@ export class Dropdown implements OnInit, AfterContentInit, AfterViewInit, OnDest
357357
protected elementRef: ElementRef,
358358
protected i18n: I18n,
359359
protected dropdownService: DropdownService,
360-
protected appRef: ApplicationRef,
360+
protected ngZone: NgZone,
361361
protected elementService: ElementService) {}
362362

363363
/**
@@ -387,36 +387,36 @@ export class Dropdown implements OnInit, AfterContentInit, AfterViewInit, OnDest
387387
const isUpdate = event => event && event.isUpdate;
388388

389389
this.view.select.subscribe(event => {
390-
if (this.type === "single" && !isUpdate(event)) {
391-
this.closeMenu();
392-
if (event.item && event.item.selected) {
393-
if (this.itemValueKey) {
394-
this.propagateChange(event.item[this.itemValueKey]);
390+
this.ngZone.run(() => {
391+
if (this.type === "single" && !isUpdate(event)) {
392+
this.closeMenu();
393+
if (event.item && event.item.selected) {
394+
if (this.itemValueKey) {
395+
this.propagateChange(event.item[this.itemValueKey]);
396+
} else {
397+
this.propagateChange(event.item);
398+
}
395399
} else {
396-
this.propagateChange(event.item);
400+
this.propagateChange(null);
397401
}
398-
} else {
399-
this.propagateChange(null);
400402
}
401-
}
402403

403-
if (this.type === "multi" && !isUpdate(event)) {
404-
// if we have a `value` selector and selected items map them appropriately
405-
if (this.itemValueKey && this.view.getSelected()) {
406-
const values = this.view.getSelected().map(item => item[this.itemValueKey]);
407-
this.propagateChange(values);
408-
// otherwise just pass up the values from `getSelected`
409-
} else {
410-
this.propagateChange(this.view.getSelected());
404+
if (this.type === "multi" && !isUpdate(event)) {
405+
// if we have a `value` selector and selected items map them appropriately
406+
if (this.itemValueKey && this.view.getSelected()) {
407+
const values = this.view.getSelected().map(item => item[this.itemValueKey]);
408+
this.propagateChange(values);
409+
// otherwise just pass up the values from `getSelected`
410+
} else {
411+
this.propagateChange(this.view.getSelected());
412+
}
411413
}
412-
}
413-
// only emit selected for "organic" selections
414-
if (!isUpdate(event)) {
415-
this.checkForReorder();
416-
this.selected.emit(event);
417-
}
418-
// manually tick the app so the view picks up any changes
419-
this.appRef.tick();
414+
// only emit selected for "organic" selections
415+
if (!isUpdate(event)) {
416+
this.checkForReorder();
417+
this.selected.emit(event);
418+
}
419+
});
420420
});
421421
}
422422

src/dropdown/list/dropdown-list.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,7 @@ export class DropdownList implements AbstractDropdownView, AfterViewInit, OnDest
276276
this.displayItems = this._items;
277277
this.updateIndex();
278278
this.setupFocusObservable();
279-
setTimeout(() => {
280-
this.doEmitSelect();
281-
});
279+
this.doEmitSelect();
282280
}
283281

284282
/**

0 commit comments

Comments
 (0)