55 * Form
66 */
77angular . module ( 'material.components.textField' , [ 'material.core' , 'material.services.theming' ] )
8- . directive ( 'mdInputGroup' , [ mdInputGroupDirective ] )
9- . directive ( 'mdInput' , [ '$mdUtil' , mdInputDirective ] )
10- . directive ( 'mdTextFloat' , [ '$mdTheming' , '$mdUtil' , mdTextFloatDirective ] ) ;
11-
8+ . directive ( 'mdInputGroup' , [ mdInputGroupDirective ] )
9+ . directive ( 'mdInput' , [ '$mdUtil' , mdInputDirective ] )
10+ . directive ( 'mdTextarea' , [ '$mdUtil' , mdTextareaDirective ] )
11+ . directive ( 'mdTextFloat' , [ '$mdTheming' , '$mdUtil' , mdTextFloatDirective ] )
12+ . directive ( 'mdTextareaFloat' , [ '$mdTheming' , '$mdUtil' , mdTextareaFloatDirective ] ) ;
1213
1314
1415/**
@@ -41,21 +42,21 @@ function mdTextFloatDirective($mdTheming, $mdUtil) {
4142 return {
4243 restrict : 'E' ,
4344 replace : true ,
44- scope : {
45- fid : '@?' ,
46- label : '@?' ,
47- value : '=ngModel'
45+ scope : {
46+ fid : '@?' ,
47+ label : '@?' ,
48+ value : '=ngModel'
4849 } ,
49- compile : function ( element , attr ) {
50+ compile : function ( element , attr ) {
5051
51- if ( angular . isUndefined ( attr . fid ) ) {
52+ if ( angular . isUndefined ( attr . fid ) ) {
5253 attr . fid = $mdUtil . nextUid ( ) ;
5354 }
5455
5556 return {
56- pre : function ( scope , element , attrs ) {
57+ pre : function ( scope , element , attrs ) {
5758 // transpose `disabled` flag
58- if ( angular . isDefined ( attrs . disabled ) ) {
59+ if ( angular . isDefined ( attrs . disabled ) ) {
5960 element . attr ( 'disabled' , true ) ;
6061 scope . isDisabled = true ;
6162 }
@@ -64,17 +65,80 @@ function mdTextFloatDirective($mdTheming, $mdUtil) {
6465 element . removeAttr ( 'type' ) ;
6566
6667 // transpose optional `class` settings
67- element . attr ( 'class' , attrs . class ) ;
68+ element . attr ( 'class' , attrs . class ) ;
69+
70+ } ,
71+ post : $mdTheming
72+ } ;
73+ } ,
74+ template : '<md-input-group ng-disabled="isDisabled" tabindex="-1">' +
75+ ' <label for="{{fid}}" >{{label}}</label>' +
76+ ' <md-input id="{{fid}}" ng-model="value" type="{{inputType}}"></md-input>' +
77+ '</md-input-group>'
78+ } ;
79+ }
80+
81+ /**
82+ * @ngdoc directive
83+ * @name mdTextareaFloat
84+ * @module material.components.textField
85+ *
86+ * @restrict E
87+ *
88+ * @description
89+ * Use the `<md-textarea-float>` directive to quickly construct `Floating Label` textarea fields
90+ *
91+ * @param {string } fid Attribute used for accessibility link pairing between the Label and Input elements
92+ * @param {string= } rows Optional value to define the amount of rows.
93+ * @param {string= } cols Optional value to define the amount of cols.
94+ * @param {string } label Attribute to specify the input text field hint.
95+ * @param {string= } ng-model Optional value to assign as existing input text string
96+ *
97+ * @usage
98+ * <hljs lang="html">
99+ * <md-textarea-float label="Intro" ng-model="user.intro" > </md-textarea-float>
100+ *
101+ * <!-- Specify the amount of rows and cols. -->
102+ * <md-textarea-float label="Company" ng-model="user.company" rows="4" cols="50" > </md-textarea-float>
103+ * </hljs>
104+ */
105+ function mdTextareaFloatDirective ( $mdTheming , $mdUtil ) {
106+ return {
107+ restrict : 'E' ,
108+ replace : true ,
109+ scope : {
110+ fid : '@?' ,
111+ label : '@?' ,
112+ rows : '@?' ,
113+ cols : '@?' ,
114+ value : '=ngModel'
115+ } ,
116+ compile : function ( element , attr ) {
117+
118+ if ( angular . isUndefined ( attr . fid ) ) {
119+ attr . fid = $mdUtil . nextUid ( ) ;
120+ }
121+
122+ return {
123+ pre : function ( scope , element , attrs ) {
124+ // transpose `disabled` flag
125+ if ( angular . isDefined ( attrs . disabled ) ) {
126+ element . attr ( 'disabled' , true ) ;
127+ scope . isDisabled = true ;
128+ }
129+
130+ // transpose optional `class` settings
131+ element . attr ( 'class' , attrs . class ) ;
68132
69133 } ,
70134 post : $mdTheming
71135 } ;
72136 } ,
73- template :
74- '<md-input-group ng-disabled="isDisabled" tabindex="-1" >' +
75- ' <label for ="{{fid}}" >{{label}}</label> ' +
76- ' <md-input id ="{{fid }}" ng-model="value" type="{{inputType }}"></md-input >' +
77- '</md-input-group>'
137+ template : '<md-input-group ng-disabled="isDisabled" tabindex="-1">' +
138+ ' <label for="{{fid}}" >{{label}}</label >' +
139+ ' <md-textarea id ="{{fid}}" ng-model="value" ' +
140+ ' rows ="{{rows }}" cols="{{cols }}"></md-textarea >' +
141+ '</md-input-group>'
78142 } ;
79143}
80144
@@ -99,12 +163,12 @@ function mdTextFloatDirective($mdTheming, $mdUtil) {
99163function mdInputGroupDirective ( ) {
100164 return {
101165 restrict : 'CE' ,
102- controller : [ '$element' , function ( $element ) {
103- this . setFocused = function ( isFocused ) {
166+ controller : [ '$element' , function ( $element ) {
167+ this . setFocused = function ( isFocused ) {
104168 $element . toggleClass ( 'md-input-focused' , ! ! isFocused ) ;
105169 } ;
106- this . setHasValue = function ( hasValue ) {
107- $element . toggleClass ( 'md-input-has-value' , hasValue ) ;
170+ this . setHasValue = function ( hasValue ) {
171+ $element . toggleClass ( 'md-input-has-value' , hasValue ) ;
108172 } ;
109173 } ]
110174 } ;
@@ -137,59 +201,111 @@ function mdInputDirective($mdUtil) {
137201 replace : true ,
138202 template : '<input >' ,
139203 require : [ '^?mdInputGroup' , '?ngModel' ] ,
140- link : function ( scope , element , attr , ctrls ) {
141- var inputGroupCtrl = ctrls [ 0 ] ;
142- var ngModelCtrl = ctrls [ 1 ] ;
143- if ( ! inputGroupCtrl ) {
144- return ;
145- }
204+ link : function mdInputDirectiveLink ( scope , element , attr , ctrls ) {
205+ linkBehaviours ( scope , element , ctrls , $mdUtil ) ;
146206
147- // scan for disabled and transpose the `type` value to the <input> element
148- var isDisabled = $mdUtil . isParentDisabled ( element ) ;
149-
150- element . attr ( 'tabindex' , isDisabled ? - 1 : 0 ) ;
151- element . attr ( 'aria-disabled' , isDisabled ? 'true' : 'false' ) ;
152- element . attr ( 'type' , attr . type || element . parent ( ) . attr ( 'type' ) || "text" ) ;
153-
154- // When the input value changes, check if it "has" a value, and
155- // set the appropriate class on the input group
156- if ( ngModelCtrl ) {
157- //Add a $formatter so we don't use up the render function
158- ngModelCtrl . $formatters . push ( function ( value ) {
159- inputGroupCtrl . setHasValue ( isNotEmpty ( value ) ) ;
160- return value ;
161- } ) ;
162- }
207+ element . attr ( 'type' , attr . type || element . parent ( ) . attr ( 'type' ) || "text" ) ;
208+ }
209+ } ;
210+ }
163211
164- element . on ( 'input' , function ( ) {
165- inputGroupCtrl . setHasValue ( isNotEmpty ( ) ) ;
166- } ) ;
167-
168- // When the input focuses, add the focused class to the group
169- element . on ( 'focus' , function ( e ) {
170- inputGroupCtrl . setFocused ( true ) ;
171- } ) ;
172- // When the input blurs, remove the focused class from the group
173- element . on ( 'blur' , function ( e ) {
174- inputGroupCtrl . setFocused ( false ) ;
175- inputGroupCtrl . setHasValue ( isNotEmpty ( ) ) ;
176- } ) ;
177-
178- scope . $on ( '$destroy' , function ( ) {
179- inputGroupCtrl . setFocused ( false ) ;
180- inputGroupCtrl . setHasValue ( false ) ;
181- } ) ;
182-
183-
184- function isNotEmpty ( value ) {
185- value = angular . isUndefined ( value ) ? element . val ( ) : value ;
186- return ( angular . isDefined ( value ) && ( value !== null ) &&
187- ( value . toString ( ) . trim ( ) != "" ) ) ;
188- }
212+ /*
213+ * @private
214+ *
215+ * @ngdoc directive
216+ * @name mdTextarea
217+ * @module material.components.textField
218+ *
219+ * @restrict E
220+ *
221+ * @description
222+ * Use the `<md-textarea>` directive as elements within a `<md-input-group>` container
223+ *
224+ * @usage
225+ * <hljs lang="html">
226+ * <md-input-group ng-disabled="user.isLocked">
227+ * <label for="i1">Intro</label>
228+ * <md-textarea id="i1" ng-model="user.intro"></md-textarea>
229+ * </md-input-group>
230+ * </hljs>
231+ */
232+ function mdTextareaDirective ( $mdUtil ) {
233+ return {
234+ restrict : 'E' ,
235+ replace : true ,
236+ template : '<textarea >' ,
237+ require : [ '^?mdInputGroup' , '?ngModel' ] ,
238+ link : function mdInputDirectiveLink ( scope , element , attr , ctrls ) {
239+ linkBehaviours ( scope , element , ctrls , $mdUtil ) ;
240+
241+ element . attr ( 'rows' , attr . rows || element . parent ( ) . attr ( 'rows' ) || "8" ) ;
242+ element . attr ( 'cols' , attr . cols || element . parent ( ) . attr ( 'cols' ) || "100" ) ;
189243 }
190244 } ;
191245}
192246
247+ /*
248+ * @private
249+ *
250+ * @ngdoc directive
251+ * @name mdTextarea
252+ * @module material.components.textField
253+ * @function
254+ *
255+ * @description
256+ * The link function used in the mdInput and mdTextarea
257+ *
258+ */
259+ function linkBehaviours ( scope , element , ctrls , $mdUtil ) {
260+ var inputGroupCtrl = ctrls [ 0 ] ;
261+ var ngModelCtrl = ctrls [ 1 ] ;
262+ if ( ! inputGroupCtrl ) {
263+ return ;
264+ }
265+
266+ // scan for disabled and transpose the `type` value to the <input> element
267+ var isDisabled = $mdUtil . isParentDisabled ( element ) ;
268+
269+ element . attr ( 'tabindex' , isDisabled ? - 1 : 0 ) ;
270+ element . attr ( 'aria-disabled' , isDisabled ? 'true' : 'false' ) ;
271+
272+ // When the input value changes, check if it "has" a value, and
273+ // set the appropriate class on the input group
274+ if ( ngModelCtrl ) {
275+ //Add a $formatter so we don't use up the render function
276+ ngModelCtrl . $formatters . push ( function ( value ) {
277+ inputGroupCtrl . setHasValue ( isNotEmpty ( value ) ) ;
278+ return value ;
279+ } ) ;
280+ }
281+
282+ element . on ( 'input' , function ( ) {
283+ inputGroupCtrl . setHasValue ( isNotEmpty ( ) ) ;
284+ } ) ;
285+
286+ // When the input focuses, add the focused class to the group
287+ element . on ( 'focus' , function ( e ) {
288+ inputGroupCtrl . setFocused ( true ) ;
289+ } ) ;
290+ // When the input blurs, remove the focused class from the group
291+ element . on ( 'blur' , function ( e ) {
292+ inputGroupCtrl . setFocused ( false ) ;
293+ inputGroupCtrl . setHasValue ( isNotEmpty ( ) ) ;
294+ } ) ;
295+
296+ scope . $on ( '$destroy' , function ( ) {
297+ inputGroupCtrl . setFocused ( false ) ;
298+ inputGroupCtrl . setHasValue ( false ) ;
299+ } ) ;
300+
301+
302+ function isNotEmpty ( value ) {
303+ value = angular . isUndefined ( value ) ? element . val ( ) : value ;
304+ return ( angular . isDefined ( value ) && ( value !== null ) &&
305+ ( value . toString ( ) . trim ( ) != "" ) ) ;
306+ }
307+ }
308+
193309
194310
195311
0 commit comments