1+ ( function ( ) {
2+ 'use strict' ;
3+ angular . module ( 'angular-autogrow' , [ ] ) . directive ( 'autogrow' , [ '$window' , function ( $window ) {
4+ return {
5+ link : function ( $scope , $element , $attrs ) {
6+
7+ /**
8+ * Default settings
9+ */
10+ $scope . attrs = {
11+ rows : 1 ,
12+ maxLines : 999
13+ } ;
14+
15+ /**
16+ * Merge defaults with user preferences
17+ */
18+ for ( var i in $scope . attrs ) {
19+ if ( $attrs [ i ] ) {
20+ $scope . attrs [ i ] = parseInt ( $attrs [ i ] ) ;
21+ }
22+ }
23+
24+ /**
25+ * Calculates the vertical padding of the element
26+ * @returns {number }
27+ */
28+ $scope . getOffset = function ( ) {
29+ var style = $window . getComputedStyle ( $element [ 0 ] , null ) ,
30+ props = [ 'paddingTop' , 'paddingBottom' ] ,
31+ offset = 0 ;
32+
33+ for ( var i = 0 ; i < props . length ; i ++ ) {
34+ offset += parseInt ( style [ props [ i ] ] ) ;
35+ }
36+ return offset ;
37+ } ;
38+
39+ /**
40+ * Sets textarea height as exact height of content
41+ * @returns {boolean }
42+ */
43+ $scope . autogrowFn = function ( ) {
44+ var newHeight = 0 , hasGrown = false ;
45+ if ( ( $element [ 0 ] . scrollHeight - $scope . offset ) > $scope . maxAllowedHeight ) {
46+ $element [ 0 ] . style . overflowY = 'scroll' ;
47+ newHeight = $scope . maxAllowedHeight ;
48+ }
49+ else {
50+ $element [ 0 ] . style . overflowY = 'hidden' ;
51+ $element [ 0 ] . style . height = 'auto' ;
52+ newHeight = $element [ 0 ] . scrollHeight - $scope . offset ;
53+ hasGrown = true ;
54+ }
55+ $element [ 0 ] . style . height = newHeight + 'px' ;
56+ return hasGrown ;
57+ } ;
58+
59+ $scope . offset = $scope . getOffset ( ) ;
60+ $scope . lineHeight = ( $element [ 0 ] . scrollHeight / $scope . attrs . rows ) - ( $scope . offset / $scope . attrs . rows ) ;
61+ $scope . maxAllowedHeight = ( $scope . lineHeight * $scope . attrs . maxLines ) - $scope . offset ;
62+
63+ $element [ 0 ] . addEventListener ( 'input' , $scope . autogrowFn ) ;
64+ }
65+ }
66+ } ] ) ;
67+ } ) ( ) ;
0 commit comments