mapr
mapr

Reputation: 119

How to implement a pseudo event for a custom component in Angular?

I have a custom component that contains an input and a button like this

<div class="input-group">
    <input type="text" class="form-control form-control-sm"
        (input)="change($event)"
        ngbDatepicker #d="ngbDatepicker" required
        #datef />
    <div class="input-group-append">
        <button type="button" class="btn btn-sm btn-success" (click)="d.toggle()" type="button">
            <i class="fa fa-calendar"></i>
        </button>
    </div>
</div>

I'd like it to have some funcionality so when the user press enter on the input it should emit a pseudo event

<custom-datepicker (keyup.enter)="handleKeyboard($event)"></custom-datepicker>

I've tried with @HostListener, but I'm getting errors about too much recursion, please, help me

Upvotes: 0

Views: 328

Answers (2)

vishal
vishal

Reputation: 157

You can just simple use the concept of event emitters wherein you can emit an event from your custom component to your parent component

----Custom Component Html----

<div class="input-group">
<input type="text" class="form-control form-control-sm"
    (input)="change($event)"
    ngbDatepicker #d="ngbDatepicker" required
    #datef />
<div class="input-group-append">
    <button type="button" class="btn btn-sm btn-success" (click)="d.toggle()" type="button">
        <i class="fa fa-calendar"></i>
    </button>
</div>

----Custom Component ts----

@Output()
customEvent = new EventEmitter();
change(event) {
this.customEvent.emit();
}

----Parent Component ----

<custom-datepicker (customEvent)="handleKeyboard($event)"></custom-datepicker>

Upvotes: 1

Sanjay Lohar
Sanjay Lohar

Reputation: 528

You can approach this using Reactive Forms FormArray. You would attach an (keyup) or (keyup.enter) handler to the <input />. Within the handler for this keyup event, we push a new FormControl to a FormArray. This example uses FormBuilder to generate a FormGroup that contains a FormArray with a key of things. We use the push method of FormArray to add a new FormControl/AbstractControl within the handler for keyup.

Component:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.createForm();
  }


  onEnter() {
    this.addThing();
  }

  get things() {
    return this.myForm.get('things') as FormArray;
  }

  private createForm() {
    this.myForm = this.fb.group({
      things: this.fb.array([
        // create an initial item
        this.fb.control('')
      ])
    });
  }

  private addThing() {
    this.things.push(this.fb.control(''));
  }
}
Template:

<form [formGroup]="myForm">
    <div formArrayName="things">
        <div *ngFor="let thing of things.controls; let i=index">
            <label [for]="'input' + i">Thing {{i}}:</label>
            <input type="text" [formControlName]="i" [name]="'input' + i" [id]="'input' + i" (keyup.enter)=""  />
        </div>
    </div>
</form>

At a very basic level you can loop through each in the form array using the controls property of the respective FormArray element and the value using the value property:

<ul>
  <li *ngFor="let thing of things.controls">{{thing.value}}</li>
</ul>

Here is a StackBlitz(https://stackblitz.com/edit/angular-r5zmbg) demonstrating the functionality.

Hopefully that helps!

Upvotes: 0

Related Questions