I have a directive that appends decimals, if the input value is a whole number, on blur. Below is the implementation.
import { Directive, ElementRef, Input, OnInit, HostListener, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Directive({
selector: '[price]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PriceDirective),
multi: true
}
]
})
export class PriceDirective implements ControlValueAccessor {
constructor(private el: ElementRef) { }
// ControlValueAccessor interface
private _onChange = (_) => { };
private _onTouched = () => { };
@HostListener('blur', ['$event'])
input(event) {
!!event.target.value ? $(this.el.nativeElement).val(Number(event.target.value).toFixed(2)) : $(this.el.nativeElement).val(null);
this._onChange(parseFloat(event.target.value));
this._onTouched();
}
writeValue(value: any): void {
!!value ? $(this.el.nativeElement).val(Number(value).toFixed(2)) : $(this.el.nativeElement).val(null);
}
registerOnChange(fn: (_: any) => void): void { this._onChange = fn; }
registerOnTouched(fn: any): void { this._onTouched = fn; }
}
Things work as expected.
But, since Angular doesn't trigger validation when the value is changed programatically, the textbox that has this directive, is not validated.
How can I enable validation in this case, by other means than passing the control
reference as an input to the directive and calling updateValueAndValidity
on it, or calling updateValueAndValidity
on input
or blur
.
It would be great if someone suggests me a way to trigger validation from the directive itself.
I solved the same problem in this way. It is my first approach.
update() {
// ...
const el = this.el.nativeElement;
const reg = new RegExp(this.textMaskConfig.replacement);
el.value = this.prevStr.replace(reg, this.currentChar);
// ...
}
But It doesn't fire the validate event. So I get the NgControl
component and used setValue()
method.
constructor(private el: ElementRef, private ctrl: NgControl) {
}
@HostListener('keydown', ['$event']) onKeyDownHandler(e) {
this.ctrl.control.setValue(value);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With