How to create a dropdown in Angular
Creating dropdown menus is a fundamental task in Angular applications, whether for form inputs or navigation menus. As the creator of CoreUI with over 10 years of Angular experience since 2014, I’ve implemented countless dropdown components in production applications. The most straightforward approach is using native HTML select elements with Angular’s reactive forms for form dropdowns, or custom click-based components for navigation dropdowns. Both approaches provide full control over styling and behavior while maintaining accessibility.
Use <select> with reactive forms for form dropdowns.
import { Component } from '@angular/core'
import { FormControl, ReactiveFormsModule } from '@angular/forms'
@Component({
selector: 'app-dropdown',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<select [formControl]="selectedOption">
<option value="">Select an option</option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
<p>Selected: {{ selectedOption.value }}</p>
`
})
export class DropdownComponent {
selectedOption = new FormControl('')
}
Here the FormControl tracks the selected value. The [formControl] directive binds the select element to the form control. When users select an option, selectedOption.value updates automatically. This approach works seamlessly with Angular’s form validation.
Creating a Custom Dropdown Component
Build a custom dropdown with click handling and positioning.
import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
@Component({
selector: 'app-custom-dropdown',
standalone: true,
imports: [CommonModule],
template: `
<div class="dropdown">
<button (click)="toggleDropdown()">
{{ selectedOption || 'Select an option' }}
</button>
<ul *ngIf="isOpen" class="dropdown-menu">
<li *ngFor="let option of options" (click)="selectOption(option)">
{{ option }}
</li>
</ul>
</div>
`,
styles: [`
.dropdown { position: relative; }
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
background: white;
border: 1px solid #ccc;
list-style: none;
padding: 0;
margin: 0;
}
.dropdown-menu li {
padding: 8px 12px;
cursor: pointer;
}
.dropdown-menu li:hover {
background: #f0f0f0;
}
`]
})
export class CustomDropdownComponent {
isOpen = false
selectedOption = ''
options = ['Option 1', 'Option 2', 'Option 3']
toggleDropdown() {
this.isOpen = !this.isOpen
}
selectOption(option: string) {
this.selectedOption = option
this.isOpen = false
}
}
The isOpen property controls dropdown visibility. The toggleDropdown() method handles button clicks. The selectOption() method updates the selected value and closes the dropdown. The styles position the menu absolutely below the button.
Creating a Dropdown with Dynamic Data
Load dropdown options from an API or service.
import { Component, OnInit } from '@angular/core'
import { CommonModule } from '@angular/common'
import { FormControl, ReactiveFormsModule } from '@angular/forms'
interface DropdownOption {
id: number
label: string
value: string
}
@Component({
selector: 'app-dynamic-dropdown',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<select [formControl]="selected">
<option value="">Select...</option>
<option *ngFor="let option of options" [value]="option.value">
{{ option.label }}
</option>
</select>
`
})
export class DynamicDropdownComponent implements OnInit {
selected = new FormControl('')
options: DropdownOption[] = []
ngOnInit() {
this.loadOptions()
}
loadOptions() {
this.options = [
{ id: 1, label: 'First Option', value: 'first' },
{ id: 2, label: 'Second Option', value: 'second' },
{ id: 3, label: 'Third Option', value: 'third' }
]
}
}
The options array stores dropdown data. The ngOnInit() lifecycle hook loads options when the component initializes. The *ngFor directive renders an option element for each item. Replace loadOptions() with an HTTP call to fetch options from an API.
Creating a Multi-Select Dropdown
Allow users to select multiple options.
import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { FormControl, ReactiveFormsModule } from '@angular/forms'
@Component({
selector: 'app-multi-select',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
template: `
<select [formControl]="selected" multiple size="5">
<option *ngFor="let option of options" [value]="option">
{{ option }}
</option>
</select>
<p>Selected: {{ selected.value | json }}</p>
`
})
export class MultiSelectComponent {
selected = new FormControl<string[]>([])
options = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']
}
The multiple attribute enables multi-select mode. The size attribute controls how many options are visible. The form control value becomes an array containing all selected values. Users hold Ctrl (Windows) or Cmd (Mac) to select multiple items.
Creating a Searchable Dropdown
Add search functionality to filter dropdown options.
import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { FormsModule } from '@angular/forms'
@Component({
selector: 'app-searchable-dropdown',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<div class="dropdown">
<input
type="text"
[(ngModel)]="searchTerm"
(focus)="isOpen = true"
placeholder="Search..."
/>
<ul *ngIf="isOpen && filteredOptions.length > 0" class="dropdown-menu">
<li *ngFor="let option of filteredOptions" (click)="selectOption(option)">
{{ option }}
</li>
</ul>
</div>
`
})
export class SearchableDropdownComponent {
isOpen = false
searchTerm = ''
options = ['Apple', 'Apricot', 'Banana', 'Cherry', 'Date']
get filteredOptions() {
return this.options.filter(option =>
option.toLowerCase().includes(this.searchTerm.toLowerCase())
)
}
selectOption(option: string) {
this.searchTerm = option
this.isOpen = false
}
}
The searchTerm property binds to the input via [(ngModel)]. The filteredOptions getter filters options based on the search term. The dropdown opens on input focus and shows only matching options. This provides a better user experience for long option lists.
Best Practice Note
This is the same dropdown implementation pattern we use in CoreUI Angular components for reliable form inputs and navigation menus. For production applications, consider using CoreUI’s CDropdown component which provides a fully accessible, keyboard-navigable dropdown with built-in click-outside detection and positioning logic. The CoreUI dropdown handles edge cases like viewport boundaries, nested dropdowns, and mobile touch interactions automatically, saving significant development time.



