Created
January 19, 2014 22:22
-
-
Save lukas-shawford/8511762 to your computer and use it in GitHub Desktop.
Auto Expanding/Grow input directive for AngularJS This is the single-line <input> analogue of this gist:
https://gist.github.com/thomseddon/4703968 Original jQuery implementation here:
http://jsbin.com/ahaxe
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
/* | |
* Auto-expanding textbox directive for single-line <input> controls. | |
* | |
* This is adapted from: https://gist.github.com/thomseddon/4703968 | |
* | |
* See the above link for auto-growing multiline <textarea> controls, a similar but slightly | |
* different objective. | |
* | |
* The original, pure jQuery (and non-AngularJS) version of this can be found here: | |
* http://jsbin.com/ahaxe | |
* | |
* Usage example: | |
* <input type="text" auto-grow max-width="500"></input> | |
*/ | |
app.directive('autoGrow', function () { | |
return function(scope, element, attr) { | |
var opts = { | |
maxWidth: parseInt(attr.maxWidth) || 1000, | |
minWidth: parseInt(attr.minWidth) || element.width(), | |
comfortZone: parseInt(attr.comfortZone) || 20 | |
}; | |
var minWidth = opts.minWidth; | |
var val = ''; | |
var input = element; | |
var $shadow = angular.element('<div></div>').css({ | |
position: 'absolute', | |
top: -10000, | |
left: -10000, | |
width: 'auto', | |
fontSize: element.css('fontSize'), | |
fontFamily: element.css('fontFamily'), | |
fontWeight: element.css('fontWeight'), | |
letterSpacing: input.css('letterSpacing'), | |
whitespace: 'nowrap' | |
}); | |
$shadow.insertAfter(element); | |
var update = function() { | |
if (val === (val = input.val())) {return;} | |
// Enter new content into the shadow element | |
var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>'); | |
$shadow.html(escaped); | |
// Calculate new width + whether to change | |
var testerWidth = $shadow.width(), | |
newWidth = (testerWidth + opts.comfortZone) >= minWidth ? testerWidth + opts.comfortZone : minWidth, | |
currentWidth = input.width(), | |
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth) | |
|| (newWidth > minWidth && newWidth < opts.maxWidth); | |
// Animate width | |
if (isValidWidthChange) { | |
input.width(newWidth); | |
} | |
if (newWidth >= opts.maxWidth) { | |
input.width(opts.maxWidth); | |
} | |
} | |
if (attr.ngModel) { scope.$watch(attr.ngModel, update); } | |
else { element.bind('keyup keydown keypress change', update); } | |
update(); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment