views:

65

answers:

3

I have a <textarea> that I want to grow by one row every time the user enters into the last row shown in the <textarea>. Is this possible?

I have seen it done before, but can't figure out how to do it.

+2  A: 

There are code and a demo at http://webdesign.torn.be/tutorials/javascript/prototype/auto-expand-contract-textarea/.

There's also a non-IE6 version that doesn't use frameworks: http://scrivna.com/blog/2008/04/12/javascript-expanding-textareas/

thejh
Are there any in jquery or just plain javascript? I do not know Prototype.
chromedude
+1  A: 

Yes, there are many plugins for JQuery, such as this one, which comes with a demo: http://james.padolsey.com/javascript/jquery-plugin-autoresize/

Very customizable in terms of maximum height, buffer space, etc.

Christian Mann
That's good, I just would like to be able to do it without using a plugin.
chromedude
+3  A: 

Okay, I just created this off the top of my head, so there may be browser compatibility issues. The concept is pretty simple however. Basically, on every keyup event, append a newline to the current text in the textarea element, then check if scrollHeight is greater than offsetHeight. If this is the case, set the elements height to be equal to scrollHeight. After all this, remove the appended newline. Assuming your textarea element has the id ta:

EDIT -- Okay, my original idea caused the cursor position to jump to the end of the text even if the user moved the cursor back, not good. The fix I came up with involves creating an invisible clone of the text area, and inserting the extra newline in that one, as to not disturb the cursor position in the visible one. Not sure I'm enterily comfortable with this method, but it works for now. If there is a better method I'd be happy to hear it. Here's the updated code:

var shadow = document.createElement('textarea');
shadow.className = 'autosize';
shadow.style.visibility = 'hidden';

document.getElementById('ta').onkeyup = function() {

  this.parentNode.appendChild(shadow);
  shadow.value = this.value + '\n';

  if (shadow.scrollHeight > shadow.offsetHeight) {
    this.style.height = shadow.scrollHeight + 'px';
  }

  this.parentNode.removeChild(shadow);

};

And the updated test http://jsfiddle.net/7wezW/1/

Now back to your regular programming...

Works well in Chrome, if someone points out issues in other browsers, I will try work them out.

PS, I should point out that if the user pastes text using just the mouse, the size of the textarea element will not adjust. Should be a trivial issue, but I'll leave it out as not to over-complicate things.

MooGoo
Wow! Thats phenomenal! I am using jquery but hopefully I will be able to duplicate it. Thanks
chromedude
Hey chromedude, I did just pick up an issue with this method. If you try to click back in the text area and type, the cursor will jump to the end. Pretty annoying, lemme see if I can fix it.
MooGoo