Angular Drop Down Component Overview

    The Ignite UI for Angular Drop Down is a component, which displays a toggleable list of predefined values and allows users to easily select a single option item with a click. It can be quickly configured to act as a drop down menu or you can simply use it to deliver more useful visual information by grouping data. With grouping you can use both flat and hierarchical data. Drop Down component allows declarative binding, which makes it possible for you to embed additional content and links. This also leaves room for further UI customization and styling of the Angular drop down list appearance. In addition to this, it is packed with key features like keyboard dropdown navigation and virtualization.

    Angular Drop Down Example

    This Angular drop down example demonstrates the basic functionalities of a drop down list. Click on it to expand the preset options, select an item, and then close the drop down.

    Getting Started with Ignite UI for Angular Drop Down

    To get started with the Ignite UI for Angular Drop Down component, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:

    ng add igniteui-angular
    

    For a complete introduction to the Ignite UI for Angular, read the getting started topic.

    The next step is to import the IgxDropDownModule in your app.module.ts file.

    // app.module.ts
    
    ...
    import { IgxDropDownModule } from 'igniteui-angular';
    // import { IgxDropDownModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., IgxDropDownModule],
        ...
    })
    export class AppModule {}
    

    Alternatively, as of 16.0.0 you can import the IgxDropDownComponent as a standalone dependency, or use the IGX_DROP_DOWN_DIRECTIVES token to import the component and all of its supporting components and directives.

    // home.component.ts
    
    import { NgFor } from '@angular/common';
    import { IGX_DROP_DOWN_DIRECTIVES, IgxToggleActionDirective, IgxButtonDirective } from 'igniteui-angular';
    // import { IGX_DROP_DOWN_DIRECTIVES, IgxToggleActionDirective, IgxButtonDirective } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <button igxButton="contained" 
            [igxToggleAction]="dropdown"
            [igxDropDownItemNavigation]="dropdown">
            Options
        </button>
        <igx-drop-down #dropdown>
            <igx-drop-down-item *ngFor="let item of items">
                {{ item.field }}
            </igx-drop-down-item>
        </igx-drop-down>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [IGX_DROP_DOWN_DIRECTIVES, IgxToggleActionDirective, IgxButtonDirective, NgFor]
        /* or imports: [IgxDropDownComponent, IgxDropDownItemComponent, IgxToggleActionDirective, IgxButtonDirective, NgFor] */
    })
    export class HomeComponent {}
    

    Now that you have the Ignite UI for Angular Drop Down module or directives imported, you can start using the igx-drop-down component.

    Using the Angular Drop Down

    Add Drop Down

    Let's create a simple drop-down that provides several option items to choose from. To achieve this, we will use the IgxDropDownComponent as well as the IgxToggleAction to open/close the drop-down.

    <!-- dropdown.component.html -->
    <button igxButton="contained" 
            [igxToggleAction]="dropdown"
            [igxDropDownItemNavigation]="dropdown">
            Options
    </button>
    <igx-drop-down #dropdown>
        <igx-drop-down-item *ngFor="let item of items">
            {{ item.field }}
        </igx-drop-down-item>
    </igx-drop-down>
    
    // dropdown.component.ts
    @Component({...})
    export class MyDropDownComponent {
        public items: Array<{ field: string }> = [
            { field: 'Option 1' },
            { field: 'Option 2' },
            { field: 'Option 3' }
        ];
    }
    

    More Angular Drop Down Examples

    The default demo shows the use of a toggleable Drop Down List in Angular that lets end-users expand all predefined items and opt for one of them. Check out the following example and see the Angular Drop Down list in action.

    Predefined selected item

    Let's say we want to have a predefined selected item. One way to do this, is by handling the opening event of the drop-down component.

    <!-- dropdown.component.html -->
    <button igxButton="contained" 
            [igxToggleAction]="dropdown" 
            [igxDropDownItemNavigation]="dropdown">
            Options
    </button>
    <igx-drop-down #dropdown (opening)="dropdown.setSelectedItem(0)">
        <igx-drop-down-item *ngFor="let item of items">
            {{ item.field }}
        </igx-drop-down-item>
    </igx-drop-down>
    
    // dropdown.component.ts
    export class MyDropDownComponent {
        public items: Array<{ field: string }> = [
            { field: 'Option 1' },
            { field: 'Option 2' },
            { field: 'Option 3' }
        ];
    }
    

    Grouping items

    To provide a more useful visual information, use the isHeader property to group items semantically or the disabled property to display an item as a non-interactive. You can also set the selected property on a particular item to make it the selected item. The igx-drop-down items have out-of-the-box support for igxPrefix, igxSuffix, and igx-divider directives that can contain or be set on HTML elements or other web components.

    <!-- dropdown.component.html -->
    <button igxButton="contained" 
            [igxToggleAction]="dropdown"
            [igxDropDownItemNavigation]="dropdown">
            Countries
    </button>
    <igx-drop-down #dropdown [width]="'240px'">
        <div class="drop-down__scroll-container">
            <igx-drop-down-item *ngFor="let item of items" 
                                [disabled]="item.disabled"
                                [isHeader]="item.header"
                                [selected]="item.selected">
                <igx-icon igxPrefix>place</igx-icon>
                {{ item.field }}
                <span igxSuffix>{{ item.code }}</span>
                <igx-divider></igx-divider>
            </igx-drop-down-item>
        </div>
    </igx-drop-down>
    
    // dropdown.component.ts
    export class MyDropDownComponent {
        public items: any[] = [
            { field: 'European Union', code: 'EU', header: true },
            { field: 'Germany', code: 'DE' },
            { field: 'Bulgaria', code: 'BG', selected: true },
            { field: 'France', code: 'FR', disabled: true },
            { field: 'North America', code: 'NA', header: true },
            { field: 'Canada', code: 'CA' },
            { field: 'United States', code: 'US' },
            { field: 'Mexico', code: 'MX' }
        ];
    }
    

    If the sample is configured properly, a list of countries should be displayed as a group under European Union header, France as a non-interactive item, and Bulgaria as a selected item:

    Grouping hierarchical data

    The igx-drop-down items can also be grouped using the igx-drop-down-item-group container, making it easier for users to differentiate separate categories. The igx-drop-down-item-group accepts igx-drop-down-item elements as its content and renders them in a grouped fashion.

    // dropdown.component.ts
    export class MyCustomDropDownComponent {
        ...
        public foods: { 
            name: string,
            entries: { name: string, refNo: string }[]
        }[] = [
        {
            name: 'Vegetables',
            entries: [{
                name: 'Cucumber',
                refNo: '00000'
            }, {
                name: 'Lettuce',
                refNo: '00001'
            },
            ...]
        }, {
            name: 'Fruits',
            entries: [{
                name: 'Banana',
                refNo: '10000'
            }, {
                name: 'Tomato',
                refNo: '10001'
            },
            ...]
        }, {
            name: 'Meats',
            entries: [{
                name: 'Chicken',
                refNo: '20000'
            }, {
                name: 'Beef',
                refNo: '20001'
            },
            ...]
        }];
    }
    
    <igx-drop-down>
        <igx-drop-down-item-group *ngFor="let foodGroup of foods" [label]="foodGroup.name">
            <igx-drop-down-item *ngFor="let food of foodGroup.entries" [value]='food.refNo'>
                {{ food.name }}
            </igx-drop-down-item>
        </igx-drop-down-item-group>
    </igx-drop-down>
    

    The group also has the additional functionality of disabling items inside of its body. For example, lets say we do not want the Meats food group to be selectable in our drop-down. Instead of disabling all of the entries in Meats separately, we can disable the group, as well as all of the child items inside:

    <igx-drop-down>
        <igx-drop-down-item-group *ngFor="let foodGroup of foods" [label]="foodGroup.name" [disabled]="foodGroup.name === 'Meats'">
            <igx-drop-down-item *ngFor="let food of foodGroup.entries" [value]='food.refNo'>
                {{ food.name }}
            </igx-drop-down-item>
        </igx-drop-down-item-group>
    </igx-drop-down>
    

    You can see the results in the sample below:

    You can configure the drop-down to behave as a menu. To do this, set the ISelectionEventArgs interface cancel member to true in the selectionChanging event handler. In this way, the selected item is not preserved when opening the menu and previous selections get invalidated. Still, you can get the clicked item through the newSelection member value in the event.

    <!-- dropdown.component.html -->
    <div>
        <igx-navbar title="Contacts">
            <button [igxToggleAction]="menu"
                    [igxToggleOutlet]="outlet"
                    [overlaySettings]="overlaySettings"
                    [igxDropDownItemNavigation]="menu"
                    igxIconButton="flat">
                <igx-icon fontSet="material">more_vert</igx-icon>
            </button>
            <igx-drop-down #menu (selectionChanging)="selectionHandler($event)">
                <igx-drop-down-item *ngFor="let item of items" [value]="item.text">
                    <div>{{ item.text }}</div>
                </igx-drop-down-item>
            </igx-drop-down>
        </igx-navbar>
    
        <div>
            <ng-container *ngIf="text">
                <label igxLabel>{{ text }}</label>
            </ng-container>
        </div>
    
        <div igxOverlayOutlet #outlet="overlay-outlet"></div>
    </div>
    
    // dropdown.component.ts
    export class MyMenuComponent {
        public items: Array<{ text: string }> =
            [{ text: 'Add New Contact' }, { text: 'Edit Contact' }, { text: 'Refresh' }, { text: 'Help' }];
        public text: string;
        public overlaySettings = {
            positionStrategy: new ConnectedPositioningStrategy({
                horizontalDirection: HorizontalAlignment.Left,
                horizontalStartPoint: HorizontalAlignment.Right,
                verticalStartPoint: VerticalAlignment.Bottom
            }),
            scrollStrategy: new NoOpScrollStrategy()
        };
    
        public selectionHandler(eventArgs: ISelectionEventArgs) {
            this.text = eventArgs.newSelection.value;
            eventArgs.cancel = true;
        }
    }
    

    Mutli-Level Drop Down menu

    The following sample demonstrates how to implement a multi-level drop down menu that allows the user to quickly and easily navigate through a hierarchy of content by hovering on a series of nested menus.

    For the implementation of the multi-level drop down menu we will use the IgxDropDownComponent as well as a custom directive and service described below.

    In order to configure the IgxDropDownItem to open an additional drop down, add the multiLevel directive that would handle the overlay settings of the nested drop down and manages its opened/closed state through its innerDropdown property.

    <igx-drop-down #dropdown1>
        <igx-drop-down-item [value]="'Web'" multiLevel [innerDropdown]="web">
            Web <igx-icon igxSuffix>chevron_right</igx-icon>
        </igx-drop-down-item>
        ...
    </igx-drop-down>
    
    <igx-drop-down #web>
        <igx-drop-down-item [value]="'App Builder'">
            App Builder
        </igx-drop-down-item>
        ...
    </igx-drop-down>
    

    To configure the multi-level drop down to behave as a menu, you need to handle the selectionChanging event of all drop downs in the hierarchy and cancel the default behavior. Then, in order to handle the selection properly you could use the MultiLevelService's handleSelection method and in order to prevent closing the drop down when clicking on a menu item, use the MultiLevelService's handleClosing methods.

    @ViewChildren(IgxDropDownComponent, { read: IgxDropDownComponent })
    private _dropdowns: QueryList<IgxDropDownComponent>;
    
    @ViewChild('dropdown1', { read: IgxDropDownComponent })
    private _multiLevelDropdown: IgxDropDownComponent;
    
    constructor(private _multiLevelService: MultiLevelService) { }
    
    public ngAfterViewInit(): void {
        this._dropdowns.forEach((dropdown) => {
            dropdown.selectionChanging.subscribe((args) => {
                args.cancel = true;
                const value = args.newSelection.value;
                const categories = this._multiLevelService.categories;
    
                if (categories.includes(value)) {
                    this.selection = '';
                    return;
                }
    
                if (this._multiLevelService.isMultiLevel(dropdown)) {
                    this._multiLevelService.handleSelection();
                } else {
                    dropdown.close();
                }
    
                this.selection = value;
            });
        });
    
        this._multiLevelDropdown.closing.subscribe((args) => {
            this._multiLevelService.handleClosing(args);
        });
    }
    

    The result from the above configurations could be seen in the below sample.

    Note

    To display the Dropdown component opened initially, it is recommended to set the open method as a callback of the requestAnimationFrame method. This will ensure that the DOM tree is repainted and all elements are correctly positioned.

    Use the igxDropDownItemNavigation directive to enable keyboard navigation for the igxDropDown component. In order to allow the directive to handle all triggered events, it should be applied to the active (focused) element or a parent container. By default, a drop-down or its items don't take focus, so the directive can be placed on a button or input that will control the drop-down. The navigation directive value should target a component that is an instance or a descendant of the IgxDropDownBaseDirective class.

    The following sample demonstrates an input that opens and closes the igxDropDown instance on click. Applying the igxDropDownItemNavigation directive on the input itself will enable keyboard navigation when using the up and down arrow keys. This relies on the default drop-down behavior with the allowItemsFocus property set to false to allow the input to maintain focus.

    <!-- input-dropdown.component.html -->
    <igx-input-group #inputGroup [igxToggleAction]="dropDown">
        <input type="text" igxInput [igxDropDownItemNavigation]="dropDown"
            readonly= "true"
            placeholder="choose an option"
            [value]="dropDown.selectedItem?.value"
            (keydown.ArrowDown)="openDropDown()"/>
    
        <igx-suffix igxIconButton="flat" igxRipple>
            <igx-icon>arrow_drop{{ dropDown.collapsed ? '_down' : '_up' }}</igx-icon>
        </igx-suffix>
    </igx-input-group>
    
    <span>Selected: {{ dropDown.selectedItem?.value }}</span>
    <igx-drop-down #dropDown [width]="'160px'">
        <igx-drop-down-item *ngFor="let item of items" [value]="item.field">
            {{ item.field }}
        </igx-drop-down-item>
    </igx-drop-down>
    
    // input-dropdown.component.ts
    export class InputDropDownComponent {
        @ViewChild(IgxDropDownComponent) public igxDropDown: IgxDropDownComponent;
        @ViewChild('inputGroup', { read: IgxInputGroupComponent}) public inputGroup: IgxInputGroupComponent;
    
        public items: Array<{ field: string }> = [
            { field: 'Option 1' },
            { field: 'Option 2' },
            { field: 'Option 3' }
        ];
    
        public openDropDown() {
            if (this.igxDropDown.collapsed) {
                this.igxDropDown.open({
                    modal: false,
                    positionStrategy: new ConnectedPositioningStrategy({
                        target: this.inputGroup.element.nativeElement
                    })
                });
            }
        }
    }
    

    Applying the directive will ensure the following actions are executed as a result from the keyboard navigation:

    Name Description
    Enter Select item from the drop down and closes the drop down.
    Space Select item from the drop down and closes the drop down.
    Esc Closes the drop down.
    Arrow Down Navigate to the next item in the target component.
    Arrow Up Navigate to the previous item in the target component.
    End Navigate to the last item in the target component.
    Home Navigate to the first item in the target component.

    When the allowItemsFocus property is enabled, the drop down items gain tab index and are focused when active. The focused drop-down items are the ones that trigger events, during keyboard navigation, which means that the navigation directive should be applied on the individual drop-down items.

    <igx-input-group [igxToggleAction]="dropDown">
        <input igxInput type="text">
    </igx-input-group>
    <igx-drop-down #dropDown [allowItemsFocus]="true">
        <igx-drop-down-item *ngFor="let p of provinceData" [igxDropDownItemNavigation]="dropDown">
            {{ p }}
        </igx-drop-down-item>
    </igx-drop-down>
    

    Styling

    Using the Ignite UI for Angular Theming, we can greatly alter the drop-down appearance. First, in order for us to use the functions exposed by the theme engine, we need to import the index file in our style file:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Following the simplest approach, we create a new theme that extends the drop-down-theme and accepts some of the default theme's parameters.

    $custom-drop-down-theme: drop-down-theme(
        $background-color: #fdfdfd,
        $header-text-color: #345779,
        $item-text-color: #2dabe8,
        $selected-item-background: #345779,
        $selected-item-text-color: #fdfdfd,
        $selected-hover-item-background: #345779,
        $selected-hover-item-text-color: #fdfdfd,
        $selected-focus-item-background: #345779,
        $selected-focus-item-text-color: #fdfdfd,
        $hover-item-background: rgba(0, 0, 0, 0.12),
        $hover-item-text-color: #345779,
    );
    

    Using CSS variables

    The last step is to pass the custom drop-down theme:

     @include css-vars($custom-drop-down-theme);
    

    Using Theme Overrides

    In order to style components for older browsers, like Internet Explorer 11, we have to use a different approach, since it doesn't support CSS variables.

    If the component is using the Emulated ViewEncapsulation, it is necessary to penetrate this encapsulation using ::ng-deep. To prevent the custom theme to leak into other components, be sure to include the :host selector before ::ng-deep:

    :host {
     ::ng-deep {
       @include drop-down($custom-drop-down-theme);
     }
    }
    
    Note

    The IgxDropDown component uses the IgxOverlay to hold and display the igx-drop-down-items list container. To properly scope your styles you might have to use an OverlaySetting.outlet. For more details check: IgxOverlay styling guide.

    Demo

    API Summary

    Theming Dependencies

    Additional Resources

    Our community is active and always welcoming to new ideas.