42

How do I auto-resize the input type="text" field with jQuery? I want it to be like 100px wide at the start, then make it auto-widening as user inputs text... is that possible?

migajek
  • 8,524
  • 15
  • 77
  • 116

9 Answers9

64

Here's a plugin that'll do what you're after:

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,' ').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);

EDIT: Found on: Is there a jQuery autogrow plugin for text fields?

Community
  • 1
  • 1
seize
  • 853
  • 6
  • 6
  • 3
    just an observation, this plugin doesn't work when pasting text, and also prevents the user from pressing down and holding a single key. – Dennis Plucinik Jun 26 '12 at 20:13
  • Why not directly do `testSubject.text(val)` instead of escaping `val`? – Gautham Badhrinathan Aug 30 '12 at 21:55
  • @DennisPlucinik adding a bind to the `input` event should help fix the pasting issue – philfreo Mar 07 '13 at 18:49
  • 9
    Downvoted -1 [This is a exact cut/paste of someone else's answer](http://stackoverflow.com/questions/931207/is-there-a-jquery-autogrow-plugin-for-text-fields). Plus, **demo (also not OPs) was created with free/anon jsbin account and has timed-out - no longer available.** *Please use jsFiddle instead.* – cssyphus Dec 08 '14 at 18:55
11

I don't think there is a perfect solution to that problem because you cannot detect the actual width of the text entered to the input element. It all depends of the font you are using, zoom settings in browser etc.

However if you can choose a font where you can actually calculate the number of pixels that text have (this is the hardest part but I guess you can try to estimate it somehow). You can use this to change the width of your input field.

 $('input').keyup(function () {
     // I'm assuming that 1 letter will expand the input by 10 pixels
     var oneLetterWidth = 10;

     // I'm also assuming that input will resize when at least five characters
     // are typed
     var minCharacters = 5;
     var len = $(this).val().length;
     if (len > minCharacters) {
         // increase width
         $(this).width(len * oneLetterWidth);
     } else {
         // restore minimal width;
         $(this).width(50);
     }
 });
Owen Versteeg
  • 342
  • 2
  • 14
RaYell
  • 69,610
  • 20
  • 126
  • 152
  • +1 for simple, concise code that actually works! – Vael Victus Jan 16 '13 at 22:10
  • 1
    This small snippet was all I needed. I also added two simple css rules so that expanding and contracting appears better to the user: transition: width 0.4s; -webkit-transition: width 0.4s; /* Safari */ – Hallgeir Engen Dec 05 '13 at 08:39
9

(Edited: using the .text() method instead of .html() to get all formatting right.)

Hello I dont know if you are still looking but i came across this when i was looking for a script to do the same thing. So hope this helps anyone who is trying to do this, or something similar.

function editing_key_press(e){
    if(!e.which)editing_restore(this.parentNode);
    var text = $('<span>')
        .text($(this).val())
        .appendTo(this.parentNode);
    var w = text.innerWidth();
    text.remove();
    $(this).width(w+10);
}

The logic to this code is to put the content onto the page in a span and then gets the width of this content and removes it. The problem i did have was with it was that i had to get it to run on both keydown and keyup for it to work successfully.

Hope this helps, Might not as i have only been doing jquery for a short amount of time.

Thanks

George

Yaakov Belch
  • 4,692
  • 33
  • 39
thor222
  • 91
  • 1
  • 1
6

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

It uses the same approach as seize's 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();
MartinF
  • 5,929
  • 5
  • 40
  • 29
2

I used seize's answer, but made these changes:

  • Between setting isValidWidthChange and // Animate width:

    if (!isValidWidthChange && newWidth > minWidth && newWidth > o.maxWidth) {
        newWidth = o.maxWidth;
        isValidWidthChange = true;
    }
    

    This way the input will grow as big as you've allowed it when its contents are too big to fit within the max width.

  • After $(this).bind('keyup keydown blur update', check);:

    // Auto-size when page first loads
    check();
    
Community
  • 1
  • 1
Sarah Vessels
  • 30,930
  • 33
  • 155
  • 222
1

Try this code:

var newTextLength = Math.floor($("input#text).val() * .80);
$("input#text").attr("size",newTextLength);
Anonymous Penguin
  • 2,027
  • 4
  • 34
  • 49
1

See this jQuery plugin: https://github.com/padolsey/jQuery.fn.autoResize

I just tested it out with textareas and it works! Supports auto-growing of textareas, input[type=text] and input[type=password].

UPD. Looks like the original author removed the repo from github. The plugin hasn't been updated in a long while and turned out to be quite buggy. I can only suggest you to find a better solution. I made a pull request to this plugin sometime ago so I have a copy of it in my github account, use it only in case you want to improve it, it's not bulletproof!

Also, I found that ExtJS framework has autosize implementation for text fields, see the grow config property. While it's not that easy to carve this little piece of logic out of the framework, it can give you some good ideas on the approach.

Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
0

I was just thinking about the same thing. Textbox should resize it self as user is writing text into it. I never used it, but I have an idea how to do it. Something like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=windows-1250">
  <meta name="generator" content="PSPad editor, www.pspad.com">
  <title></title>
  </head>
  <body>

  <table border="1">
  <tr>
    <td>
      <span id="mySpan">
        <span id="mySpan2"></span>
        <input id="myText" type="text" style="width:100%" onkeyup="var span = document.getElementById('mySpan2');var txt = document.getElementById('myText'); span.innerHTML=txt.value;">
       </span>
    </td>
    <td>
            sss
    </td>
  </tr>
</table>

  </body>
</html>
Racky
  • 1,173
  • 18
  • 24
0

By default, input width is controlled by the size parameter, which for type="text" corresponds to number of characters wide it should be.

Since this is measured in characters and not pixels, the actual pixel size is controlled by the (fixed-width) font in use.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • If you set up a width for the input in CSS when changing the size parameters will not have any effect on the actual element width. – RaYell Aug 17 '09 at 14:49