Last active
December 26, 2015 12:49
-
-
Save typeofweb/7153571 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* Works nicely with the following styles: | |
* textarea { | |
* resize: none; | |
* transition: height 0.1s; | |
* } | |
* | |
* Usage: <textarea autoexpand></textarea> | |
*/ | |
'use strict'; | |
angular.module('app') | |
.directive('autoexpand', ['$timeout', function ($timeout) { | |
return function (scope, element) { | |
var maxHeight = element.css('max-height') || 1e9; | |
var $shadow = $('<div/>'); | |
$shadow.appendTo('body'); | |
$shadow.css({ | |
'white-space': 'pre-wrap', | |
'font-family': element.css('font-family'), | |
'font-size': element.css('font-size'), | |
'padding': element.css('padding'), | |
'word-wrap': 'break-word', | |
'line-height': element.css('line-height'), | |
top: -1000, | |
left: -1000, | |
'position': 'absolute' | |
}); | |
var update = function () { | |
var val = element.val().replace('\n', '<br>'); | |
$shadow.html(val); | |
$shadow.width(element.width()); | |
$timeout(function () { | |
var height = $shadow.outerHeight() + 15; | |
if (height > maxHeight) { | |
height = maxHeight; | |
} | |
element.css({height: height}); | |
}, 0); | |
}; | |
element.bind('change keyup keydown keypress ', update); | |
scope.$on('$destroy', function () { | |
$shadow.remove(); | |
}); | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
describe('Autoexpand directive', function () { | |
var $scope, $compile; | |
beforeEach(module('app')); | |
beforeEach(inject(function (_$rootScope_, _$compile_) { | |
$scope = _$rootScope_; | |
$compile = _$compile_; | |
})); | |
describe('textarea', function () { | |
var compileTa = function (markup, scope) { | |
var $el = $compile(markup)(scope); | |
scope.$digest(); | |
return $el; | |
}; | |
var shadow; | |
afterEach(function () { | |
shadow.remove(); | |
}); | |
it('should copy text to the shadow element', function () { | |
var ta = compileTa('<textarea autoexpand>text</textarea>', $scope); | |
shadow = angular.element('body').find('div').last(); | |
ta.trigger('keypress'); | |
expect(shadow.text()).toEqual('text'); | |
ta.text('lol wut xD'); | |
ta.trigger('keypress'); | |
expect(shadow.text()).toEqual('lol wut xD'); | |
}); | |
it('should replace \\n with <br>', function () { | |
var ta = compileTa('<textarea autoexpand>text1\ntext2</textarea>', $scope); | |
shadow = angular.element('body').find('div').last(); | |
ta.trigger('keypress'); | |
expect(shadow.html()).toEqual('text1<br>text2'); | |
}); | |
it('should increase height of the textarea while typing', inject(function ($timeout) { | |
var ta = compileTa('<textarea autoexpand>t\nt\nt\nt\nt\nt\nt\n</textarea>', $scope); | |
ta.appendTo('body'); | |
ta.css({ | |
'width': '10px' | |
}); | |
shadow = angular.element('body').find('div').last(); | |
ta.trigger('keypress'); | |
$timeout.flush(); | |
expect(shadow.width()).toBe(10); | |
var oldHeight = ta.height(); | |
expect(oldHeight).toBe(shadow.height() + 15); | |
ta.html('a\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\na'); | |
ta.trigger('keypress'); | |
$timeout.flush(); | |
var newHeight = ta.height(); | |
expect(newHeight).not.toEqual(oldHeight); | |
expect(newHeight).toBe(shadow.height() + 15); | |
})); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment