Skip to content

Instantly share code, notes, and snippets.

@fesor
Created July 31, 2013 09:38
Show Gist options
  • Save fesor/6120750 to your computer and use it in GitHub Desktop.
Save fesor/6120750 to your computer and use it in GitHub Desktop.
Autogrow angular directive for textareas
app.directive('autogrow', function () {
// styles that influence on text
var props = [
'webkitBoxSizing', '-webkit-box-sizing', 'padding', 'font', 'width', 'textIndent',
'whiteSpace', 'wordSpacing', 'wordWrap', 'textAlign'
];
return {
restrict: 'A',
require: 'ngModel',
replace: false,
link: function ($scope, $element, attrs, ngModel) {
var $copy = $('<div></div>'),
minHeight = $element[0].clientHeight,
computedStyles = window.getComputedStyle($element[0]),
stylesheets = $copy[0].style,
val;
// copy styles of original element
props.forEach(function (prop) {
if (computedStyles.hasOwnProperty(prop)) {
stylesheets[prop] = computedStyles[prop];
}
});
// make out copy element invisible
$copy.css({
height: 'auto',
position: 'absolute',
top: '-9999px',
left: '-9999px'
});
$(document.body).append($copy);
function update() {
function times (string, number) {
for (var i = 0, r = ''; i < number; i++) {
r += string;
}
return r;
}
val = $element.val().replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/&/g, '&amp;')
.replace(/\n$/, '<br/>&nbsp;')
.replace(/\n/g, '<br/>')
.replace(/\s{2,}/g, function(space) { return times('&nbsp;', space.length - 1) + ' ' });
$copy.html(val);
$element.css('height', Math.max($copy[0].offsetHeight, minHeight) + 'px');
}
// update on value changed
// note: use throttle when you expect that value will change very frequently
$scope.$watch(function () {
return ngModel.$modelValue;
}, update);
$scope.$on('$destroy', function () {
// remove copy element on scope destroy
$copy.remove();
});
}
}
});
@fesor
Copy link
Author

fesor commented Jul 31, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment