Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom directive for trimming whitespace in Angular 9

I have created a custom directive to remove whitespaces from the input box which works completely fine till Angular version 7, but not working in Angular version 9.

import {
    Directive,
    ElementRef,
    Output,
    EventEmitter,
} from '@angular/core';
@Directive({
    selector: '[trim]',
    host: {
        '(blur)': 'onBlur()'
    }
})
export class TrimDirective {
    @Output() ngModelChange: EventEmitter < any > = new EventEmitter();
    constructor(private element: ElementRef) {}
    onBlur() {
        (this.element.nativeElement as HTMLInputElement).value = (this.element.nativeElement as HTMLInputElement).value.trim();
        this.ngModelChange.emit((this.element.nativeElement as HTMLInputElement).value.trim());
    }
}

On blur event it supposed to trim the whitespaces and update the ngModel, but it's not updating ngModel

like image 839
MeVimalkumar Avatar asked Sep 18 '25 07:09

MeVimalkumar


1 Answers

I know this is pretty late, but It's been around 3 years since I posted this question, and the answer given by radik is working well with template-driven forms but with Reactive forms, it is not working as expected. It trims the HTML control value, but it does not update the corresponding form control. So I'm posting this answer which works with Template driven forms as well as with reactive forms.

trim.directive.ts looks like follows

import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[trim]'
})
export class TrimDirective {

  @Output() ngModelChange = new EventEmitter();

  constructor(private el: ElementRef,
    private control: NgControl) {
  }

  /**
   * Trim the input value on focus out of input component
   */
  @HostListener('focusout') onFocusOut() {
    (this.el.nativeElement as HTMLInputElement).value = (this.el.nativeElement as HTMLInputElement).value.trim();
    this.ngModelChange.emit(this.el.nativeElement.value)
    this.control.control?.setValue(this.el.nativeElement.value)
  }

}

And just use the trim directive in your HTML as below.

<input trim matInput name="name" id="name" formControlName="name"/>

This will not just update the HTML control it updates the angular form control as well and it emits the trimmed value on the ngModelChange event.

like image 66
MeVimalkumar Avatar answered Sep 19 '25 22:09

MeVimalkumar