Skip to content

Commit 62da739

Browse files
committed
fix(input): prevent overlapping placeholder on inputs with native masking
Prevents the Material placeholder overlapping with native input masking (e.g. on `input[type="time"]`. Previously, this was hardcoded for `date`, however it didn't take into account that not all browsers support `date` inputs. This change runs a feature test on each of the types that should have input masking and only triggers the special behavior if the type is supported. Fixes #1853.
1 parent 009046f commit 62da739

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

src/lib/input/input.spec.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
import {Component} from '@angular/core';
66
import {FormsModule} from '@angular/forms';
77
import {By} from '@angular/platform-browser';
8-
import {MdInput, MdInputModule} from './input';
8+
import {MdInput, MdInputModule, TYPES_WITH_MASK} from './input';
99

1010
function isInternetExplorer11() {
1111
return 'ActiveXObject' in window;
@@ -53,7 +53,7 @@ describe('MdInput', function () {
5353
MdInputWithMin,
5454
MdInputWithStep,
5555
MdInputWithTabindex,
56-
MdInputDateTestController,
56+
MdInputWithMask,
5757
MdInputTextTestController,
5858
MdInputPasswordTestController,
5959
MdInputNumberTestController,
@@ -80,11 +80,11 @@ describe('MdInput', function () {
8080
.toBe(true, 'Expected MdInput to default to having floating placeholders turned on');
8181
});
8282

83-
it('should not be treated as empty if type is date', () => {
84-
if (isInternetExplorer11()) {
83+
it('should not be treated as empty if the input has native masking', () => {
84+
if (!TYPES_WITH_MASK.length) {
8585
return;
8686
}
87-
let fixture = TestBed.createComponent(MdInputDateTestController);
87+
let fixture = TestBed.createComponent(MdInputWithMask);
8888
fixture.componentInstance.placeholder = 'Placeholder';
8989
fixture.detectChanges();
9090

@@ -787,8 +787,9 @@ class MdInputWithStep { }
787787
@Component({template: `<md-input [tabindex]="tabIndex"></md-input>`})
788788
class MdInputWithTabindex { }
789789

790-
@Component({template: `<md-input type="date" [placeholder]="placeholder"></md-input>`})
791-
class MdInputDateTestController {
790+
@Component({template:
791+
`<md-input type="${TYPES_WITH_MASK[0] || 'text'}" [placeholder]="placeholder"></md-input>`})
792+
class MdInputWithMask {
792793
placeholder: string = '';
793794
}
794795

src/lib/input/input.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ const MD_INPUT_INVALID_INPUT_TYPE = [
4040
'checkbox',
4141
];
4242

43+
let featureTestInput: HTMLInputElement = document.createElement('input');
44+
45+
/** Native input types, supported by the current browser, that have input masking. */
46+
export const TYPES_WITH_MASK = [
47+
'range', 'date', 'month', 'week', 'time', 'datetime', 'datetime-local'
48+
].filter(value => {
49+
featureTestInput.setAttribute('type', value);
50+
return featureTestInput.type === value;
51+
});
52+
53+
featureTestInput = null;
54+
4355

4456
let nextUniqueId = 0;
4557

@@ -139,7 +151,10 @@ export class MdInput implements ControlValueAccessor, AfterContentInit, OnChange
139151

140152
/** Readonly properties. */
141153
get focused() { return this._focused; }
142-
get empty() { return (this._value == null || this._value === '') && this.type !== 'date'; }
154+
get empty() {
155+
return (this._value == null || this._value === '') &&
156+
TYPES_WITH_MASK.indexOf(this.type) === -1;
157+
}
143158
get characterCount(): number {
144159
return this.empty ? 0 : ('' + this._value).length;
145160
}

0 commit comments

Comments
 (0)