How to make the textarea automatically increase height to a certain limit?

Asked

Viewed 6,692 times

5

I would like to know the best way to get the textarea automatically increase height to the limit of 500px when the user enters content.

Do not use another library other than Jquery.

CSS:

textearea{
    resize: none; /* impede que o próprio usuário altere o tamanho do textarea */
    width:300px;
    height:100px;
    overflow-y: auto;
}
  • has a jquery plugin q does this

  • @user3230262 And what is the plugin? I’ve seen that the answer is far from trivial, so external references would help a lot...

5 answers

5


Whenever the textarea is edited by any means (keyboard, mouse, Ctrl+V, etc), check that your screen size is smaller than your actual content (i.e. the content being served by the scrollbar) and, while it is, increase the size of the element.

$("textarea").bind("input", function(e) {
    while( $(this).outerHeight() < this.scrollHeight +
                                   parseFloat($(this).css("borderTopWidth")) +
                                   parseFloat($(this).css("borderBottomWidth"))
           && $(this).height() < 500 // Altura máxima
    ) {
        $(this).height($(this).height()+1);
    };
});

Source: that answer in Soen.

Example in jsFiddle. Notes:

  • If you assign programmatically the content of textarea, should call the above code manually (as the input doesn’t do it for you);
  • The code above maybe can be improved to avoid this loop that increments one by one, but as the original answer did so (and I’m running out of time to test the alternatives) I decided to leave as was.
    • The use of outerHeight instead of simply height is to take into account the padding (and optionally also the margin) instead of considering only the height of the content. Perhaps that is why the increment of one in one, since otherwise the calculation would be more complex (and in practice, I noticed no problem in the perceived performance).
  • My alternative answer (in editing history) does not work in all cases, for various reasons. My attempts to calculate content size by other means (e.g., using an auxiliary element) were also unsuccessful, so this was the most complete and simple solution I found.
  • 1

    I liked your solution for the detail that prevents the scroll bar to appear while the textarea size does not reach 500px, so I will assign as best answer, although it does not work in IE. I’m still studying both codes to make improvements, thanks for the collaboration.

5

Here’s another idea:

$('#texto').on('keyup onpaste', function () {
    var alturaScroll = this.scrollHeight;
    var alturaCaixa = $(this).height();

    if (alturaScroll > (alturaCaixa + 10)) {
        if (alturaScroll > 500) return;
        $(this).css('height', alturaScroll);
    }
});

Example

This code runs each time a letter is inserted (when the key is released) or when text is copied to the textarea with the event onpaste.

When the key is raised the code reads the height of the Scroll and the box. If the scroll is larger then makes the box increase to 500.

How @mgibsonbr referred to the event input has advantages over the keyup, maybe it’s a good idea to use all three. The input has the disadvantage of not be accepted in some browsers. IE being one of them.

  • The advantage of input about keyup (in theory, at least) is that if you hold a key and do not release more, the textarea is being filled but the height does not increase. And if it goes beyond 500 While you’re doing this, it doesn’t go any higher - take the one that was at that moment.

  • 1

    @mgibsonbr, good suggestion! I added this idea to the answer, thank you and I mentioned that IE (not to escape the tradition) does not deal well with the input.

  • I don’t know if you and @mgibsonbr qualify as technical repair (gambiarra) this, but I would use an approximation of the simplest possible, and a timer for fallback (take, 3 seconds up).

  • @Bacco I think it depends on your goals. I liked the code of my answer because it is quite accurate and does not give any visual Glitch. But surely many people would be horrified to see a loop that increases from one to one...

  • @mgibsonbr now you need to invent one that will decrease if the text is cut :)

1

I made a small change for it to return to the default size if the person gives up writing and deletes what they had written leaving the textarea empty. In my case the height is 40px.

$('textarea[name="responder"]').on('keyup change onpaste', function () {
    var alturaScroll = this.scrollHeight;
    var alturaCaixa = $(this).height();

    if (alturaScroll > (alturaCaixa + 10)) {
        if (alturaScroll > 500) return;
        $(this).css('height', alturaScroll);
    }

    if( $(this).val() == '' ){
        // retonando ao height padrão de 40px
        $(this).css('height', '40px');
    }
});

Unfortunately I could not make it decrease gradually when the person is deleting letter by letter, but in my case it was enough. I hope this can help someone else and thank you for the help you’ve given me with this code.

0

Complete solution with minimum and maximum height and solving problems with scroll:

var textarea =
{
    tornarFlex:
        function (id_textarea, altura_minima, altura_maxima)
        {
            var textarea = document.getElementById(id_textarea);
            if (typeof altura_minima == 'undefined')
            {
                altura_minima = textarea.offsetHeight;
            }
            if (typeof altura_maxima == 'undefined')
            {
                altura_maxima = 0;
            }
            textarea.style.height = altura_minima + 'px';
            textarea.addEventListener('keyup', new Function("textarea.ajusta('" + id_textarea + "'," + altura_minima + ", " + altura_maxima + ");"));
        },
    ajusta:
        function(id_textarea, altura_minima, altura_maxima)
        {
            var textarea = document.getElementById(id_textarea);
            while 
            (
                textarea.offsetHeight < textarea.scrollHeight 
                && (!altura_maxima || textarea.offsetHeight < altura_maxima)
            )
            {
                textarea.style.height = (textarea.offsetHeight + 1) + 'px';
            };
            if (textarea.offsetHeight < altura_maxima)
            {
                textarea.style.overflowX = 'hidden';
                textarea.style.overflowY = 'hidden';
            }
            else
            {
                textarea.style.overflowX = 'visible';
                textarea.style.overflowY = 'visible';
            }
        }
};

textarea.tornarFlex(id_elemento, 20, 100);

0

//I changed it to automatically take all textboxes of the form and do the Resizer.

function ResizeTextArea(){ 
    for (var j=1; j < form.length-1; j++){
        if (form[j].type=="textarea"){

            txtBox = form[j];
            nCols = txtBox.cols;
            sVal = txtBox.value;
            nVal = sVal.length;

            nRowCnt = 1;

            for (i=0;i<nVal;i++){ 
                if ((sVal.charAt(i).charCodeAt(0) == 13) || (sVal.charAt(i).charCodeAt(0) == 10)){ 
                    nRowCnt = nRowCnt +1;
                } 
            }

            if (nRowCnt < (nVal / nCols)) {
                nRowCnt = 2 + (nVal / nCols); 
            }
            if (nVal == 0){
                nRowCnt = 1; 
            }
            txtBox.rows = nRowCnt;
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.