How do I make the textarea automatically increase to a certain limit?

5

I'd like to know how best to make textarea increase automatically to the limit of 500px when the user enters content.

  

Do not use another library besides Jquery .

CSS:

textearea{
    resize: none; /* impede que o próprio usuário altere o tamanho do textarea */
    width:300px;
    height:100px;
    overflow-y: auto;
}
    
asked by anonymous 07.04.2014 / 05:45

5 answers

4

When the textarea is edited, by any means (keyboard, mouse, Ctrl + V , etc), check that your screen size is less than the size of your actual content (ie the content being served by the scroll bar) and increase the size of the element as long as it is.

$("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: this answer in SOen .

Example in jsFiddle . Notes:

    If you assign programmatically content of textarea , you should invoke the above code manually (because input does not do this for you);
  • The above code maybe can be improved to avoid this loop that increments one by one, but as the original response did so (and I'm out of time to test the alternatives) I preferred to leave it as it was.
    • Using outerHeight instead of simply height " is to account for padding (and optionally also margin ) instead of considering only content height. Maybe that's why the one-by-one increment, since otherwise the calculation would be more complex (and in practice, I did not notice any problems in perceived performance).
  • My alternative answer (in edit history) does not work in all cases, for several reasons. My attempts to calculate the size of the content by other means (eg using an auxiliary element) were also unsuccessful, so this was the most complete and simple solution I found.
07.04.2014 / 07:46
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 every time a letter is entered (when the key is released) or when text is copied to the textarea with the onpaste event.

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

Since @mgibsonbr mentioned the input event has advantages over keyup , it might be a good idea to use all three. input has the disadvantage that is not accepted in some browsers . IE being one of them.

    
07.04.2014 / 08:49
1

I made a small change to it back to the default size if the person gave up writing and erasing what he 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 deletes letter by letter, but in my case it was enough. I hope this can help someone else and thanks for the help they gave me with this code.

    
27.03.2017 / 02:10
0

// I gave a change to automatically get all of the form's textboxes and 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;
        }
    }
}
    
27.02.2015 / 21:45
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 (element_id, 20, 100);

    
21.06.2018 / 01:21