Home > Net >  Match the size of two textarea elements when one of them changes
Match the size of two textarea elements when one of them changes

Time:09-22

I have a small HTML page with two textarea elements side-by-side. One is enabled for input and the other is readonly and dynamically shows a preview for the first one (for some custom template processing).

two textarea elements side-by-side

I want both textarea elements to always have the same height and for them to match the other if the use resizes. I'm not using jQuery or any fancy JS framework, though I am using Bootstrap 5.

Can this be done with vanilla JS?

This is my code for the two textareas:

<div class="row">
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
            <textarea class="form-control" id="note_content" style="height: 300px"></textarea>
            <label for="note_content" class="form-label">Note content template (you can use book parameters here!)</label>
        </div>
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
            <textarea class="form-control" id="note_content_preview" style="height: 300px" placeholder="preview" disabled></textarea>
            <label for="note_content_preview" class="form-label">Note content preview</label>
        </div>
    </div>

CodePudding user response:

You could use a resize observer to listen for resize changes on your main textarea element, and then adjust the height of your second textarea element based on the height/width of the first element by grabbing its height/width whenever it resizes:

const note = document.getElementById("note_content");
const preview = document.getElementById("note_content_preview");

const resizeObserver = new ResizeObserver(() => {
 preview.style.height = note.offsetHeight   "px";
 preview.style.width = note.offsetWidth   "px";
});
resizeObserver.observe(note);
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div class="row">
  <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
    <textarea class="form-control" id="note_content" style="height: 300px"></textarea>
    <label for="note_content" class="form-label">Note content template (you can use book parameters here!)</label>
  </div>
  <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
    <textarea class="form-control" id="note_content_preview" style="height: 300px" placeholder="preview" disabled></textarea>
    <label for="note_content_preview" class="form-label">Note content preview</label>
  </div>
</div>

CodePudding user response:

If you simply want the textareas to match when either is resized you don't need any custom JS or CSS. In your markup use flexbox (d-flex flex-column) to make the textareas grow in height flex-grow-1...

<div class="row">
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1 d-flex flex-column">
            <textarea class="form-control flex-grow-1" id="note_content" style="height: 300px"></textarea>
            <label for="note_content" class="form-label">Note content template (you can use book parameters here!)</label>
        </div>
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1 d-flex flex-column">
            <textarea class="form-control flex-grow-1" id="note_content_preview" placeholder="preview" disabled></textarea>
            <label for="note_content_preview" class="form-label">Note content preview</label>
        </div>
    </div>

If you also want the first textarea to resize to its content, use an input handler.

/* this is used to make 1st textarea resize to its content upon input */
const note_content = document.getElementById("note_content")
note_content.addEventListener("input", function(){
    this.style.height = "auto";
    this.style.height = (this.scrollHeight)   "px";
}, false)

https://codeply.com/p/scxO6z78dd

CodePudding user response:

const noteContentElement = document.getElementById("note_content");
const noteContentPreviewElement = document.getElementById("note_content_preview");
noteContentElement.addEventListener('keyup', function(){
noteContentElement.style.height = (noteContentElement.scrollHeight > noteContentElement.clientHeight) ? (noteContentElement.scrollHeight) "px" : noteContentElement.style.height "px";
noteContentPreviewElement.style.height = noteContentElement.style.height;
noteContentPreviewElement.value = noteContentElement.value;
});

//Credits: https://stackoverflow.com/questions/995168/textarea-to-resize-based-on-content-length
.col-6{
width: 40%;
margin: 10px;
display: inline-block;
vertical-align:top;
}
.col-6 label{
display:block;
}
textarea{
overflow: hidden;
}
<div class="row">
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
            <textarea class="form-control" id="note_content"></textarea>
            <label for="note_content" class="form-label">Note content template (you can use book parameters here!)</label>
        </div>
        <div class="col-6 mb-3 form-floating mt-3 ml-auto gx-1">
            <textarea class="form-control" id="note_content_preview"  placeholder="preview" disabled></textarea>
            <label for="note_content_preview" class="form-label">Note content preview</label>
        </div>
    </div>

  • Related