Combo

The igx-combo component provides a powerful input, combining the features of the basic HTML input, select and the IgniteUI for Angular igx-drop-down components.
The combo component provides easy filtering and multiple selection of items, grouping and adding custom values to the dropdown list.
Custom templates could be provided in order to customize different areas of the components, such as items, header, footer, etc.
The igx-combo component is integrated with the Template Driven Forms and Reactive Forms.
The igx-combo exposes intuitive keyboard navigation and it is accessibility compliant.
Drop Down items are virtualized, which guarantees smooth work, even if the igx-combo is bound to data source with a lot of items.

Demo

Usage

The IgxComboComponent allows you to search and select items from the list. The combo uses the IgxDropDownComponent internally as an item container.

To get started with the combo component, first you need to install Ignite UI for Angular by typing 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 IgxComboModule in our app.module.ts file:

// app.module.ts

...
import { IgxComboModule } from 'igniteui-angular';

@NgModule({
    ...
    imports: [..., IgxComboModule],
    ...
})
export class AppModule {}

Then in the template bind the igx-combo with some data.

export class ComboDemo implements OnInit {
    public cities: { name: string, id: string }[] = [];

    public ngOnInit() {
        this.cities = [{ name: 'London', id: 'UK01' }, { name: 'Sofia', id: 'BG01'}, ...];
    }
}
<igx-combo [data]="cities"></igx-combo>

Our combo is now bound to the array of cities.

Data value and display properties

With the above configuration, since the combo is bound to an array of complex data (i.e. objects), we need to specify a property that the control will use to handle the selected items. The control exposes two @Input properties - valueKey and displayKey

  • valueKey: Optional. Recommended for object arrays. Specifies which property of the data entries is stored for the combo's selection. If valueKey is omitted, the combo value will use references to the data entries (i.e. the selection will be an array of entries from combo.data).
  • displayKey: Required for object arrays. Specifies which property is used for the items' text. If no value is specified for displayKey, the combo will use the specified valueKey (if any).

In our case, we want the combo to display the name of each city and, for the combo value, store the id of each city. We do this by providing these properties to the combo's displayKey and valueKey, respectively:

<igx-combo [data]="cities" displayKey="name" valueKey="id">

The combo is now bound to the data and will display a list of items when initialized. Users can mark items as selected via mouse and keyboard interactions, causing the combo to visually update to reflect the current selection (displaying the selected items in its input and highlighting them as selected in the list). The combo selection can be accessed either through two-way binding or through the selection API.

Note

When the data source is comprised of a simple type (e.g. string[], number[]), do not specify a valueKey and displayKey.

Two-Way Binding

The combo fully supports two way data binding with [(ngModel)] as well use in template driven and reactive forms. We can pass an array of items of the same type as the ones in the combo's selection (based on valueKey) and any time either changes, the other is updated accordingly.

For example, if we follow up with the configurations from the earlier examples:

<igx-combo [data]="cities" [(ngModel)]="selectedCities" displayKey="name" valueKey="id"></igx-combo>
export class MyCombo {
    public cities: { name: string, id: string }[] = [{ name: "Sofia", id: "BG01" }, { name: "London", id: "UK01" }, ...];
    public selectedCities: string[] = ["BG01", "UK01"];
}

With this setup, the cities Sofia and London will initially be selected. Any further changes in the combo's selection will be reflected in the selectedCities array.

Two-way binding can also be achieved without a specified valueKey. For example, if valueKey is omitted, the bound model will be the following:

export class MyCombo {
    public cities: { name: string, id: string }[] = [{ name: "Sofia", id: "BG01" }, { name: "London", id: "UK01" }, ...];
    public selectedCities: { name: string, id: string }[] = [this.cities[0], this.cities[1]];
}

Selection

The combo exposes API that allows getting and manipulating the current selection state of the control.

One way to get the combo's selection is via the selectedItems() method. It returns an array of values which correspond to the selected items, depending on the specified valueKey (if any).

In our cities example, selectedItems will return an array of the selected cities' ids:

export class MyCombo {
    ...
    public selectedItems: string[] = this.combo.selectedItems();
}

Using the selection API, you can also change the combo's selected items without having the user interact with the control - via a button click, as a response to an Observable changing, etc.

For example, let's revisit the cities example and see how we can implement a button that selects a set of cities, using the combo's selectItems method:

<igx-combo [data]="cities" displayKey="name" valueKey="id"></igx-combo>
<button igxButton (click)="selectFavorites()">Select Favorites</button>
export class MyExampleCombo {
    @ViewChild(IgxComboComponent, { read: IgxComboComponent, static: true })
    public combo: IgxComboComponent;
    ...
    selectFavorites(): void {
        this.combo.selectItems(['UK01', 'BG01']);
    }
}

When clicking the button, the cities London and Sofia will be added to the combo's selection.

The combo also fires an event every time its selection changes - onSelectionChange(). The emitted event arguments, IComboSelectionChangeEventArgs, contain information about the selection prior to the change, the current selection, what items were added and removed. The event can also be cancelled, preventing it from updating the selection with the new array of items.

Binding to the event can be done through the proper @Output on the igx-combo tag:

<igx-combo [data]="cities" displayKey="name" valueKey="id" (onSelectionChange)="handleCityChange($event)">

For example, a page could be displaying a statistic for all selected cities. If a cities is added or removed from that selection, we can fire a handler that properly adds/removes the city to the statistic visualization:

export class MyExampleCombo {
    ...
    handleCityChange(event: IComboSelectionChangeEventArgs): void {
        for (const item of event.added) {
            this.addToVisualization(item);
        }
        for (const item of event.removed) {
            this.removeFromVisualization(item);
        }
    }
}

Usage Demo

In the demo below, you can see a side-by-side comparison of the different ways a combo can be bound to data:

Features

Combo control exposes the following features:

Single Selection

By default, the Combo control provides multiple selection. The example below demonstrates how to achieve single selection in the component by attaching a handler to the onSelectionChange event:

<igx-combo [data]="lData" (onSelectionChange)="singleSelection($event)"></igx-combo>
public singleSelection(event: IComboSelectionChangeEventArgs) {
    if (event.added.length) {
        event.newSelection = event.added;
    }
}

Keyboard Navigation

When igxCombo is closed and focused:

  • ArrowDown or Alt + ArrowDown will open the combo drop down and will move focus to the search input.

When igxCombo is opened and search input is focused:

  • ArrowUp or Alt + ArrowUp will close the combo drop down and will move focus to the closed combo.

  • ArrowDown will move focus from the search input to the first list item. If list is empty and custom values are enabled will move it to the Add new item button.

    Note: Any other key stroke will be handled by the input.

When igxCombo is opened and list item is focused:

  • ArrowDown will move to next list item. If the active item is the last one in the list and custom values are enabled then focus will be moved to the Add item button.

  • ArrowUp will move to previous list item. If the active item is the first one in the list then focus will be moved back to the search input.

  • End will move to last list item.

  • Home will move to first list item.

  • Space will select/deselect active list item.

  • Enter will confirm the already selected items and will close the list.

  • Esc will close the list.

When igxCombo is opened, allow custom values are enabled and add item button is focused:

  • Enter will add new item with valueKey and displayKey equal to the text in the search input and will select the new item.

  • ArrowUp focus will be moved back to the last list item or if list is empty will be moved to the search input.

Styling

Using the Ignite UI for Angular Theming, we can greatly alter the igx-combo appearance. Since igx-combo extends igx-drop-down, it also makes good use of its existing igx-drop-down styling, so you can directly refer to the igx-drop-down styling guide for details. On top of that, IgxCombo includes an IgxInputGroup as well, so any styling to the input-group will affect the IgxCombo component. You can refer to igx-input-group styling guide for details. IgxCheckbox is yet another related component. For details check igx-checkbox styling guide.

Code snippets

We are going to use the following:

// in component.scss
@import '~igniteui-angular/lib/core/styles/themes/index';
$my-primary-color:#FFC314;
$my-secondary-color: #7344df;
$my-info-color: #ffffff;

$my-color-palette: igx-palette(
    $primary: $my-primary-color,
    $secondary: $my-secondary-color,
    $info: $my-info-color
);

$custom-drop-down-theme: igx-drop-down-theme(
    $background-color: igx-color($my-color-palette, "secondary", 100),
    $header-text-color: igx-color($my-color-palette, "secondary", 600),
    $item-text-color: igx-color($my-info-color, "info", 100),

    $selected-item-background: igx-color($my-color-palette, "secondary", 400),
    $selected-item-text-color: igx-color($my-color-palette, "info"),
    $selected-hover-item-background: igx-color($my-color-palette, "secondary", 400),
    $selected-hover-item-text-color: igx-color($my-color-palette, "info"),
    $selected-focus-item-background: igx-color($my-color-palette, "secondary", 400),
    $selected-focus-item-text-color: igx-color($my-color-palette, "info"),

    $focused-item-background: igx-color($my-color-palette, "secondary", 300),
    $focused-item-text-color: igx-color($my-color-palette, "info"),

    $hover-item-background: igx-color($my-color-palette, "info"),
    $hover-item-text-color: igx-color($my-color-palette, "secondary", 600)
);

// igx-combo-theme exposes several parameters on top of the igx-drop-down-theme.
// change $search-separator-border-color to one matching better our purple theme
$custom-combo-theme: igx-combo-theme(
    $search-separator-border-color: igx-color($my-color-palette, "secondary", 600)
);

Applying

All that's left is to properly scope our newly created themes. Here we will assume you want to style a particular IgxCombo so the other components of this type in your application will not be affected by the custom themes. For details regarding applying theme globally or scoped, you can refer to igx-drop-down styling guide

// Pass our custom-drop-down-theme and custom-combo-theme to respectively `igx-drop-down` and igx-combo mixins.
:host {
   ::ng-deep {
           @include igx-drop-down($custom-drop-down-theme);
           @include igx-combo($custom-combo-theme);
   }
}
Note

The IgxCombo component uses IgxOverlay to hold and display the igx-combo-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

Known Issues

  • Combo input that displays the selected items is not editable, however due to a browser specifics in IE and FireFox the cursor is visible
  • Backspace works in disabled combo in IE
  • Combo is not having input for sizing its height. In the future IgxInputGroup will expose an option that allows custom sizing and then IgxCombo will use the same functionality for proper styling and better consistency.
Note

igxCombo uses igxForOf directive internally hence all igxForOf limitations are valid for igxCombo. For more details see igxForOf Known Issues section.

Additional Resources

Our community is active and always welcoming to new ideas.