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 = '';