Angular 2 Input Directive Modifying Form Control Value
Asked Answered
C

2

23

I have a simple Angular 2 directive that modifies the input value of a textbox. Note that i'm using the Model-Driven form approach.

@Directive({
  selector: '[appUpperCase]'
})
export class UpperCaseDirective{

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

  }

  @HostListener('input',['$event']) onEvent($event){
    console.log($event);
    let upper = this.el.nativeElement.value.toUpperCase();
    this.control.valueAccessor.writeValue(upper);

  }

}

The dom updates properly, however the model updates after every other keystroke. Take a look at the plnkr

Caucasian answered 18/11, 2016 at 17:20 Comment(0)
A
48

This thrills me because I encountered this earlier and was left scratching my head.

Revisiting the issue, what you need to do is to change your this.control.valueAccessor.writeValue(upper) where the ControlValueAccessor is explicitly writing to the DOM element and not to the control itself to instead call

 this.control.control.setValue(upper);

which will change the value on the control and be correctly reflected both on the page and in the control's property. https://angular.io/docs/ts/latest/api/forms/index/ControlValueAccessor-interface.html

A ControlValueAccessor abstracts the operations of writing a new value to a DOM element representing an input control.

Here's a forked plunker: http://plnkr.co/edit/rllNyE07uPhUA6UfiLkU?p=preview

Anthrax answered 18/11, 2016 at 17:51 Comment(4)
Awesome! Thanks for the explanation.Caucasian
What about character position? Keypress sends character position to end of input.Dimorph
@silntsod Do you have any idea, how to use it with template driven form ? with ngModelHenson
Thank you for this great answerLamella
P
1

I was looking for something like this, but when I tried the code in my project I was getting errors on the line this.el.nativeElement.value.toUpperCase() as per the working example above given by @silentsod.

I amended the code to:

let str:string = this.control.value;
this.control.control.setValue(str.toUpperCase());

Here's a forked plunker: http://plnkr.co/edit/uf6udp7mQYmnKX6hGPpR?p=preview

Pemphigus answered 26/7, 2017 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.