Skip to main content

Angular PrimeNG Integration

Introduction

PrimeNG is one of the most popular UI component libraries for Angular applications. It offers a rich set of over 80 UI components that are responsive, accessible, and customizable. In this guide, we'll explore how to integrate PrimeNG into your Angular applications and leverage its extensive component library to build beautiful and functional user interfaces.

PrimeNG stands out from other UI libraries due to its:

  • Comprehensive collection of components
  • Consistent design language
  • Excellent documentation
  • Regular updates and community support
  • Flexible theming options

Let's dive into how you can start using PrimeNG in your Angular projects!

Getting Started with PrimeNG

Prerequisites

Before integrating PrimeNG, make sure you have:

  • Node.js and npm installed
  • Angular CLI installed
  • An existing Angular project (or create one using ng new my-project)

Step 1: Install PrimeNG Package

First, we need to add PrimeNG to our Angular project. Open your terminal and run:

bash
npm install primeng

Additionally, we need to install PrimeIcons for icons:

bash
npm install primeicons

Step 2: Import Required Styles

Next, we need to import the necessary PrimeNG styles. Open your angular.json file and add the following CSS files to the styles array:

json
"styles": [
"node_modules/primeng/resources/themes/lara-light-blue/theme.css",
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"src/styles.css"
]

Step 3: Import PrimeNG Modules

Now, we need to import the specific PrimeNG modules that we want to use in our application. Let's modify our app.module.ts file:

typescript
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';

// Import PrimeNG modules
import { ButtonModule } from 'primeng/button';
import { TableModule } from 'primeng/table';
import { CalendarModule } from 'primeng/calendar';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
// Add PrimeNG modules here
ButtonModule,
TableModule,
CalendarModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

In this example, we've imported three common PrimeNG components: Button, Table, and Calendar.

Using PrimeNG Components

Now that we've set up PrimeNG in our Angular application, let's explore how to use some of the most common components.

Basic Button Component

Let's start with a simple button component:

typescript
// app.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
clickCount = 0;

incrementCounter() {
this.clickCount++;
}
}
html
<!-- app.component.html -->
<h2>PrimeNG Button Example</h2>

<p-button label="Click Me" icon="pi pi-check" (onClick)="incrementCounter()"></p-button>

<p *ngIf="clickCount > 0">
Button clicked {{clickCount}} times!
</p>

Output:

When rendered, you'll see a styled button with a check icon. Each time you click it, the counter below will increment.

Data Table Component

Now, let's implement a more complex component - the data table:

typescript
// app.component.ts
import { Component, OnInit } from '@angular/core';

interface Product {
id: number;
code: string;
name: string;
category: string;
quantity: number;
}

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
products: Product[] = [];

ngOnInit() {
// Simulate data from API
this.products = [
{id: 1, code: 'P001', name: 'Laptop', category: 'Electronics', quantity: 24},
{id: 2, code: 'P002', name: 'Smartphone', category: 'Electronics', quantity: 45},
{id: 3, code: 'P003', name: 'Headphones', category: 'Accessories', quantity: 30},
{id: 4, code: 'P004', name: 'Mouse', category: 'Computer Peripherals', quantity: 60},
{id: 5, code: 'P005', name: 'Keyboard', category: 'Computer Peripherals', quantity: 55}
];
}
}
html
<!-- app.component.html -->
<h2>PrimeNG Table Example</h2>

<p-table [value]="products" [tableStyle]="{'min-width': '50rem'}">
<ng-template pTemplate="header">
<tr>
<th>Code</th>
<th>Name</th>
<th>Category</th>
<th>Quantity</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.quantity}}</td>
</tr>
</ng-template>
</p-table>

Output:

This will render a responsive data table with headers and rows based on our product data. The table includes styling for better readability and supports various interactions.

Calendar Component

Let's implement a date picker using the Calendar component:

typescript
// app.component.ts
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
selectedDate: Date | undefined;

onDateSelect(event: any) {
console.log('Selected date:', this.selectedDate);
}
}
html
<!-- app.component.html -->
<h2>PrimeNG Calendar Example</h2>

<div class="card">
<p-calendar [(ngModel)]="selectedDate"
[showIcon]="true"
dateFormat="dd/mm/yy"
(onSelect)="onDateSelect($event)"></p-calendar>

<div *ngIf="selectedDate">
<p>You selected: {{selectedDate | date:'fullDate'}}</p>
</div>
</div>

Note: To use [(ngModel)], you must import FormsModule from '@angular/forms' in your app.module.ts file.

Output:

This will render a date picker with a calendar icon. When a date is selected, it will display the selected date in a user-friendly format below.

Real-World Example: Product Management Dashboard

Now, let's build a more complex example combining multiple PrimeNG components - a simple product management dashboard:

First, extend your app.module.ts with more components:

typescript
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';

// Import PrimeNG modules
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';
import { DialogModule } from 'primeng/dialog';
import { ToastModule } from 'primeng/toast';
import { MessageService } from 'primeng/api';

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
TableModule,
ButtonModule,
InputTextModule,
DialogModule,
ToastModule
],
providers: [MessageService],
bootstrap: [AppComponent]
})
export class AppModule { }

Now create the component:

typescript
// app.component.ts
import { Component } from '@angular/core';
import { MessageService } from 'primeng/api';

interface Product {
id: number;
name: string;
price: number;
category: string;
stockStatus: string;
}

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [MessageService]
})
export class AppComponent {
products: Product[] = [];
displayDialog: boolean = false;
newProduct: Product = this.initNewProduct();
selectedProduct: Product | null = null;

constructor(private messageService: MessageService) {
this.loadProducts();
}

loadProducts() {
// Simulating data fetch from server
this.products = [
{ id: 1, name: 'Bluetooth Headphones', price: 89.99, category: 'Electronics', stockStatus: 'In Stock' },
{ id: 2, name: 'Wireless Mouse', price: 24.99, category: 'Computer Accessories', stockStatus: 'Low Stock' },
{ id: 3, name: 'Ergonomic Keyboard', price: 59.99, category: 'Computer Accessories', stockStatus: 'In Stock' },
{ id: 4, name: 'Smart Watch', price: 199.99, category: 'Electronics', stockStatus: 'Out of Stock' },
{ id: 5, name: 'USB Drive 64GB', price: 19.99, category: 'Storage', stockStatus: 'In Stock' }
];
}

initNewProduct(): Product {
return {
id: 0,
name: '',
price: 0,
category: '',
stockStatus: 'In Stock'
};
}

openNewDialog() {
this.newProduct = this.initNewProduct();
this.displayDialog = true;
}

saveProduct() {
if (this.newProduct.name && this.newProduct.price > 0) {
this.newProduct.id = this.products.length + 1;
this.products = [...this.products, this.newProduct];
this.messageService.add({severity: 'success', summary: 'Success', detail: 'Product added successfully'});
this.displayDialog = false;
this.newProduct = this.initNewProduct();
} else {
this.messageService.add({severity: 'error', summary: 'Error', detail: 'Please fill in all required fields'});
}
}

deleteProduct(product: Product) {
this.products = this.products.filter(p => p.id !== product.id);
this.messageService.add({severity: 'info', summary: 'Deleted', detail: 'Product removed'});
}
}
html
<!-- app.component.html -->
<div class="card">
<p-toast></p-toast>

<h2>Product Management Dashboard</h2>

<div class="p-toolbar-group-start mb-3">
<p-button label="Add New Product" icon="pi pi-plus" (onClick)="openNewDialog()"></p-button>
</div>

<p-table [value]="products" [tableStyle]="{'min-width': '60rem'}" [paginator]="true" [rows]="5">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Price</th>
<th>Category</th>
<th>Stock Status</th>
<th>Actions</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.name}}</td>
<td>{{product.price | currency:'USD'}}</td>
<td>{{product.category}}</td>
<td>
<span [class]="'product-badge status-' + (product.stockStatus === 'In Stock' ? 'instock' :
product.stockStatus === 'Low Stock' ? 'lowstock' : 'outofstock')">
{{product.stockStatus}}
</span>
</td>
<td>
<p-button icon="pi pi-trash" styleClass="p-button-danger p-button-rounded"
(onClick)="deleteProduct(product)"></p-button>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="5">No products found.</td>
</tr>
</ng-template>
</p-table>

<p-dialog header="Add New Product" [(visible)]="displayDialog" [style]="{width: '450px'}" [modal]="true">
<div class="p-fluid">
<div class="field">
<label for="name">Name</label>
<input pInputText id="name" [(ngModel)]="newProduct.name" required />
</div>

<div class="field">
<label for="price">Price</label>
<input pInputText id="price" [(ngModel)]="newProduct.price" required type="number" />
</div>

<div class="field">
<label for="category">Category</label>
<input pInputText id="category" [(ngModel)]="newProduct.category" required />
</div>

<div class="field">
<label for="stockStatus">Stock Status</label>
<input pInputText id="stockStatus" [(ngModel)]="newProduct.stockStatus" />
</div>
</div>

<ng-template pTemplate="footer">
<p-button icon="pi pi-check" label="Save" (onClick)="saveProduct()"></p-button>
<p-button icon="pi pi-times" label="Cancel" styleClass="p-button-secondary"
(onClick)="displayDialog = false"></p-button>
</ng-template>
</p-dialog>
</div>

Add these styles to your project's CSS:

css
/* styles.css */
.product-badge.status-instock {
background: #C8E6C9;
color: #256029;
padding: 0.25rem 0.5rem;
border-radius: 3px;
}

.product-badge.status-lowstock {
background: #FEEDAF;
color: #8A5340;
padding: 0.25rem 0.5rem;
border-radius: 3px;
}

.product-badge.status-outofstock {
background: #FFCDD2;
color: #C63737;
padding: 0.25rem 0.5rem;
border-radius: 3px;
}

.mb-3 {
margin-bottom: 1rem;
}

.field {
margin-bottom: 1rem;
}

Output:

This comprehensive example creates a product management dashboard with:

  • A data table displaying product information with pagination
  • Visual indicators for stock status
  • Add new product functionality with form validation
  • Delete product functionality
  • Toast notifications for user feedback

Customizing PrimeNG Themes

One of PrimeNG's strengths is its theming capability. You can either use the pre-built themes or create your own.

Using Pre-built Themes

PrimeNG comes with several pre-built themes. To use a different theme, simply change the theme import in your angular.json file:

json
"styles": [
"node_modules/primeng/resources/themes/md-light-indigo/theme.css", // Changed from lara-light-blue
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"src/styles.css"
]

Available themes include:

  • lara-light-blue
  • lara-dark-blue
  • md-light-indigo
  • md-dark-indigo
  • bootstrap4-light-blue
  • bootstrap4-dark-blue
  • And many more...

Creating Custom Themes

For more advanced customization, you can create a custom theme:

  1. Install the theme designer:
bash
npm install @primeng/designer
  1. Create a SCSS file (e.g., src/theme.scss):
scss
// Import the designer functions
@import "@primeng/designer";

// Define your custom variables
$primaryColor: #2196F3;
$primaryTextColor: #ffffff;

// Create a theme with primeng-designer
@include primeng-designer-theme(
(
"surface-a": #ffffff,
"surface-b": #f8f9fa,
"surface-c": #e9ecef,
"surface-d": #dee2e6,
"surface-e": #ffffff,
"surface-f": #ffffff,
"text-color": #495057,
"primary-color": $primaryColor,
"primary-color-text": $primaryTextColor
)
);
  1. Import your custom theme in angular.json instead of the pre-built theme:
json
"styles": [
"src/theme.scss",
"node_modules/primeng/resources/primeng.min.css",
"node_modules/primeicons/primeicons.css",
"src/styles.css"
]

Best Practices for PrimeNG Integration

  1. Import only what you need: Import only the PrimeNG modules you're using to keep your bundle size smaller.

  2. Use lazy loading: For large applications, consider using Angular's lazy loading to load specific PrimeNG modules only when needed.

  3. Leverage PrimeNG templates: Use PrimeNG's template system to customize components without modifying their core functionality.

  4. Follow Angular structural patterns: Organize your components, services, and models according to Angular best practices.

  5. Keep up with PrimeNG updates: PrimeNG is actively maintained, so stay updated with the latest versions for bug fixes and new features.

Summary

In this guide, we've covered:

  • How to set up and integrate PrimeNG into an Angular application
  • Using basic PrimeNG components like Button, Table, and Calendar
  • Building a real-world product management dashboard
  • Customizing PrimeNG themes
  • Best practices for using PrimeNG components

PrimeNG provides a comprehensive suite of UI components that can significantly speed up your Angular development process. With its rich component library, theming capabilities, and excellent documentation, PrimeNG is an excellent choice for building professional Angular applications.

Additional Resources

Exercises

  1. Create a contact form using PrimeNG components (InputText, Dropdown, Calendar, and Button) with form validation.
  2. Build a dashboard with multiple PrimeNG components including a Chart, DataTable, and Cards.
  3. Implement a custom theme for PrimeNG that matches your brand colors.
  4. Create a responsive layout using PrimeNG's FlexGrid system.
  5. Build a simple task management application with CRUD operations using PrimeNG components.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)