I have a written a directive in angular 4 that captures onFocus and onBlur. I can see that my directive gets initialized when the form is loaded but dont see the obBlur or Onfocus firing when i click the input control. Not sure what is wrong. I have set the ShortNumberFormatterDirective on the input element
directive
import { Directive, HostListener, ElementRef, OnInit } from "@angular/core";
//import { MyCurrencyPipe } from "./my-currency.pipe";
@Directive({ selector: "[shortNumberFormatter]" })
export class ShortNumberFormatterDirective implements OnInit {
private el: HTMLInputElement;
constructor(
private elementRef: ElementRef,
// private currencyPipe: MyCurrencyPipe
) {
this.el = this.elementRef.nativeElement;
}
ngOnInit() {
//this.el.value = this.currencyPipe.transform(this.el.value);
}
@HostListener("focus", ["$event.target.value"])
onFocus(value) {
//this.el.value = this.currencyPipe.parse(value); // opossite of transform
}
@HostListener("blur", ["$event.target.value"])
onBlur(value) {
//this.el.value = this.currencyPipe.transform(value);
}
}
html
<tr *ngFor="let item of domicileInfo.taxAssesment.items; let last = last; let item_IDX = index">
<td *ngIf="!last" >
<click-input [classNames]="{'has-warning': !isMinValid(item,item_IDX) }">
<!-- <input [(ngModel)]="item.minSize" (ngModelChange)="modelChanged(item,item_IDX)" required min="0" max="999999999999999" numberFormat="shortNumberFormat:.0"> -->
<input [(ngModel)]="item.minSize" shortNumberFormatter required min="0" max="999999999999999" numberFormat="shortNumberFormat:.0">
</click-input>
</td>
<td *ngIf="!last">
<click-input [classNames]="{'has-warning': !isMaxValid(item,item_IDX) }">
<!-- <input [(ngModel)]="item.maxSize" (ngModelChange)="modelChanged(item,item_IDX)" required min="0" max="999999999999999" numberFormat="shortNumberFormat:.0"> -->
<input [(ngModel)]="item.maxSize" required min="0" max="999999999999999" numberFormat="shortNumberFormat:.0">
</click-input>
</td>
</tr>
Updated code based on Thomas response. If you notice i have written a parse method. The problem that i am facing is , the values are not getting transformed on form initialization. I am seeing the actual number for e.g 20000000 on the screen instead of 20M. I have tried to initialize in the onInit event but the cntrl value seem to be null.
Directive
import { Directive, HostListener } from "@angular/core";
import { NgControl } from '@angular/forms';
import { ShortNumberFormatPipe } from '../pipes/shortNumberFormat/shortNumberFormat.pipe';
@Directive({ selector: "[shortNumberFormatter]" })
export class ShortNumberFormatterDirective {
_shortNumberPipe = new ShortNumberFormatPipe();
get ctrl() {
return this.ngControl.control;
}
constructor(
private ngControl: NgControl
) { }
ngOnInit() {
if (this.ctrl != null && this.ctrl.value !=null) {
const x = this._shortNumberPipe.transform(this.ctrl.value);
console.log(x);
this.ctrl.setValue(x);
}
}
@HostListener("focus")
onFocus() {
const x = this._shortNumberPipe.parse(this.ctrl.value);
console.log(x);
this.ctrl.setValue(x);
}
@HostListener("blur")
onBlur() {
const x = this._shortNumberPipe.transform(this.ctrl.value);
console.log(x);
this.ctrl.setValue(x);
}
}
Pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'shortNumberFormat'
})
export class ShortNumberFormatPipe implements PipeTransform {
transform(number: any, decimals = 0) {
if (number === null) {
return;
}
number = parseFloat(number);
if (isNaN(number)) {
return;
}
if (isNaN(decimals)) {
return;
}
const signPrefix = number < 0 ? '-' : '';
number = Math.abs(number);
if (number <= 999) { // hundreds
number = number.toFixed(decimals);
} else if (number >= 1000 && number <= 999999) { // thousands
number = (number / 1000).toFixed(decimals) + 'K';
} else if (number >= 1000000 && number <= 999999999) { // millions
number = (number / 1000000).toFixed(decimals) + 'M';
} else { // billions
number = (number / 1000000000).toFixed(decimals) + 'B';
}
return signPrefix + number;
}
parse(inputField: string)
{
let parsedNumber: any;
if(inputField === '')
return;
let shortFormatCharector = inputField.substr(inputField.length - 1);
switch(shortFormatCharector)
{
case'k':
parsedNumber = parsedNumber * 1000;
break;
case'M':
parsedNumber = parsedNumber * 1000000;
break;
case'B':
parsedNumber = parsedNumber * 1000000000;
break;
}
return parsedNumber;
}
}
Introduction. @HostBinding and @HostListener are two decorators in Angular that can be really useful in custom directives. @HostBinding lets you set properties on the element or component that hosts the directive, and @HostListener lets you listen for events on the host element or component.
HostListenerlinkDecorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs.
@HostListener is Angular's decorator method that's used for listening to DOM events on the host element of both component and attribute directives. @HostListener sets the listeners once the directive is initialized and removes them automatically once the directive gets destroyed.
While there is a (blur)
output event in Angular components, AFAIK the corresponding event of host listening is not blur
but focusout
. So you should rather use:
@HostListener("focusout", ["$event.target.value"])
onBlur(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