in Angular2 how to know when ANY form input field lost focus
Why not use focusout it bubbles by default in the DOM
Here's a simple directive that catches focusout and checks if input value is blank, then sets value to zero:
@Directive({
selector: '[blankToZero]'
})
export class BlankToZeroDirective {
constructor(private elementHost: ElementRef) { }
@HostListener('focusout')
ensureInput(): void {
if (Util.isNullOrEmpty(this.elementHost.nativeElement.value)) {
this.elementHost.nativeElement.value = 0;
}
}
}
The blur
event doesn't bubble, therefore we need to listen on every input element directly. Angular provides a nice solution for this situation.
A directive that applies to all input elements inside your template.
This directive uses a host-listener to listen for the blur
events on all elements where the selector applies and forwards a bubbling input-blur
event:
@Directive({
selector: 'input,select',
host: {'(blur)': 'onBlur($event)'}
})
class BlurForwarder {
constructor(private elRef:ElementRef, private renderer:Renderer) {}
onBlur($event) {
this.renderer.invokeElementMethod(this.elRef.nativeElement,
'dispatchEvent',
[new CustomEvent('input-blur', { bubbles: true })]);
// or just
// el.dispatchEvent(new CustomEvent('input-blur', { bubbles: true }));
// if you don't care about webworker compatibility
}
}
By adding the BlurForwarder
directive to directives: [...]
it will be applied to all elements in its template that match the selector.
The host-listener listens for bubbling input-blur
events and calls our event handler:
@Component({
selector: 'my-component',
directives: [BlurForwarder],
host: {'(input-blur)':'onInputBlur($event)'},
template: `
<form>
<input type="text" [(ngModel)]="xxx">
<input type="text" [(ngModel)]="yyy">
<input type="text" [(ngModel)]="zzz">
</form>`
}) {
onInputBlur(event) {
doSomething();
}
}