Search code examples
angularangularjsangular-material

Angular - Send form on enter in MatDialog


My goal is to execute the form in a MatDialog if I press Enter. It doesn't matter which element is focused. I've searched a lot and tried lots of things but each time it didn't work.

I've tried to use ngSubmit on the form, I init the event keyup.enter on the source html element,the mat-dialog-content-Element and the form itself.

All trails didn't work. If I set the keyup.enter-Event for the form it only is triggered when I focus a form field and press enter. If I set this event to the source html-element or the mat-dialog-content-Element it only is triggered when I don't focus the form.

I tried to create a Stackblitz but it didn't work, so I am just sharing the code:

Component from which the MatDialog is opened:

TS

public openDialog() {
const dialogRef = this.dialog.open(EditUserComponent, {
  width: '100%',
  height: '100%',
});

}

HTML

<button mat-button (click)="openDialog()">Open Dialog</button>

The MatDialog that is opened:

HTML

    <div class="flex-c justify-center full-height padding-l">
  <label class="title-2">Create user</label>
  <div class="flex-c full-size padding-l gap-l">
    <div>
      <form [formGroup]="formData" class="user-form">
        <div>
          <mat-form-field>
            <mat-label>Name</mat-label>
            <input type="text" matInput formControlName="name" />
          </mat-form-field>
        </div>
        <div>
          <mat-form-field>
            <mat-label>Age</mat-label>
            <input type="number" matInput formControlName="age" />
          </mat-form-field>
        </div>
      </form>
    </div>
    <mat-dialog-actions>
      <button mat-button color="warn" (click)="cancel()">cancel</button>
      <button (click)="saveUser()" cdkFocusInitial>save</button>
    </mat-dialog-actions>
  </div>
</div>

TS

export class EditUserComponent {
  public formData = new FormGroup({
    name: new FormControl('', Validators.required),
    age: new FormControl('', Validators.required),
  });

  constructor(public dialogRef: MatDialogRef<EditUserComponent>) {}

  public cancel() {
    this.dialogRef.close();
  }

  public save() {
    if (this.formData.valid) {
      console.log('User is updated');
    }
  }
}

How can I do that?


Solution

  • Have you tried using @HostListener? HostListener allows you to capture events inside the component. Something like this

    export class EditUserComponent {
      public formData = new FormGroup({
        name: new FormControl('', Validators.required),
        age: new FormControl('', Validators.required),
      });
    
      constructor(public dialogRef: MatDialogRef<EditUserComponent>) {}
    
      @HostListener('document:keydown', ['$event'])
      handleKeyboardEvent(event: KeyboardEvent) {
        if (event.key === 'Enter') {
          this.save();
        }
      }
    
      public cancel() {
        this.dialogRef.close();
      }
    
      public save() {
        if (this.formData.valid) {
          console.log('User is updated');
        }
      }
    }