Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in Angular2 how to know when ANY form input field lost focus

Tags:

angular

In Angular2 how to know when ANY input field has lost focus..! If I use observables on the form:

form.valueChange.subscribe...

wont work since I really want to know when a field lost it's blur (focus) so I can update my store (if I update the store before losing focus, my cursor on a text input gets moved to the end, since the data gets swapped which is weird looking)

of course I can also add (change)="" on each input, but I have a lot of'em...

I was thinking something of the sorts of:

this.form.valueChanges.debounceTime(1000).subscribe((changes:any) => {
  if (this.form.dirty){
    this.appStore.dispatch(this.resellerAction.updateResellerInfo(changes))
  }
});

but the problem is that the dirty remains dirty, so it stuck in an everlasting loop of change detections...

tx

Sean

like image 541
born2net Avatar asked Mar 31 '16 20:03

born2net


People also ask

Which event is fired when an input text field loses focus?

The onblur event occurs when an object loses focus. The onblur event is most often used with form validation code (e.g. when the user leaves a form field).

How do you know if an element is focused angular?

hasFocus() : whether the document or any element inside the document has focus. document. activeElement : Property containing which element currently has focus.

What is Focus event in angular?

The ng-focus directive tells AngularJS what to do when an HTML element gets focus. The ng-focus directive from AngularJS will not override the element's original onfocus event, both will be executed.

What is the use of Focusout in angular?

you can easily use focus out event in angular 6, angular 7, angular 8, angular 9, angular 10, angular 11, angular 12, angular 13 and angular 14 application. When user will key up on input box field then trigger onFocusEvent() of angular component. we will use (change) attribute for call function.


2 Answers

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();
  }
}
like image 114
Günter Zöchbauer Avatar answered Oct 11 '22 16:10

Günter Zöchbauer


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;
    }
  }
}
like image 44
TrickySituation Avatar answered Oct 11 '22 15:10

TrickySituation