Search code examples
javascriptjquerycssajaxauto-increment

Change height of a textarea after ajax success function


There is a textarea in my code used to show the message responded from the backend. And I want to increase the height automatically when the length of contents is so long that appearing a scrollbar. here is my code:

$.ajax({
    type: 'POST',
    async: false,
    url: '/text_translation',
    data: JSON.stringify(data),
    success: function(returnStr) {
        $.each(returnStr,function(item, value) {
            returnString.html(returnString.html() + value + '\n');//show message
        });

        console.log(returnString.clientHeight);//undefined

        //if message too long, increase the height 
        if (returnString.clientHeight < returnString.scrollHeight) {
            returnString.css('height', 'auto').css('height', returnString.scrollHeight + (returnString.offsetHeight - returnString.clientHeight));    
        }

}

At first, because ajax is asynchronous, I set the "async" as "false" to ensure the change can be executed after the each function, but it also can't work. I tried to print the clientHeight, it showed "undefined" no matter async was false or true. Doesn't setting false mean that the statement I'm calling has to complete before the next statement in my function can be called? I've been confused to the result, which was a specific number I thought.

And then I tried to use the "input" event function like this:

returnString.on('input',function() {
    if (this.clientHeight < thhis.scrollHeight) {
        $(this).css('height', 'auto').css('height', this.scrollHeight + (this.offsetHeight - this.clientHeight));
    }
});

Nothing changed.

I must do something wrong, but I don't know where is it. Please tell me the reason, thanks for your answer first.


Solution

  • Have a look here for how async works with $.ajax, because you're using the success callback, I don't think it affects how your code works in this scenario.

    To resize the text area, I found this answer useful and have created a function where you pass in the textarea element below.

    $("button").click(() => {
    
      let returnStr = "Test\n\nTest\n\nTest\n\nTest\n\nTest\n\nTest";
    
      $("textarea").val(returnStr);
      resizeTextareaHeight($("textarea")[0]);
    });
    
    function resizeTextareaHeight(textarea) {
      while ($(textarea).outerHeight() < textarea.scrollHeight + parseFloat($(textarea).css("borderTopWidth")) + parseFloat($(textarea).css("borderBottomWidth"))) {
        $(textarea).height($(textarea).height() + 1);
      };
    }
    textarea {
      overflow-y: hidden;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div>
    
      <button type="button">Pretend Ajax Call</button>
    </div>
    <div>
    
    
      <textarea></textarea>
    </div>