I have been developing an e-commerce app with Angular 14.
I am currently working on a form that *can only be submitted upon accepting the "Terms & conditions" displayed in a modal.
The FormComponent
and ModalComponent
are sibling components.
In form.component.ts
I have:
import { Component } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { FormGroup, FormControl } from '@angular/forms';
import { ModalComponent } from '../modal/modal.component';
@Component({
selector: 'my-app',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css'],
})
export class FormComponent {
public form: FormGroup = new FormGroup({});
constructor(private dialog: MatDialog) {}
ngOnInit() {
this.form = new FormGroup({
first_name: new FormControl(''),
last_name: new FormControl(''),
phone: new FormControl(''),
email: new FormControl(''),
});
}
public openDialog() {
const dialogConfig = new MatDialogConfig();
// Dialog options
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.width = '420px';
this.dialog.open(ModalComponent, dialogConfig);
}
public sendFormData() {
console.log(this.form);
}
}
In the form componant's template:
<h1>Get in touch</h1>
<form [formGroup]="form">
<div class="form-grid">
<mat-form-field appearance="outline" floatLabel="never">
<mat-label class="mat-label">Fast name:</mat-label>
<input class="mat-input" matInput formControlName="first_name" />
</mat-form-field>
<mat-form-field appearance="outline" floatLabel="always">
<mat-label class="mat-label">Last name:</mat-label>
<input class="mat-input" matInput formControlName="last_name" />
</mat-form-field>
<mat-form-field appearance="outline" floatLabel="never">
<mat-label class="mat-label">Phone:</mat-label>
<input class="mat-input" matInput formControlName="phone" />
</mat-form-field>
<mat-form-field appearance="outline" floatLabel="never">
<mat-label class="mat-label">Email:</mat-label>
<input class="mat-input" matInput formControlName="email" />
</mat-form-field>
</div>
<div class="center">
<button (click)="openDialog()" mat-raised-button color="primary">
Submit
</button>
</div>
</form>
In modal.component.ts
I have:
import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css'],
})
export class ModalComponent implements OnInit {
constructor(private dialogRef: MatDialogRef<ModalComponent>) {}
ngOnInit(): void {}
accept() {
console.log('Terms accepted!');
}
reject() {
this.dialogRef.close();
}
}
In modal.component.html
I have:
<div mat-dialog-title>
<h2>Terms & Conditions</h2>
</div>
<div mat-dialog-content>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur expedita
ipsam assumenda sed non aut possimus, dolores ullam voluptates voluptatum
distinctio aspernatur neque velit eum, eveniet voluptas omnis. Veritatis,
architecto?
</p>
</div>
<mat-dialog-actions>
<button mat-raised-button color="primary" (click)="reject()">Reject</button>
<button mat-raised-button color="primary" (click)="accept()">Accept</button>
</mat-dialog-actions>
I have put it all together in THIS Stackblitz.
The goal is to trigger the function sendFormData()
from the form component from inside the accept()
function of the modal component?
For achieving this, I did:
accept() {
console.log('Terms accepted!');
this.FormComponent.sendFormData();
}
The above does not work.
In your dialog component, you pass a result to the close()
function:
accept() {
this.dialogRef.close('ACCEPTED');
}
reject() {
this.dialogRef.close('REJECTED');
}
In your form component's openDialog()
function, you handle the result:
public openDialog() {
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.width = '420px';
const dialogRef = this.dialog.open(ModalComponent, dialogConfig);
dialogRef.afterClosed().subscribe((result) => {
if (result === 'ACCEPTED') {
this.sendFormData();
}
});
}