Learn how to create a reusable dialog in Angular using Angular CDK, @ngx-formly, and Tailwind CSS. Follow this step-by-step guide to enhance your Angular application's functionality and maintainability.
As an Angular developer, creating reusable components can significantly improve your productivity and maintainability. Today, I'll walk you through the process of creating a reusable dialog using Angular CDK, @ngx-formly, and Tailwind CSS. We'll build a dialog service that can display forms dynamically, making it a great tool for various use cases in your application. In this guide we will take a look on how to attach a Formly Form inside your dialog for quick-editing your application data.
Introduction to @ngx-formly
@ngx-formly is a dynamic form library for Angular that simplifies the process of creating and managing complex forms. By allowing developers to define form fields as JSON configuration objects, @ngx-formly eliminates the need for repetitive boilerplate code. This results in more maintainable and flexible form structures.
The primary benefit of @ngx-formly is its ability to dynamically render forms based on the configuration provided. This means you can easily create forms that adapt to varying data models and requirements without having to manually code each form field and validation rule. Additionally, @ngx-formly supports integration with popular UI libraries like Angular Material, Bootstrap, and others, making it easy to create consistent and visually appealing forms across your application.
With features like field validation, conditional rendering, and customizable templates, @ngx-formly is an essential tool for Angular developers looking to streamline their form-building processes and enhance their application's flexibility and maintainability.
Prerequisites
Before we start, make sure you have Angular CDK
and @ngx-formly
installed in your project. If you haven't already set these up, you can follow the instructions below:
- Angular CDK: Installation Guide
- @ngx-formly: Installation Guide
Step 1: Setting Up Angular CDK and @ngx-formly
First, let's install Angular CDK and @ngx-formly:
npm install @angular/cdk @ngx-formly/core @ngx-formly/material
Step 2: Setting Up Tailwind CSS
If you haven't already set up Tailwind CSS in your Angular project, you can follow the official Tailwind CSS Installation Guide.
Step 3: Creating the Dialog Component
We'll start by creating a standalone dialog component that will be used to display our forms.
ng generate component formly-dialog --standalone
Here’s a basic structure for our FormlyDialogComponent
:
import { Component, Inject } from "@angular/core";
import { MAT_DIALOG_DATA, MatDialogRef } from "@angular/material/dialog";
import { FormGroup } from "@angular/forms";
import { FormlyFieldConfig, FormlyFormOptions } from "@ngx-formly/core";
@Component({
selector: "app-formly-dialog",
template: `
<div class="p-6 bg-white rounded-lg">
<h2 class="text-xl font-bold mb-4">{{ data.title }}</h2>
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<formly-form
[form]="form"
[fields]="data.fields"
[model]="model"
[options]="options"
></formly-form>
<div class="flex justify-end mt-4">
<button
type="button"
class="btn btn-secondary mr-2"
(click)="onClose()"
>
Cancel
</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
`,
})
export class FormlyDialogComponent {
form = new FormGroup({});
model: any = {};
options: FormlyFormOptions = {};
constructor(
public dialogRef: MatDialogRef<FormlyDialogComponent>,
@Inject(MAT_DIALOG_DATA)
public data: { title: string; fields: FormlyFieldConfig[] }
) {}
onSubmit() {
if (this.form.valid) {
this.dialogRef.close(this.model);
}
}
onClose() {
this.dialogRef.close();
}
}
Step 4: Creating the Dialog Service
Next, we'll create a service that will manage opening the dialog with the specified form fields and title.
ng generate service dialog
Here's the implementation of the DialogService
:
import { Injectable } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { FormlyFieldConfig } from "@ngx-formly/core";
import { FormlyDialogComponent } from "./formly-dialog/formly-dialog.component";
@Injectable({
providedIn: "root",
})
export class DialogService {
constructor(private dialog: MatDialog) {}
formlyDialog(fields: FormlyFieldConfig[], title: string = "Form") {
const dialogRef = this.dialog.open(FormlyDialogComponent, {
width: "400px",
data: { title, fields },
});
return dialogRef.afterClosed();
}
}
Step 5: Using the Dialog Service
Finally, let's use the DialogService
in a component to display a form in a dialog.
import { Component } from "@angular/core";
import { FormlyFieldConfig } from "@ngx-formly/core";
import { DialogService } from "./dialog.service";
@Component({
selector: "app-root",
template: `
<div class="p-6">
<button class="btn btn-primary" (click)="openDialog()">
Open Form Dialog
</button>
</div>
`,
})
export class AppComponent {
constructor(private dialogService: DialogService) {}
openDialog() {
const fields: FormlyFieldConfig[] = [
{
key: "firstName",
type: "input",
templateOptions: {
label: "First Name",
placeholder: "Enter your first name",
required: true,
},
},
{
key: "lastName",
type: "input",
templateOptions: {
label: "Last Name",
placeholder: "Enter your last name",
required: true,
},
},
];
this.dialogService
.formlyDialog(fields, "User Information")
.subscribe((result) => {
console.log("Dialog closed with result:", result);
});
}
}
Summary
By following the steps above, you've created a reusable dialog component that can be used to display dynamic forms using Angular CDK, @ngx-formly, and Tailwind CSS. This setup not only enhances the reusability of your components but also provides a consistent user experience across your application. You can now expand on this foundation by adding more features and customizations to your custom dialog as needed.