Angular is one of the popular JavaScript libraries that allows web developers to develop dynamic and interactive single-page applications. There are different components that are used in the user interfaces to provide functionality in the application. One of the components is the Dropdown Menus, which allows users to select the choice item from the list of many items. While developing the ngbDropdown Menu in Angular, we need to add validation to these menus to make sure that user experiences by preventing invalid selections and guiding users toward selecting the proper choices. In this article, we will see how we can validate the ngbDropdown menu in Angular with two different scenarios or Approaches.
Installation Syntax
Before we proceed to install & configure the Angular Bootstrap, we need to install the Angular CLI. Please refer to the Build an App with Angular and Angular CLI article for a detailed description of the installation.
- Now, to use the Angular Bootstrap, follow the below command:
npm install --save @ng-bootstrap/ng-bootstrap
ng add @angular/material
- Import ng bootstrap module in app.module.ts file.
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
imports: [
NgbModule
]
Project Structure
After following the above installation process, the below project structure will be generated.

Example 1: In this example, we will validate the ngbDropDownMenu in Angular.
HTML
<!-- app.component.html -->
<div class="container">
<h1 class="page-title">GeeksforGeeks</h1>
<h3 class="page-title1">
Add validation to ngbDropdownMenu in Angular
</h3>
<div class="dropdown-container">
<div ngbDropdown class="dropdown">
<button class="dropdown-button"
id="validation-dropdown"
(click)="toggleDropdown()">
Open Dropdown
</button>
<div class="dropdown-menu"
*ngIf="dropdownVisible"
aria-labelledby="validation-dropdown" ngbDropdownMenu>
<form [formGroup]="dropdownForm"
(ngSubmit)="submitForm()"
class="form">
<div class="form-group">
<label for="dropdownSelect">
Select an Item:
</label>
<select id="dropdownSelect"
class="form-control"
formControlName="selectedItem" ngbDropdownToggle>
<option value="" disabled>
Select an option
</option>
<option *ngFor="let item of dropdownItems"
[value]="item">
{{ item }}
</option>
</select>
<div class="error-message"
*ngIf=
"dropdownForm.get('selectedItem')?.hasError('required')">
Please select an item.
</div>
</div>
<button type="submit"
class="btn-primary">
Submit
</button>
</form>
</div>
</div>
</div>
<p class="validation-message"
*ngIf="selectedItem">
You have selected: {{ selectedItem }}
</p>
</div>
CSS
/*app.component.css*/
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
min-height: 100vh;
background-color: #f0f2f5;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.geeks-title {
font-size: 36px;
color: #28a745;
margin-bottom: 5px;
}
.page-title {
font-size: 24px;
color: #28a745;
}
.dropdown-container {
text-align: center;
position: relative;
}
.dropdown-button {
padding: 12px 24px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s;
font-size: 16px;
margin-bottom: 10px;
}
.dropdown-button:hover {
background-color: #0056b3;
}
.dropdown-menu {
position: absolute;
top: calc(100% + 10px);
left: 50%;
transform: translateX(-50%);
width: 260px;
padding: 12px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.1);
z-index: 1000;
text-align: left;
}
.form-group {
margin-bottom: 20px;
}
.form-control {
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 8px;
font-size: 16px;
}
.btn-primary {
background-color: #28a745;
color: #fff;
border: none;
border-radius: 8px;
padding: 12px 24px;
cursor: pointer;
font-size: 16px;
}
.btn-primary:hover {
background-color: #218838;
}
.error-message {
color: #dc3545;
font-size: 14px;
margin-top: 5px;
}
.validation-message {
margin-top: 10px;
text-align: center;
color: #28a745;
font-size: 14px;
}
JavaScript
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators }
from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
dropdownItems: string[] =
['GFG Bag', 'GFG Tshirt', 'GFG Hoodie'];
selectedItem: string = '';
dropdownForm: FormGroup;
dropdownVisible: boolean = false;
constructor(private formBuilder: FormBuilder) {
this.dropdownForm = this.formBuilder.group({
selectedItem: ['', Validators.required],
});
}
toggleDropdown(): void {
this.dropdownVisible = !this.dropdownVisible;
}
submitForm(): void {
if (this.dropdownForm.valid) {
this.selectedItem =
this.dropdownForm.value.selectedItem;
this.dropdownForm.reset();
this.toggleDropdown();
} else {
// Display popup if form is not valid
window.alert('Please select an item.');
}
}
}
JavaScript
// app.module.ts
import { BrowserModule }
from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule }
from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Below are the configuration files:
{
"name": "ngb-dropdown-validation-example",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^16.2.0",
"@angular/cdk": "^16.2.0",
"@angular/common": "^16.2.0",
"@angular/compiler": "^16.2.0",
"@angular/core": "^16.2.0",
"@angular/forms": "^16.2.0",
"@angular/material": "^16.2.0",
"@angular/platform-browser": "^16.2.0",
"@angular/platform-browser-dynamic": "^16.2.0",
"@angular/router": "^16.2.0",
"@ng-bootstrap/ng-bootstrap": "^15.1.1",
"bootstrap": "^5.3.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.2.0",
"@angular/cli": "~16.2.0",
"@angular/compiler-cli": "^16.2.0",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.1.3"
}
}
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ngb-dropdown-validation-example": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/ngb-dropdown-validation-example",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"@angular/material/prebuilt-themes/deeppurple-amber.css",
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "ngb-dropdown-validation-example:build:production"
},
"development": {
"browserTarget": "ngb-dropdown-validation-example:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "ngb-dropdown-validation-example:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"@angular/material/prebuilt-themes/deeppurple-amber.css",
"src/styles.css"
],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": false
}
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts"
],
"include": [
"src/**/*.d.ts"
]
}
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es5",
"module": "es2022",
"useDefineForClassFields": false,
"lib": [
"es2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
Output:
Example 2: In this example, we have used the Validation before using the ngbDropdownMenu. If the user logs in, then only the DropDown is been accessed and the user can select the item from the drop-down. Follow the below directory structure and create the files according to it. Then add the below code to the respective files.

Code Snippets:
HTML
<!--app.component.html-->
<div class="header">
<h1 class="geeks-title">GeeksforGeeks</h1>
<h3 class="page-title">
Add validation to ngbDropdownMenu in Angular
</h3>
</div>
<div class="container">
<button mat-raised-button color="primary"
(click)="toggleAuthentication()">
{{ authService.isAuthenticated ? "Logout" : "Login" }}
</button>
<div class="dropdown-container"
*ngIf="authService.isAuthenticated">
<button mat-button [matMenuTriggerFor]="menu"
(click)="openDropdownMenu()">
Open Dropdown
</button>
<mat-menu #menu="matMenu" xPosition="before">
<button mat-menu-item class="dropdown-item"
*ngFor="let item of dropdownItems; let i = index" [@fadeIn]
(click)="selectDropdownItem(item)">
{{ item }}
</button>
</mat-menu>
</div>
<p class="selected-item-message"
*ngIf="selectedItem !== ''">
{{ selectedItem }} is selected
</p>
</div>
<div class="validation-form" *ngIf="showForm">
<mat-form-field appearance="outline">
<mat-label>Validation Field</mat-label>
<input matInput [(ngModel)]="validationValue" required />
</mat-form-field>
<button mat-button color="accent"
class="validation-button"
(click)="submitValidation()">
Submit
</button>
</div>
CSS
/*app.component.css */
@import
'@angular/material/prebuilt-themes/deeppurple-amber.css';
.header {
text-align: center;
margin-bottom: 20px;
}
.geeks-title {
font-size: 36px;
color: green;
}
.page-title {
font-size: 24px;
margin-top: -10px;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.dropdown-container {
display: inline-block;
position: relative;
margin-top: 20px;
}
.dropdown-item {
display: flex;
align-items: center;
padding: 10px 20px;
cursor: pointer;
transition: background-color 0.3s;
}
.dropdown-item:hover {
background-color: #e6e6e6;
}
.disabled {
opacity: 0.5;
pointer-events: none;
}
JavaScript
// app.component.ts
import { Component, ViewChild }
from '@angular/core';
import { AuthService } from './auth.service';
import {
trigger,
state,
style,
animate,
transition,
} from '@angular/animations';
import { MatMenuTrigger }
from '@angular/material/menu';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('fadeIn', [
state('void', style({ opacity: 0 })),
transition(':enter', animate('300ms ease-out')),
]),
],
})
export class AppComponent {
@ViewChild(MatMenuTrigger) menuTrigger!: MatMenuTrigger;
dropdownItems: string[] =
['GFG Bag', 'GFG Tshirt', 'GFG Hoodie'];
selectedItem: string = '';
showForm: boolean = false;
validationValue: string = '';
constructor(public authService: AuthService) { }
toggleAuthentication(): void {
if (this.authService.isAuthenticated) {
this.authService.logout();
this.closeValidationForm();
this.menuTrigger.closeMenu();
} else {
this.authService.login();
}
}
showValidationForm(): void {
this.showForm = true;
}
submitValidation(): void {
if (this.validationValue.trim() !== '') {
console.log('Validation value submitted:',
this.validationValue);
this.closeValidationForm();
}
}
closeValidationForm(): void {
this.showForm = false;
this.validationValue = '';
}
selectDropdownItem(item: string): void {
this.selectedItem = item;
setTimeout(() => {
this.selectedItem = '';
}, 3000);
}
openDropdownMenu(): void {
if (this.menuTrigger) {
this.menuTrigger.openMenu();
}
}
}
JavaScript
// 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 { MatButtonModule }
from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule }
from '@angular/material/form-field';
import { MatDividerModule }
from '@angular/material/divider';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
MatButtonModule,
MatMenuModule,
MatInputModule,
MatFormFieldModule,
MatDividerModule,
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule { }
JavaScript
// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private _isAuthenticated: boolean = false;
get isAuthenticated(): boolean {
return this._isAuthenticated;
}
login(): void {
this._isAuthenticated = true;
}
logout(): void {
this._isAuthenticated = false;
}
}
Note: Configuration files for this example are the same. All the packages are specified in the above files.
Output:
Similar Reads
How to perform custom validation in Angular forms?
Angular's built-in form controls provide a set of predefined validators for common validation such as required fields, email format, and minimum/maximum values. However, there may be cases where you need to implement custom validation logic specific to your application's requirements. Angular offers
4 min read
How to trigger Form Validators in Angular2 ?
In Angular 2, the best way to deal with complex forms is by using Reactive forms. Below we are going to elaborate on how to trigger form validators for login page. In reactive forms, we use FormControl and by using this, we get access to sub-fields of form and their properties. Some of their propert
4 min read
How to Validate Data in AngularJS ?
In this article, we will know to validate the data in Angular JS, along with understanding the various ways to validate the data through the examples. AngularJS allows client-side form validation. Form validation is necessary because it ensures that the data in the form is correct, complete, and are
10 min read
How to select onchange pass option value in angular 6 ?
In this article, we will see how to select onchange pass option value in angular 6, along with knowing the different techniques for retrieving the value of the user-selected item in a dropdown list & will understand their implementation through the illustration. The Dropdown is a commonly used e
5 min read
How to Add Validator to FormControl After Control is Created in Angular ?
Adding a validator to a form typically refers to the process of defining rules or conditions that suggest whether the data entered into the form fields is valid or not. Initially, the form can be submitted without any validation. However, after adding a validation rule, submission is only allowed if
4 min read
AngularJS Form Validation
AngularJS performs form validation on the client side. AngularJS monitors the state of the form and input fields (input, text-area, select), and notify the user about the current state. AngularJS also holds information about whether the input fields have been touched, modified, or not. Form input fi
3 min read
How to add Buttons without Submit the Form in Angular?
In Angular, when adding buttons to a form, their default behavior on click is to submit the form itself. However, there are certain situations in which it is necessary to create buttons for forms that provide some sort of functionality or trigger custom logic without triggering the default form subm
5 min read
How to achieve Two-Way Data Binding in Angular with ngModel ?
Two-way Data Binding in Angular allows you to automatically synchronize data between a component class property and an input element (e.g., an input field) in your template. To achieve this binding, it's typically used with Angular [(ngModel)] Â directive. This is basically the combination of the Pro
3 min read
How to prevent form submission when input validation fails in AngularJS ?
Validation of fields is an important process while developing a dynamic web application. In terms of security, validation is an important concept. We pass the data from the client side through input fields to the server. If any of the fields is not validated properly and the user sends any irrelevan
7 min read
How to validate checkbox form in angular 15
In Angular applications, it is often necessary to validate form inputs to ensure that users provide the required information correctly. Checkbox inputs are commonly used to allow users to select one or more options from a list. This article will cover different approaches to validating checkbox inpu
5 min read