Walrus
Walrus

Reputation: 20484

Simple jQuery textarea expand to fit content

In my attempt to build a simple cross browser expanding text area I found that all plugins seam far too overly cluttered.

I developed this:

$(document).ready(function() {
    $('textarea').keyup(function() {
        var txtheight = this.scrollHeight;
        $(this).height(txtheight)
    });
    $('textarea').keyup();
});​

It is producing unexpected results.

On FIREFOX it is working but if I delete lines from the textarea it does not reduce in size.

On CHROME the presseing of any key leads to another line height being added.

This is extremely confusing because if instead I change the code to this:

$(document).ready(function() {
    $('textarea').keyup(function() {
        var txtheight = this.scrollHeight;
       alert(txtheight); 
    });
    $('textarea').keyup();
});​

The alert gets the number correct every single time on both Browsers. What the hell is going on?

Upvotes: 0

Views: 3537

Answers (3)

Language Lassi
Language Lassi

Reputation: 2630

I know its too late to answer the thread but you'll get a solution cooked enough :)

I just binded two events on textarea and thats all.

$('textarea').keypress(function (e) {
  // check if user pressed 'Enter'
  if(e.which == 13) 
  {
   // get control object to modify further
   var control = e.target;

    // get existing 'Height' of pressed control
   var controlHeight = $(control).height();

   //add some height to existing height of control, I chose 17 as my line-height was 17 for the control 
   $(control).height(controlHeight+17);
  }
});

$('textarea').blur(function (e) {

    // Here we get exact number of lines in our TextArea
    var textLines = $(this).val().trim().split(/\r*\n/).length; 

    // Now apply the number Of Lines * line-height to your control. That's all.
    $(this).val($(this).val().trim()).height(textLines*17);
});

It will grow your textbox while adding content in it, and also removes extra whitespaces ata the end. Check it out an example and fiddle

Upvotes: 0

David Thomas
David Thomas

Reputation: 253496

Here's one approach that seems to work:

​$('#test').on('keydown', function(e){
    var that = $(this);
    if (that.scrollTop()) {
        $(this).height(function(i,h){
            return h + 20;
        });
    }
});​​​​​​​​

JS Fiddle demo.

Amended the above, in a slightly complicated manner but with, I think, proper accuracy:

function heightComparison(el) {
    if (!el) {
        return false;
    }
    else {
        var $el = $(el),
            clone = $('#' + el.id + '-clone'),
            cH = clone.height();

        $el.height(cH);

    }
}

$('#test').on('keyup paste', function(e) {
    var that = this,
        $that = $(that),
        clone = $('#' + that.id + '-clone').length ? $('#' + that.id + '-clone') : $('<div />', {
            'id': that.id + '-clone'
        }).css({
            'position': 'absolute',
            'left': '-1000px',
            'border-width': '1px',
            'border-color': '#000',
            'border-style': 'solid',
            'overflow': 'hidden',
            'width': $that.width(),
            'min-height': $that.height(),
            'padding': $that.css('padding'),
            'font-size': $that.css('font-size'),
            'font-family': $that.css('font-family')
        }).appendTo('body');

    clone.text($that.val());

    heightComparison(that);
});​

JS Fiddle demo.

Upvotes: 3

Walrus
Walrus

Reputation: 20484

Would not this work:

$(document).ready(function() {
    $('textarea').keyup(function() {
       var txtheight = $(this).scrollTop();
       $(this).css('height',($(this).height() + txtheight) + 'px')
    });
    $('textarea').keyup();
});

Simple effective solution.

Upvotes: 2

Related Questions