bug(autocomplete): deselect the other options when the user select an option (#3690)

* bug(autocomplete): deselect the other options when the user select one from the autocomplete

Fixes #3689

* bug(autocomplete): only call deselect on the previous selected option. Unit tests.
This commit is contained in:
Jeferson Estevo
2017-03-28 17:28:18 -03:00
committed by tinayuangao
parent 1ae81a4450
commit 61085633ef
2 changed files with 75 additions and 0 deletions
@@ -307,6 +307,7 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
*/
private _setValueAndClose(event: MdOptionSelectionChange | null): void {
if (event) {
this._clearPreviousSelectedOption(event.source);
this._setTriggerValue(event.source.value);
this._onChange(event.source.value);
}
@@ -314,6 +315,17 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
this.closePanel();
}
/**
* Clear any previous selected option and emit a selection change event for this option
*/
private _clearPreviousSelectedOption(skip: MdOption) {
this.autocomplete.options.forEach((option) => {
if (option != skip && option.selected) {
option.deselect();
}
});
}
private _createOverlay(): void {
this._portal = new TemplatePortal(this.autocomplete.template, this._viewContainerRef);
this._overlayRef = this._overlay.create(this._getOverlayConfig());
+63
View File
@@ -918,6 +918,69 @@ describe('MdAutocomplete', () => {
});
describe('Option selection', () => {
let fixture: ComponentFixture<SimpleAutocomplete>;
beforeEach(() => {
fixture = TestBed.createComponent(SimpleAutocomplete);
fixture.detectChanges();
fixture.componentInstance.trigger.openPanel();
fixture.detectChanges();
});
it('should deselect any other selected option', async(() => {
let options =
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
options[0].click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
let componentOptions = fixture.componentInstance.options.toArray();
expect(componentOptions[0].selected)
.toBe(true, `Clicked option should be selected.`);
options =
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
options[1].click();
fixture.detectChanges();
expect(componentOptions[0].selected)
.toBe(false, `Previous option should not be selected.`);
expect(componentOptions[1].selected)
.toBe(true, `New Clicked option should be selected.`);
});
}));
it('should call deselect only on the previous selected option', async(() => {
let options =
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
options[0].click();
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
let componentOptions = fixture.componentInstance.options.toArray();
componentOptions.forEach(option => spyOn(option, 'deselect'));
expect(componentOptions[0].selected)
.toBe(true, `Clicked option should be selected.`);
options =
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
options[1].click();
fixture.detectChanges();
expect(componentOptions[0].deselect).toHaveBeenCalled();
componentOptions.slice(1).forEach(option => expect(option.deselect).not.toHaveBeenCalled());
});
}));
});
describe('misc', () => {
it('should allow basic use without any forms directives', () => {