Server-side dev here, looking to dabble in a bit of vanilla JS to learn the ropes.
This question is about creating a form where textareas are initially hidden behind button clicks, and which also resize as the text entered into them grows larger. It's a challenging problem for someone at my level, and I'm trying to code it myself for learning purposes.
Here's what I've done so far.
Imagine a forum where users submit textual content. Each submission has a "reply" button under it. Pressing that opens a simple textarea that one can type their response into. I wrote simple JS to accomplish this:
var replyBtns = document.querySelectorAll('[id=rep]');
for(var i = 0; i < replyBtns.length; i++) {
replyBtns[i].addEventListener('click', function(e) {
e.preventDefault();
var textarea = document.getElementById("reply-message");
if (textarea) { textarea.parentNode.removeChild(textarea); }
var replyBox = document.createElement('textarea');
replyBox.setAttribute('id', 'reply-message');
replyBox.setAttribute('placeholder', 'Reply');
this.parentNode.insertAdjacentElement('beforeend', replyBox);
}, false);
}
As you can see, this JS creates a text area and adds it in the HTML. The CSS to go with it is:
textarea#reply-message {
display: block;
border: none;
color:#306654;
font-size:120%;
padding: 5px 10px;
line-height: 20px;
width:550px;
height: 20px;
border-radius: 6px;
overflow: hidden;
resize: none;
}
This works well.
My next endeavour was to make this textarea resize as the text starts overflowing. For that, I'm taking this route:
Grab the content loaded into the
textareaCreate an invisible clone
divGive the clone the same width and typographical properties as the
textareaPlace the content into the clone
Get the height of the clone
Apply the height of the clone to the height of the
textarea
This strategy uses the property that any div element naturally stretches to fit the height of its content (assuming no floats or absolutely positioned elements). I owe this technique to this blog post.
Here's the JS for implementing the aforementioned technique:
let txt = document.getElementById('reply-message'),
hiddenDiv = document.createElement('div'),
content = null;
hiddenDiv.classList.add('hiddendiv');
document.body.appendChild(hiddenDiv);
txt.addEventListener('keyup', function () {
content = this.value;
hiddenDiv.innerHTML = content + '\n\n';
this.style.height = hiddenDiv.getBoundingClientRect().height + 'px';
}, false);
Where hiddendiv is:
.hiddendiv {
position: absolute;
left: -9999px;
visibility: hidden;
white-space: pre-wrap;
width: 550px;
height: 20px;
font-size: 120%;
padding: 5px 10px;
word-wrap: break-word;
overflow-wrap: break-word;
}
But thing is, I need this JS snippet to run only once the textarea actually exists.
Currently, I have it running on page load, where it's unable to have any effect since textareas don't yet exist. How do I ensure it only runs once they've been created? Being a newbie in JS, this is totally eluding me. Please advise.