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
textarea
Create an invisible clone
div
Give the clone the same width and typographical properties as the
textarea
Place 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.