angular-directiveionic4elementref

Unable to get nativeElement of ion-textarea in Ionic 4 to set height


I have a custom directive to adjust the ion-textarea height to autosize the height as text is entered rather than setting a fixed row height or having ugly scroll bars as the textarea fills up.

In Ionic-4 I am unable to get the nativeElement of the html textarea of the ion-textarea. Any help would be great

It's running on Angular 6 and Ionic 4 but when I try and get this.element.nativeElement.getElementsByTagName('textarea')[0] it is always undefined so I can't set the height programatically.

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

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

export class AutosizeDirective 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.overflow = 'hidden';
    textArea.style.height = 'auto';
    textArea.style.height = textArea.scrollHeight + 'px';
  }
}

As the const textArea always comes back undefined I can't set the height to follow the scroll height to prevent the scroll bars.

Anyone been able to do this in Ionic-4? seen working examples in Ionic-3 as per the above code.

Thank you Rowie


Solution

  • Below code would help your problem.

    import { ElementRef, HostListener, Directive, AfterViewInit } from '@angular/core';
    
    @Directive({
      selector: 'ion-textarea[autosize]'
    })
    
    export class AutoSizeDirective implements AfterViewInit {
      readonly defaultHeight = 64;
    
      @HostListener('input', ['$event.target'])
      onInput(textArea: HTMLTextAreaElement) {
        this.adjust(textArea);
      }
    
      constructor(private element: ElementRef) {}
    
      ngAfterViewInit() {
        this.adjust();
      }
    
      adjust(textArea?: HTMLTextAreaElement) {
        textArea = textArea || this.element.nativeElement.querySelector('textarea');
    
        if (!textArea) {
          return;
        }
    
        textArea.style.overflow = 'hidden';
        textArea.style.height = 'auto';
        textArea.style.height = (textArea.value ? textArea.scrollHeight : defaultHeight) + 'px';
      }
    }
    

    Usage: <ion-textarea autosize></ion-textarea>

    I have confirmed it on Ionic 4.0.2/Angular 7.2.6.

    Regards.