Is there a jQuery autogrow plugin for text fields?

JavascriptJqueryScripting

Javascript Problem Overview


I have found various plugins for auto-growing a textarea, but not input text fields. Does anybody know if any exist?

Javascript Solutions


Solution 1 - Javascript

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://jsfiddle.net/rRHzY

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, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    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);

Solution 2 - Javascript

I have a jQuery plugin on GitHub: https://github.com/MartinF/jQuery.Autosize.Input

It uses the same approach as James answer but have some of the changes mentioned in the comments.

You can see an live example here: http://jsfiddle.net/mJMpw/6/

Example:

<input type="text" value="" placeholder="Autosize" data-autosize-input='{ "space": 40 }' />

input[type="data-autosize-input"] {
  width: 90px;
  min-width: 90px;
  max-width: 300px;
  transition: width 0.25s;    
}

You just use css to set min/max-width and use a transition on the width if you want a nice effect.

You can specify the space / distance to the end as the value in json notation for the data-autosize-input attribute on the input element.

Of course you can also just initialize it using jQuery

$("selector").autosizeInput();

Solution 3 - Javascript

Good plugin, thank you! I changed two things that seemed to work better in my project though.

  1. 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?
  2. 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.

Solution 4 - Javascript

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.

Solution 5 - Javascript

I'd also replaced

$(this).bind('keyup keydown blur update', check)

to

$(this).bind('keyup blur update', check).bind('keydown', function() {
    setTimeout(check);
});

in order to get the field resized right after it was re-rendered by browser. It would rid the field from some chattering.

Solution 6 - Javascript

I have create a plugin for the input of type text, that recreates this behaviour. It has some other unique features. You can see an example and view the documentation of the plugin. @james answer has some problems with pasting large text into the input. To fix it, I have made some modifications to his code. Here is a demo, for this example.

(function($){        
    $.fn.autoGrowInput = function(o) {
        
        o = $.extend({
            maxWidth: 200,
            minWidth: 1,
            comfortZone: 1,
          width: 1
        }, o);
        
        this.filter('input:text').each(function(){
            
            var minWidth = o.minWidth || $(this).width(),
                maxWidth = o.maxWidth,
                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, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                    testSubject.html(escaped);
                    
                    // Calculate new width + whether to change
                    var testerWidth = testSubject.width(),
                    newWidth = testerWidth + o.comfortZone,
                    currentWidth = input.width();
                    
                   if (testerWidth < minWidth) {
                       newWidth = minWidth;
                   } else if (testerWidth > maxWidth) {
                       newWidth = maxWidth;
                   } 

                   input.width(newWidth + o.comfortZone);  
            };
                
            testSubject.insertAfter(input);
            
            $(this).bind('input', check);
            
        });
        
        return this;
    
    };
    
})(jQuery);

Solution 7 - Javascript

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>

Solution 8 - Javascript

Funny enough in IE overflow: visible is taken very seriously. You can achieve this effect by applying overflow: visible on your input elements. Not sure if any similar CSS tricks exist for modern browsers.

Solution 9 - Javascript

Awsome plugin James ! Thanks. I did add the check suggestion in the end by JP though very effective .

Also I added a some changes on my part. I wanted to set the size for the input to the maximum size if the changed width exceeded the maxWidth so I added :

else if (widthexceeds){
    input.width(o.maxWidth);
}

below the if check for isValidWidthChange where widthexceeds = newWidth > o.maxWidth

Solution 10 - Javascript

I created a plugin called input-autogrow to solve this problem for my own projects. This plugin was originally based off of James answer but has been improved in many ways.

https://github.com/westonganger/input-autogrow

input-autogrow is a plugin for autogrowing inputs. This plugin is different from others because most usually target textarea tags, this library is instead targeted at input tags. Requires a DOM library such as jQuery, Zepto, or any that supports $.fn plugins.

Here are some usage examples.

/* Makes elements readonly if they already have the readonly attribute */
$('input.autogrow').inputAutogrow();

/* Manually trigger update */
$('input.autogrow').trigger('autogrow');
/* or */
$('input.autogrow').trigger('change');

/* Custom Options */
$('input.autogrow').inputAutogrow({maxWidth: 500, minWidth: 25, trailingSpace: 10});

/* Remove autogrow from input */
$('input.autogrow').inputAutogrow('destroy');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrad GesslerView Question on Stackoverflow
Solution 1 - JavascriptJamesView Answer on Stackoverflow
Solution 2 - JavascriptMartinFView Answer on Stackoverflow
Solution 3 - JavascriptJP.View Answer on Stackoverflow
Solution 4 - JavascriptMichaelView Answer on Stackoverflow
Solution 5 - JavascriptSergei MorozovView Answer on Stackoverflow
Solution 6 - JavascriptajorqueraView Answer on Stackoverflow
Solution 7 - JavascriptBraedenPView Answer on Stackoverflow
Solution 8 - JavascripttbranyenView Answer on Stackoverflow
Solution 9 - JavascriptSnigdha BatraView Answer on Stackoverflow
Solution 10 - JavascriptWeston GangerView Answer on Stackoverflow