user9410919
user9410919

Reputation:

Angular - Textarea auto height does not automatically resize on text deletion

I am using the following directive to allow an auto-sizing to a text area depending on user input:

import { ElementRef, HostListener, Directive, OnInit } from '@angular/core';

@Directive({
  selector: 'ion-textarea[autosize]'
})

export class Autosize implements OnInit {
  @HostListener('input', ['$event.target'])
  onInput(textArea:HTMLTextAreaElement):void {
    this.adjust();
  }

  constructor(public element:ElementRef) {
  }

  ngOnInit():void {
    setTimeout(() => this.adjust(), 0);
  }

  adjust():void {
    const textArea = this.element.nativeElement.getElementsByTagName('textarea')[0];
      textArea.style.height = 'auto';
      textArea.style.height = textArea.scrollHeight + "px";
      textArea.style.maxHeight = '100px';
  }
}

It is working as intended, however when the text inside that textarea is manually deleted, the textarea will not resize automatically.

E.g. if the [(ngModel)] variable assigned to that textarea is assigned a different string, or empty string, the height of the text area will not automatically resize. The user needs to start typing again in order to make the textarea resize accordingly.

What could be a good solution to solving this issue?

Upvotes: 5

Views: 20509

Answers (5)

The solution provided by Chtioui Malek works like a charm in Angular 18.

For the ones that wants to add maximum height, find the resolution below:

autoGrowTextZone(event : any) {
event.target.style.height = "0px";
event.target.style.height = (event.target.scrollHeight + 25) + "px";
event.target.style.maxHeight = "200px";

Upvotes: 0

AsGoodAsItGets
AsGoodAsItGets

Reputation: 3171

You may not need to write your own directive. You can use cdkTextareaAutosize from the official Angular CDK.

https://material.angular.io/components/input/overview#auto-resizing-code-lt-textarea-gt-code-elements

Upvotes: 14

Chtioui Malek
Chtioui Malek

Reputation: 11515

I'm using this simple approach, and textarea does shrink when text is deleted :

<textarea (keyup)="autoGrowTextZone($event)"></textarea>

and

autoGrowTextZone(e) {
  e.target.style.height = "0px";
  e.target.style.height = (e.target.scrollHeight + 25)+"px";
}

Upvotes: 13

Dat Duong
Dat Duong

Reputation: 1

You dont need find textArea, using :

this.element.nativeElement.style.height = 'auto';
this.element.nativeElement.style.height = this.element.nativeElement.scrollHeight + 'px';
this.element.nativeElement.style.maxHeight = '100px';

Upvotes: -1

chrystian
chrystian

Reputation: 914

try adding something like this:

ngAfterContentChecked(): void {
    this.adjust();
}

or just use this lib: ngx-autosize :)

UPDATE
The solution with ngAfterContentChecked hook is still valid but it might affect app speed if used too often...

another way is to treat ngModel as input and that will let you rely on ngOnChanges hook, so in your directive try adding:

...
@Input('ngModel') text: any;
...
ngOnChanges(changes) {
    if (changes.text) {
        this.adjust();
    }
}

Upvotes: 4

Related Questions