I have a found various plugins for autogrowing a textarea, but not input text fields. Does anybody know if any exist?
If you want the textbox to grow when the string within it extends past its width, maybe something like this would work for you... It detects the size attribute of the textbox. If the length of the string goes over that attribute, it extends the textbox to the length of the string on keyup.
In the below script, "#test" is a textbox ID.
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$("#test").keyup(function(){
if($("#test").attr("size") < $("#test").val().length){
size = $("#test").val().length;
$("#test").attr("size",size);
}
})
});
</script>
Here's a plugin that'll do what you're after:
EDIT: I've fixed the plugin as per Mathias' comment. :)
See a demo here: http://jsbin.com/ahaxe
The plugin:
(function($){
$.fn.autoGrowInput = function(o) {
o = $.extend({
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
}, o);
this.filter('input:text').each(function(){
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
testSubject = $('<tester/>').css({
position: 'absolute',
top: -9999,
left: -9999,
width: 'auto',
fontSize: input.css('fontSize'),
fontFamily: input.css('fontFamily'),
fontWeight: input.css('fontWeight'),
letterSpacing: input.css('letterSpacing'),
whiteSpace: 'nowrap'
}),
check = function() {
if (val === (val = input.val())) {return;}
// Enter new content into testSubject
var escaped = val.replace(/&/g, '&').replace(/\s/g,' ').replace(/</g, '<').replace(/>/g, '>');
testSubject.html(escaped);
// Calculate new width + whether to change
var testerWidth = testSubject.width(),
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
currentWidth = input.width(),
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth && newWidth < o.maxWidth);
// Animate width
if (isValidWidthChange) {
input.width(newWidth);
}
};
testSubject.insertAfter(input);
$(this).bind('keyup keydown blur update', check);
});
return this;
};
})(jQuery);
Good plugin, thank you! I changed two things that seemed to work better in my project though.
- I changed the TESTER tag to a DIV, to avoid getting 'Unexpected call to method or property access.' in IE8 (even though your demo does work in IE8. Was there a particular reason for for using a custom HTML tag?
- After the bind statement near the end of the code, I added a call to check(), in order to resize the textbox immediately after loading the page, in case the textbox already has content in it on startup.
Hope this helps.
Hi there, just wanted to share a small improvement to James's great plugin. Add this code to the CSS declaration for the tester element to account for text-indent:
textIndent: 0
Without it, in some situations the tester element may inadvertently inherit the text-indent from elsewhere, thus throwing off the size of the input.
Like JP, I also wanted to resize the input to the correct size from the beginning, which I did just slightly differently, by chaining "trigger('keyup')" to the autoGrowInput method call, e.g.:
$('#contact_form').autoGrowInput({comfortZone: 7, minWidth: 10, maxWidth: 200}).trigger('keyup');
As a side note, I signed up to this site purely to comment on James's solution and I'm a bit annoyed to find that I can't because I don't have enough reputation points to start with. Sorry if I've missed something, but that seems to mean that I have to post this is a comment on the main question rather than more appropriately on James's solution.