Mateus Borges
Mateus Borges

Reputation: 73

How to handle input events on custom input component in Angular?

I'm trying to create a custom Input component using Reative Form in Angular 7 but i'm having trouble passing events to the input field.

My component has a label and an input field and a specific layout. My component html looks like this:

<div id="customInputGroup"  [formGroup]="parentFormGroup" [ngClass]="{'input-value': hasValue()}">
    <label [for]="inputId">{{label}}</label>
    <input [id]="inputId"  [name]="inputName"  class="form-control" [placeholder]="placeholder" [formControlName]="inputName" [mask]="mask">
</div>

And in my Component:

@Component({
  selector: 'app-input-field',
  templateUrl: './input-field.component.html',
  styleUrls: ['./input-field.component.css']
})
export class InputFieldComponent implements OnInit {


  @Input('placeholder') placeholder = '' ;
  @Input('label') label = '';
  @Input('inputId') inputId = '';
  @Input('inputName') inputName = '';
  @Input('parentFormGroup') parentFormGroup:FormGroup;
  @Input('mask') mask;
  constructor() { }

  ngOnInit() {
  }

  hasValue(){
    return (this.parentFormGroup.get(this.inputName).value != undefined 
    && this.parentFormGroup.get(this.inputName).value != null 
    && this.parentFormGroup.get(this.inputName).value != '')
  }

Everything was working fine till i had to handle an input onBlur event(or it could be any other input event). The result i want is to call my component passing any event like this:

<app-input-field (blur)="functionName()"></app-input-field>

or

<app-input-field (keyup)="functionName()"></app-input-field>

And my component will be able to pass these events to my input field 'dynamically'. Is it possible to do it?

Upvotes: 5

Views: 11235

Answers (2)

Adrita Sharma
Adrita Sharma

Reputation: 22213

Events like blur works on input field , not selectors like <app-input-field>

You can emit event for all events like blur, keyup, mouseover etc..

InputFieldComponent:

HTML:

<input (blur)="functionName('blur')" (keyup)="functionName('keyUp')" [id]="inputId"  [name]="inputName"  class="form-control" [placeholder]="placeholder" [formControlName]="inputName" [mask]="mask">

TS:

@Output() OnInputEvent= new EventEmitter();

functionName(eventName) {
    this.OnInputEvent.emit(eventName);
}

In your component:

<app-input-field (OnInputEvent)="functionName($event)"></app-input-field>

TS:

functionName(event) {
    switch (event) {
       case "blur":
       ...
       break;

       case "keyUp":
       ...
       break;
    }
}

Working Demo

Upvotes: 5

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

for blur event you need to create a eventemitter with the same name and emit this event on input elemnt blur emit

export class InputFieldComponent implements OnInit {

  @Output() blur:EventEmitter<any> = new EventEmitter(); // 👈

  constructor() { }

  ngOnInit() {
  }

}

template

<input type="text" (blur)="blur.emit($event)"  >

app.template

<app-input-field (blur)="onBlur($event)" (keyup)="onKeyup($event)"></app-input-field>

we did this for the blur event because the event is not bubble where the keyup will work without create any custom event because it bubble.

demo 🔥🔥

you can implement two way data binding like this

  @Input() value:EventEmitter<any> = new EventEmitter();

  @Output() valueChange:EventEmitter<any> = new EventEmitter();

template

<app-input-field  [(value)]="name" ></app-input-field>

demo 🌟🌟

any bubble event like input,keypress,keyup,keydown you can capture on the element itself or you can work around it like what we did on blur event.

Upvotes: 5

Related Questions