Shaun
Shaun

Reputation: 546

Javascript Resize Textarea

I am trying to resize multiple textareas on my page according to the amount of text in them. The textareas are created in an event handler by replacing the surrounding tags:

$('.container').on('click', '.js-post-edit-button', function (e) {
    e.preventDefault();
    const $form = $(this).parentsUntil(".js-post-update-form").parent();
    const $h5 = $form.find(".post-title");
    const $p = $form.find(".post-content");
    $h5.replaceWith($("<textarea/>", {
        "name": "post_edit[title]",
        "class": "form-control js-textarea-content",
        "id": "js-textarea-title",
        "style": "margin-bottom: 20px;",
        "text": $h5.text().replace("\n", "").replace(/\s{2,}/g, " ").trim(),
    }));
    $p.replaceWith($("<textarea/>", {
        "name": "post_edit[description]",
        "class": "form-control js-textarea-content",
        "id": "js-textarea-description",
        "style": "margin-bottom: 20px;",
        "text": $p.text().replace("\n", "").replace(/\s{2,}/g, " ").trim(),
    }));
    resizeTextarea();
});

function resizeTextarea () {
    const textarea = document.getElementsByClassName("form-control js-textarea-content");
    textarea.style.height = 'auto';
    textarea.style.height = text.scrollHeight+'px';
}

When I click on the edit button (js-post-edit-button), I get the following error:

Uncaught TypeError: Cannot set property 'height' of undefined

Can anyone tell me why I am getting this error please?

Upvotes: 0

Views: 154

Answers (2)

Rob Monhemius
Rob Monhemius

Reputation: 5144

NewToJS pretty much already gave you the answer. I'll try to add some extra nuance.

Why you code doesn't work

According to MDN documentation getElementsByClassName() returns an HTMLCollection (a list of elements).

  • You are trying to access a property (height) from another property (style) of this collection. Because the property 'style' does not exist on the HTMLCollection this will return undefined.
  • Now you are trying to change the 'height' property on this.

That should explain why you get the error:

Uncaught TypeError: Cannot set property 'height' of undefined

Alternative approach

I would just change the function to accept an element as parameter.

function resizeTextarea ( textarea ) {
    textarea.style.height = 'auto';
    textarea.style.height = text.scrollHeight+'px';
}

You could also use a more OOP approach and add a new method to HTMLTextAreaElement.prototype. Whatever you fancy I suppose.

Now you can get the element any way you want

  • I would not recommend using getElementsByClassName()[0]. It probably works most of the time but can lead to unexpected scenarios when that class exists multiple times on a page.
  • Better would be document.getElementById() if you are 100% sure the element will only appear once on a page.
  • You could use the reference to the element when you generate it in javascript.

Upvotes: 1

PierreN
PierreN

Reputation: 988

I don't know if you absolutely want to code it by yourself, for learning or another reason :-)

Anyway, if you're opened to the idea to use an existing js plugin, I can suggest you this excellent one : http://www.jacklmoore.com/autosize/

With a single line of code like this autosize($('textarea')) it will work immediately...

Here is a JsFiddle Example

$('#autosize').autosize();
<script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/1.18.4/jquery.autosize.min.js"></script>
<textarea id="autosize" style="width:200px;">
First
Second
Third</textarea>

Upvotes: 0

Related Questions