From 7579428c4408803a3d790ba81eb08445ad312bb1 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 25 Nov 2018 17:52:05 +0100 Subject: [PATCH] fix(form-field): native select label floating incorrectly when invalid value is set Fixes the label for a form field with a native select floating when it isn't supposed to, if a value that isn't in the options list is assigned. --- src/lib/input/input.spec.ts | 15 +++++++++++++++ src/lib/input/input.ts | 6 ++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/lib/input/input.spec.ts b/src/lib/input/input.spec.ts index 1935f556c69a..06e6c6501702 100644 --- a/src/lib/input/input.spec.ts +++ b/src/lib/input/input.spec.ts @@ -643,6 +643,21 @@ describe('MatInput without forms', () => { expect(formFieldEl.classList).toContain('mat-form-field-should-float'); })); + it('should not float the label if the selectedIndex is negative', fakeAsync(() => { + const fixture = createComponent(MatInputSelect); + fixture.detectChanges(); + + const formFieldEl = fixture.debugElement.query(By.css('.mat-form-field')).nativeElement; + const selectEl: HTMLSelectElement = formFieldEl.querySelector('select'); + + expect(formFieldEl.classList).toContain('mat-form-field-should-float'); + + selectEl.selectedIndex = -1; + fixture.detectChanges(); + + expect(formFieldEl.classList).not.toContain('mat-form-field-should-float'); + })); + it('should not float labels when select has no value, no option label, ' + 'no option innerHtml', fakeAsync(() => { const fixture = createComponent(MatInputSelectWithNoLabelNoValue); diff --git a/src/lib/input/input.ts b/src/lib/input/input.ts index 545f9fe8be5e..e754c7a825ab 100644 --- a/src/lib/input/input.ts +++ b/src/lib/input/input.ts @@ -385,8 +385,10 @@ export class MatInput extends _MatInputMixinBase implements MatFormFieldControl< const selectElement = this._elementRef.nativeElement as HTMLSelectElement; const firstOption: HTMLOptionElement | undefined = selectElement.options[0]; - return selectElement.multiple || !this.empty || this.focused || - !!(firstOption && firstOption.label); + // On most browsers the `selectedIndex` will always be 0, however on IE and Edge it'll be + // -1 if the `value` is set to something, that isn't in the list of options, at a later point. + return this.focused || selectElement.multiple || !this.empty || + !!(selectElement.selectedIndex > -1 && firstOption && firstOption.label); } else { return this.focused || !this.empty; }