2

It is a MERN stack app. I tried to make the height of a textarea responsive to the content using this script.

It looks like the external javascript file is working because I tried putting alert in the for loop and it did work. So I tried putting alert inside the OnInput() function but the alert was not called. Therefore, I think something is wrong with this function.

index.html

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>

  <script src="/main.js"></script>
</body>

main.js

var tx = document.getElementsByClassName('comment-area-responsive');

for (var i = 0; i < tx.length + 1; i++) {
  //   alert(i);
  tx[i].setAttribute(
    'style',
    'height:' + tx[i].scrollHeight + 'px;overflow-y:hidden;'
  );
  tx[i].addEventListener('change', OnInput, false);
}

function OnInput() {
  this.style.height = 'auto';
  alert('hi2');
  this.style.height = this.scrollHeight + 'px';
}

page

<textarea 
  className='comment-area-responsive' 
  name='title' 
  placeholder='What do you think?' 
  value={text} onChange={e => setText(e.target.value)} 
  required
/>
DreamTeK
  • 32,537
  • 27
  • 112
  • 171
Kittichote Chain
  • 596
  • 1
  • 10
  • 22
  • 1
    You may have called your function `OnInput`, but the event you are binding it to is the `change` event. That one fires only after the field loses focus again, not _while_ the user is typing. – 04FS Sep 19 '19 at 11:23
  • I wrote a codepen long ago to change the font-size of a textarea when there is too much text, not exacly the same thing but could help: https://codepen.io/elisabeth_hamel/pen/pdLRvv I used the keyup event – Elisabeth Hamel Sep 19 '19 at 12:16

2 Answers2

1

The script works as intended after removing a few problems from your code -

  1. Instead of change event, you should listen to the textarea's input event.

  2. textarea is a container, so you close it using a closing tag </textarea> and not a self closing tag. Read more

  3. Maybe you're using some other library, so make sure that you really need value={text} and onChange={e => setText(e.target.value)} attributes on the textarea. If you added them only for the purpose of this script, then they're not needed as you can see in the code below.

Run the snippet below to check that it works correctly after fixing all the above problems

var tx = document.getElementsByClassName('comment-area-responsive');
for (var i = 0; i < tx.length; i++) {
  tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
  tx[i].addEventListener("input", OnInput, false);
}

function OnInput() {
  this.style.height = 'auto';
  this.style.height = (this.scrollHeight) + 'px';
}
<div>
<textarea 
  class='comment-area-responsive' 
  name='title' 
  placeholder='What do you think?'  
  required
  ></textarea>  
</div>

Update : For getting it to work with React, since React treats onChange and onInput in the same way, you can do it inside your onChange handler, like -

const setText = (val) => {
      this.setState({text: val});
      var tx = document.getElementsByClassName('comment-area-responsive');
      for (var i = 0; i < tx.length; i++) {
        tx[i].setAttribute('style', 'height:' + (tx[i].scrollHeight) + 'px;overflow-y:hidden;');
      }
    }

...

    <textarea 
      className='comment-area-responsive' 
      name='title' 
      placeholder='What do you think?' 
      value={text} onChange={e => setText(e.target.value)} 
      required>
    </textarea>

Here's a working Stackblitz to play around.

Vandesh
  • 6,368
  • 1
  • 26
  • 38
  • it still doesn't work after changing everything you said, looks like the `OnInput()`function is not run. `onChange` is added not for this purpose but for managing the state of react. – Kittichote Chain Sep 20 '19 at 00:22
  • Updated the answer with a Stackblitz link for React – Vandesh Sep 20 '19 at 01:10
0

I think the issue lies with your textarea.

<textarea 
  className='comment-area-responsive' 
  name='title' 
  placeholder='What do you think?' 
  value={text} onChange={e => setText(e.target.value)} 
  required
/>

The textarea tag must be implicitly closed.

<textarea 
  className='comment-area-responsive' 
  name='title' 
  placeholder='What do you think?' 
  value={text} onChange={e => setText(e.target.value)} 
  required
></textarea>

Can you try and see if this fixes your issue?

DreamTeK
  • 32,537
  • 27
  • 112
  • 171