1

I'm trying to create an autosize function where it resizes the textarea height based on the text context. However the content comes from the input elements from the form, so the user will enter it in the form. For example:

<input placeholder="name" value=""/>
<input placeholder="address" value=""/>
<input placeholder="company" value=""/>
<input placeholder="telephone" value=""/>
<textarea value={this.getFinalSentence()}></textarea>

So in this case, the user will enter its information on the input element. Say, the textarea min-height: 40px, if the information data is longer then textarea height it will increase.

Has anyone encountered this problem? So far I was able to resize the textarea if user edits the textarea, but not from the inputs. Your help will be appreciated.

medev21
  • 2,469
  • 8
  • 31
  • 43
  • instead of the `textarea`, use a `p` or `div` with contenteditable. P and div resize like you want. Add change/keyup/focus listeners to your p/div and copy the text into the value of an `` – ControlAltDel Nov 12 '19 at 19:16

4 Answers4

1

You need to listen to content change, and update textarea height to the scrollHeight.

Working snippet on: https://jsfiddle.net/0zsd3nty/

<textarea id ="content">some text</textarea>

document.getElementById("content").addEventListener("keyup", function() {
  let scrollHeight = this.scrollHeight;
  let height = this.clientHeight;

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

Similar solution also on: jQuery / JS get the scrollbar height of an textarea

smartilabs
  • 121
  • 1
  • 3
  • this works if I edit the textarea. What i need is if the user edits the input element and its data is large, then the textarea should autoresize – medev21 Nov 12 '19 at 20:39
  • Ok, if I understand correctly, users fill inputs, then you combine text and enter it into textarea? This should be quite simple - after calling getFinalSentence() function, also call let textarea = document.getElementById("content"); textarea.style.height = (textarea.scrollHeight) + 'px'; – smartilabs Nov 12 '19 at 20:50
  • yes, you got my point. Not sure if I follow your solution, can you provide it in a js fiddle? It's not working for me – medev21 Nov 12 '19 at 21:00
  • Here you go: https://jsfiddle.net/ej41k9zn/ - I also added some extra explanation in fiddle. – smartilabs Nov 12 '19 at 21:29
  • It would be better if you use the `onkeydown` event, instead of the `onkeyup`. Holding a key will make it so the scrollbar is visible until you release the key. There are other events you should try to listen to too. – Ismael Miguel Nov 15 '19 at 11:44
0

I suggest to put inputs' values into the state. And then calculate textarea rows property according to content length.

const rows = Math.ceil(this.getFinalSentence().length/TEXTAREA_LINE_LENGTH)

Dima Vishnyakov
  • 1,361
  • 10
  • 21
0

You can listen for scroll and add another row when the scroll function is triggered

<textarea id ="ta" cols="8" rows="5">afefeefaefae</textarea>
<script>
  document.getElementById("ta").addEventListener("scroll",function() {
    this.rows++;
  });
</script>
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
  • not sure if this works, it will work only if the user scrolls on the textarea, it doesn't autoresize the textarea. – medev21 Nov 12 '19 at 20:02
  • i did try it, unless I'm doing it wrong. can you provide js fiddle or something? – medev21 Nov 12 '19 at 20:26
  • @medev21 I tested this on Firefox and IE. When I just keep typing in the textarea, I see it add more rows – ControlAltDel Nov 12 '19 at 20:38
  • perhaps i didn't explain well in the question, what i need is when I edit the `input` elements, and its data is large, then the `textarea` should resize based on the input element data; ``. See code example above – medev21 Nov 12 '19 at 20:40
0

I created a small (7kb) custom element that deals with this stuff. Apart from listening for the input event, it also has a timer that fires every 100ms to make sure things are still working in case the text content changes by some other means.

Here's a quick implementation example on codesandbox: https://codesandbox.io/s/loving-banach-u00ip

It looks like you're using React, so i wrote the example in React, but this component works with plain JS, plain HTML or any other virtual DOM (Since it's implemented as a custom element, rather than a React component, jQuery plugin or what have you)

Essentially it works by just adding the following wrapper in React:

import "autoheight-textarea";

const App = () => {
  return (
    <autoheight-textarea>
      <textarea rows={2} />
    </autoheight-textarea>
  );
}

Or, if you're using plain HTML just import the script somewhere and do

<autoheight-textarea>
  <textarea rows="2" />
</autoheight-textarea>

You can grab the custom element from NPM: https://www.npmjs.com/package/autoheight-textarea

Ahrengot
  • 1,579
  • 1
  • 17
  • 29