Skip to content

Commit d9e0d5f

Browse files
committed
fix(select): clear select if no option matches value
Closes #2109
1 parent a695574 commit d9e0d5f

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

src/lib/select/select.spec.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,19 @@ describe('MdSelect', () => {
191191
});
192192

193193
it('should focus the selected option if an option is selected', async(() => {
194-
trigger.click();
195-
fixture.detectChanges();
196-
197-
const options =
198-
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
199-
options[1].click();
200-
fixture.detectChanges();
194+
// must wait for initial writeValue promise to finish
195+
fixture.whenStable().then(() => {
196+
fixture.componentInstance.control.setValue('pizza-1');
197+
fixture.detectChanges();
201198

202-
trigger.click();
203-
fixture.detectChanges();
199+
trigger.click();
200+
fixture.detectChanges();
204201

205-
fixture.whenStable().then(() => {
206-
expect(fixture.componentInstance.select._keyManager.focusedItemIndex).toEqual(1);
202+
// must wait for animation to finish
203+
fixture.whenStable().then(() => {
204+
fixture.detectChanges();
205+
expect(fixture.componentInstance.select._keyManager.focusedItemIndex).toEqual(1);
206+
});
207207
});
208208
}));
209209

@@ -305,6 +305,27 @@ describe('MdSelect', () => {
305305
.toEqual('steak-0', `Expected control's value to be set to the new option.`);
306306
});
307307

308+
it('should clear the selection when a nonexistent option value is selected', () => {
309+
fixture.componentInstance.control.setValue('pizza-1');
310+
fixture.detectChanges();
311+
312+
fixture.componentInstance.control.setValue('gibberish');
313+
fixture.detectChanges();
314+
315+
const value = fixture.debugElement.query(By.css('.md-select-value'));
316+
expect(value).toBe(null, `Expected trigger to be cleared when option value is not found.`);
317+
expect(trigger.textContent)
318+
.not.toContain('Pizza', `Expected trigger to be cleared when option value is not found.`);
319+
320+
trigger.click();
321+
fixture.detectChanges();
322+
323+
const options =
324+
overlayContainerElement.querySelectorAll('md-option') as NodeListOf<HTMLElement>;
325+
expect(options[1].classList)
326+
.not.toContain('md-selected', `Expected option with the old value not to be selected.`);
327+
});
328+
308329
it('should set the control to touched when the select is touched', () => {
309330
expect(fixture.componentInstance.control.touched)
310331
.toEqual(false, `Expected the control to start off as untouched.`);

src/lib/select/select.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,7 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
252252
return;
253253
}
254254

255-
this.options.forEach((option: MdOption) => {
256-
if (option.value === value) {
257-
option.select();
258-
}
259-
});
255+
this._setSelectionByValue(value);
260256
}
261257

262258
/**
@@ -353,6 +349,28 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
353349
scrollContainer.scrollTop = this._scrollTop;
354350
}
355351

352+
/**
353+
* Sets the selected option based on a value. If no option can be
354+
* found with the designated value, the select trigger is cleared.
355+
*/
356+
private _setSelectionByValue(value: any): void {
357+
this.options.forEach((option: MdOption) => {
358+
if (option.value === value) {
359+
option.select();
360+
}
361+
});
362+
363+
if (this.selected && this.selected.value !== value) {
364+
this._clearSelection();
365+
}
366+
}
367+
368+
/** Clears the select trigger and deselects every option in the list. */
369+
private _clearSelection(): void {
370+
this._selected = null;
371+
this._updateOptions();
372+
}
373+
356374
private _getTriggerRect(): ClientRect {
357375
return this.trigger.nativeElement.getBoundingClientRect();
358376
}

0 commit comments

Comments
 (0)