How to implement a gracefully close form on hit escape key in Angular dialog material?
Asked Answered
L

4

13

I have a dialog form and I want to have it closed gracefully when a user hits the escape key. When the user hits the escape key the form is shut down immediately but for some reason the dialog form doesn't send a result to the parent form.

There is no problem when the shutdown is done via the cancel button.

I have tried it with an "onKey" event on the userform component but that also doesn't work.

In my typescript and template dialog files:

import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';

constructor(
  private dialogRef: MatDialogRef<UpdateBonusConditieComponent>,
  @Inject(MAT_DIALOG_DATA) private PassedData: ConditieTypeDialog,
) {}  // I also tried it with a public PassedData instead of private

onCancel() {
  console.log('komt ie hier');
  this.PassedData.cancel = true;
}

onKey(event: any) { 
  this.onCancel();
  console.log('toets ingedrukt ' + event.target);
}

onOK() {
  console.log('OK button pressed');
}
<mat-dialog-content [formGroup]="dialogConditieForm"
                    (keyup)="onKey($event)">

</mat-dialog-content>

<mat-dialog-actions>
  <button mat-button
          color="accent"
          (click)="onOK()"
          [mat-dialog-close]="PassedData"
          [disabled]="dialogConditieForm.invalid">Ok</button>
  <button mat-button
          color="warn"
          (click)="onCancel()"
          [mat-dialog-close]="PassedData">Cancel</button>
</mat-dialog-actions>

Then I have the parent form where I call the dialog, some details:

import { MatDialog } from '@angular/material';

constructor(private matDialog: MatDialog) {}

const dialogRef = this.matDialog.open(UpdateBonusConditieComponent, {
  data: {
    onderwerpGUI: onderwerpGUI,
    isNewRow: isNewRow,
    cancel: false,
  }
});

dialogRef.afterClosed().subscribe((result: ConditieTypeDialog) => {
  if (result.cancel) { //when hitting escape result is undefined for some reason
    this.selectedRow = null;
    return 0;
  }
});

I should expect a result back so that the this.selectedRow is set to null but if the escape key is used to close the dialog form this does not happen.

I think I am doing something wrong. Can anybody can help me ?

Lozenge answered 24/8, 2019 at 13:3 Comment(0)
F
26

The dialog form is not sending a result because the onKey function is never getting called. You can instead subscribe to the keyboardEvents in MatDialogRef and call onCancel if Escape is clicked. I have also added the same for the backdropClick as that would be required as well.

constructor(
    private dialogRef: MatDialogRef<UpdateBonusConditieComponent>,
    @Inject(MAT_DIALOG_DATA) private passedData: ConditieTypeDialog,
) { }

ngOnInit() {
    this.dialogRef.keydownEvents().subscribe(event => {
        if (event.key === "Escape") {
            this.onCancel();
        }
    });

    this.dialogRef.backdropClick().subscribe(event => {
        this.onCancel();
    });
}

onCancel(): void {
    this.passedData.cancel = true;
    this.dialogRef.close(this.passedData);
}

onOK() {
    console.log('OK button pressed');
}

Also, as per convention, use camelCase for your variable names (passedData).

Forename answered 25/8, 2019 at 0:9 Comment(4)
Thanks nash11 this is exactly what I was looking for !! :-)Lozenge
@Lozenge - Anytime :)Forename
We have to hard code the "Escape" value as a string ?Faucal
This doesn't seem to give you a chance to cancel the event e.g. for an "Are you sure you want to close without saving?" prompt.Toughie
F
0
  openSaveDialog() {
    this._matDialog.closeAll();
    const dataExist = {
      disableClose: true,
      width: '600px',
      backdropClass: 'transparent',
      cancel: false,
      data: { data: null, gridData: null }
    }
    this.submitModelRef = this._matDialog.open(SaveDetailsDialogComponent, dataExist);

    this.submitModelRef.afterClosed().subscribe(async (savedData) => {
      console.log(savedData);
    });
  }

Ref: https://material.angular.io/components/dialog/api#MatDialogConfig

Fuegian answered 16/8, 2023 at 6:51 Comment(0)
L
-1

I have found a work around to prevent crashes. I have blocked the keys by using this in the parent component:

const dialogConfig = new MatDialogConfig();

    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.data =  {
    onderwerpGUI: onderwerpGUI,
    isNewRow: isNewRow,
    cancel: false
}
});

const dialogRef = this.matDialog.open(UpdateBonusConditieComponent, dialogConfig);

maybe someone can use this. :-)

Lozenge answered 24/8, 2019 at 19:48 Comment(0)
P
-1

You can just use disableClose attribute. Here is an example usage of ModalComponent.

    const confirm = this._dialog.open(ModalComponent, {
  disableClose: false,
  width: '1200px',
  height:'1000px',
  data: {
    type: ModalType.ShowUserGuide,
    title: 'showUserGuide',
    body: 'userGuide',
    color: 'warn'
  }
})
Profligate answered 15/2 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.