diff --git a/src/demo-app/select/select-demo.html b/src/demo-app/select/select-demo.html index 821934b4b59f..b1fc095641b5 100644 --- a/src/demo-app/select/select-demo.html +++ b/src/demo-app/select/select-demo.html @@ -19,6 +19,8 @@ + #drinkControl="ngModel"> + None {{ drink.viewValue }} diff --git a/src/demo-app/select/select-demo.ts b/src/demo-app/select/select-demo.ts index b731087b5624..3307dd1ee848 100644 --- a/src/demo-app/select/select-demo.ts +++ b/src/demo-app/select/select-demo.ts @@ -18,6 +18,7 @@ export class SelectDemo { foodControl = new FormControl('pizza-1'); foods = [ + {value: null, viewValue: 'None'}, {value: 'steak-0', viewValue: 'Steak'}, {value: 'pizza-1', viewValue: 'Pizza'}, {value: 'tacos-2', viewValue: 'Tacos'} diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts index ab82b27c9634..bebf3907eca9 100644 --- a/src/lib/select/select.spec.ts +++ b/src/lib/select/select.spec.ts @@ -38,7 +38,8 @@ describe('MdSelect', () => { FloatPlaceholderSelect, SelectWithErrorSibling, ThrowsErrorOnInit, - BasicSelectOnPush + BasicSelectOnPush, + ResetValuesSelect ], providers: [ {provide: OverlayContainer, useFactory: () => { @@ -1342,6 +1343,72 @@ describe('MdSelect', () => { expect(trigger.textContent).not.toContain('Pizza'); }); }); + + describe('reset values', () => { + let fixture: ComponentFixture; + let trigger: HTMLElement; + let placeholder: HTMLElement; + let options: NodeListOf; + + + beforeEach(() => { + fixture = TestBed.createComponent(ResetValuesSelect); + fixture.detectChanges(); + trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement; + placeholder = fixture.debugElement.query(By.css('.mat-select-placeholder')).nativeElement; + + trigger.click(); + fixture.detectChanges(); + options = overlayContainerElement.querySelectorAll('md-option') as NodeListOf; + + options[0].click(); + fixture.detectChanges(); + }); + + it('should reset when an option with an undefined value is selected', () => { + options[4].click(); + fixture.detectChanges(); + + expect(fixture.componentInstance.control.value).toBeUndefined(); + expect(fixture.componentInstance.select.selected).toBeFalsy(); + expect(placeholder.classList).not.toContain('mat-floating-placeholder'); + expect(trigger.textContent).not.toContain('Undefined'); + }); + + it('should reset when an option with a null value is selected', () => { + options[5].click(); + fixture.detectChanges(); + + expect(fixture.componentInstance.control.value).toBeNull(); + expect(fixture.componentInstance.select.selected).toBeFalsy(); + expect(placeholder.classList).not.toContain('mat-floating-placeholder'); + expect(trigger.textContent).not.toContain('Null'); + }); + + it('should not reset when any other falsy option is selected', () => { + options[3].click(); + fixture.detectChanges(); + + expect(fixture.componentInstance.control.value).toBe(false); + expect(fixture.componentInstance.select.selected).toBeTruthy(); + expect(placeholder.classList).toContain('mat-floating-placeholder'); + expect(trigger.textContent).toContain('Falsy'); + }); + + it('should not consider the reset values as selected when resetting the form control', () => { + expect(placeholder.classList).toContain('mat-floating-placeholder'); + + fixture.componentInstance.control.reset(); + fixture.detectChanges(); + + expect(fixture.componentInstance.control.value).toBeNull(); + expect(fixture.componentInstance.select.selected).toBeFalsy(); + expect(placeholder.classList).not.toContain('mat-floating-placeholder'); + expect(trigger.textContent).not.toContain('Null'); + expect(trigger.textContent).not.toContain('Undefined'); + }); + + }); }); @@ -1588,6 +1655,32 @@ class FloatPlaceholderSelect { @ViewChild(MdSelect) select: MdSelect; } +@Component({ + selector: 'reset-values-select', + template: ` + + + {{ food.viewValue }} + + + ` +}) +class ResetValuesSelect { + foods: any[] = [ + { value: 'steak-0', viewValue: 'Steak' }, + { value: 'pizza-1', viewValue: 'Pizza' }, + { value: 'tacos-2', viewValue: 'Tacos' }, + { value: false, viewValue: 'Falsy' }, + { viewValue: 'Undefined' }, + { value: null, viewValue: 'Null' }, + ]; + control = new FormControl(); + isRequired: boolean; + + @ViewChild(MdSelect) select: MdSelect; + @ViewChildren(MdOption) options: QueryList; +} + /** * TODO: Move this to core testing utility until Angular has event faking diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts index 1a92699e5437..db0870db2710 100644 --- a/src/lib/select/select.ts +++ b/src/lib/select/select.ts @@ -500,7 +500,7 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr /** When a new option is selected, deselects the others and closes the panel. */ private _onSelect(option: MdOption): void { - this._selected = option; + this._selected = option.value == null ? null : option; this._updateOptions(); this._setValueWidth(); this._placeholderState = '';