Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

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.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author