@@ -75,53 +75,71 @@ export class MdHint {
75
75
` ,
76
76
host : {
77
77
'class' : 'md-input-element' ,
78
+ // Native input properties that are overwritten by Angular inputs need to be synced with
79
+ // the native input element. Otherwise property bindings for those don't work.
78
80
'[id]' : 'id' ,
81
+ '[placeholder]' : 'placeholder' ,
82
+ '[disabled]' : 'disabled' ,
83
+ '[required]' : 'required' ,
79
84
'(blur)' : '_onBlur()' ,
80
85
'(focus)' : '_onFocus()' ,
81
86
'(input)' : '_onInput()' ,
82
87
}
83
88
} )
84
89
export class MdInputDirective implements AfterContentInit {
90
+
91
+ /** Variables used as cache for getters and setters. */
92
+ private _type = 'text' ;
93
+ private _placeholder : string = '' ;
94
+ private _disabled = false ;
95
+ private _required = false ;
96
+ private _id : string ;
97
+ private _cachedUid : string ;
98
+
99
+ /** The element's value. */
100
+ value : any ;
101
+
102
+ /** Whether the element is focused or not. */
103
+ focused = false ;
104
+
85
105
/** Whether the element is disabled. */
86
106
@Input ( )
87
107
get disabled ( ) { return this . _disabled ; }
88
108
set disabled ( value : any ) { this . _disabled = coerceBooleanProperty ( value ) ; }
89
- private _disabled = false ;
90
109
91
110
/** Unique id of the element. */
92
111
@Input ( )
93
112
get id ( ) { return this . _id ; } ;
94
- set id ( value : string ) { this . _id = value || this . _uid ; }
95
- private _id : string ;
113
+ set id ( value : string ) { this . _id = value || this . _uid ; }
96
114
97
115
/** Placeholder attribute of the element. */
98
116
@Input ( )
99
117
get placeholder ( ) { return this . _placeholder ; }
100
118
set placeholder ( value : string ) {
101
- if ( this . _placeholder != value ) {
119
+ if ( this . _placeholder !== value ) {
102
120
this . _placeholder = value ;
103
121
this . _placeholderChange . emit ( this . _placeholder ) ;
104
122
}
105
123
}
106
- private _placeholder = '' ;
107
-
108
124
/** Whether the element is required. */
109
125
@Input ( )
110
126
get required ( ) { return this . _required ; }
111
127
set required ( value : any ) { this . _required = coerceBooleanProperty ( value ) ; }
112
- private _required = false ;
113
128
114
129
/** Input type of the element. */
115
130
@Input ( )
116
131
get type ( ) { return this . _type ; }
117
132
set type ( value : string ) {
118
133
this . _type = value || 'text' ;
119
134
this . _validateType ( ) ;
120
- }
121
- private _type = 'text' ;
122
135
123
- /** The element's value. */
124
- value : any ;
136
+ // When using Angular inputs, developers are no longer able to set the properties on the native
137
+ // input element. To ensure that bindings for `type` work, we need to sync the setter
138
+ // with the native property. Textarea elements don't support the type property or attribute.
139
+ if ( ! this . _isTextarea ( ) && getSupportedInputTypes ( ) . has ( this . _type ) ) {
140
+ this . _renderer . setElementProperty ( this . _elementRef . nativeElement , 'type' , this . _type ) ;
141
+ }
142
+ }
125
143
126
144
/**
127
145
* Emits an event when the placeholder changes so that the `md-input-container` can re-validate.
@@ -130,10 +148,7 @@ export class MdInputDirective implements AfterContentInit {
130
148
131
149
get empty ( ) { return ( this . value == null || this . value === '' ) && ! this . _isNeverEmpty ( ) ; }
132
150
133
- focused = false ;
134
-
135
151
private get _uid ( ) { return this . _cachedUid = this . _cachedUid || `md-input-${ nextUniqueId ++ } ` ; }
136
- private _cachedUid : string ;
137
152
138
153
private _neverEmptyInputTypes = [
139
154
'date' ,
@@ -172,12 +187,18 @@ export class MdInputDirective implements AfterContentInit {
172
187
173
188
/** Make sure the input is a supported type. */
174
189
private _validateType ( ) {
175
- if ( MD_INPUT_INVALID_TYPES . indexOf ( this . _type ) != - 1 ) {
190
+ if ( MD_INPUT_INVALID_TYPES . indexOf ( this . _type ) !== - 1 ) {
176
191
throw new MdInputContainerUnsupportedTypeError ( this . _type ) ;
177
192
}
178
193
}
179
194
180
- private _isNeverEmpty ( ) { return this . _neverEmptyInputTypes . indexOf ( this . _type ) != - 1 ; }
195
+ private _isNeverEmpty ( ) { return this . _neverEmptyInputTypes . indexOf ( this . _type ) !== - 1 ; }
196
+
197
+ /** Determines if the component host is a textarea. If not recognizable it returns false. */
198
+ private _isTextarea ( ) {
199
+ let nativeElement = this . _elementRef . nativeElement ;
200
+ return nativeElement ? nativeElement . nodeName . toLowerCase ( ) === 'textarea' : false ;
201
+ }
181
202
}
182
203
183
204
0 commit comments