0

I have a directive that filters text pasted into an input field. Special characters are removed and only alphanumerical chars are kept.

export class PasteFilterDirective {
  constructor(private element: ElementRef) {}

  @HostListener('paste', ['$event'])
  handlePaste(event: ClipboardEvent) {
    event.preventDefault();

    const rawText = event.clipboardData?.getData('text/plain');
    const parsedText = this.removeSpecialChars(rawText);

    this.element.nativeElement.value = parsedText;
  }

  private removeSpecialChars(str: string): string {
    return str.match(/[A-Za-z0-9]/g).join('');
  }
}

The directive works fine, except for the fact that after pasting, NgModel is not updated. In other words - the input value changes, but if I have an ngModel binding against that input field, it won't change. Here's a stackblitz demonstrating the issue.

How can I write to the input field in a way that updates ngModel?

Allan Juan
  • 2,048
  • 1
  • 18
  • 42
  • 1
    you can dispatch "input" event on a control to cause ngModel handle it, or you could inject NgControl and call its function directly – Andrei Dec 13 '22 at 11:55
  • Does this answer your question? [Attribute directive with ngModel to change field value](https://stackoverflow.com/questions/36106350/attribute-directive-with-ngmodel-to-change-field-value) – Naren Murali Dec 13 '22 at 11:56
  • Injecting NgControl and calling `ngControl.control.setValue()` worked like a charm. – Allan Juan Dec 13 '22 at 16:17

1 Answers1

0

I think you can use an

@Output('valueChange') valueChange = new EventEmitter<any>()

after every

this.element.nativeElement.value = parsedText;

something like this

this.valueChange.emit(parsedText);

you can catch this from component template, for example:

<... (valueChange)="updateModel($event)" ...>

and finally implement your own update model logic in component

updateModel(value: any) { /* Your Code */ }.

Selaka Nanayakkara
  • 3,296
  • 1
  • 22
  • 42