Combobox In Angular Using Ignite UI

A Combo box control is very commonly use in Web applications where we need to select one item from a list of available items.

Introduction

A Combo box control is very commonly used in Web applications where we need to select one item from a list of available items.

Ignite UI library provides a set of rich UI controls including a Combo box, iigCombo, that comes with advanced features such as multi-selection, animation, grouping, style, header, footer and item template. You can learn more about IgCombo control here.

Let's get started.

We are using Visual Studio code as IDE for this example and Angular's latest version. If you do not have IgniteUI setup, start here.

Simple Combo

Let's make a new project in Angular. I am assuming you’ve already set up the NodeJS and IgniteUI for the Angular project. Use the below command to make a new project. Here we are naming this project as IgniteUI-Combo. See listing 1.

  1. “ng new IgniteUI-Combo”  

Listing 1.

Now go to the app.module.ts file and add the reference of ComboModule. See listing 2.

  1. import { IgxComboModule } from "igniteui-angular";  
  2. // to use ngModel in page  
  3. import { FormsModule } from "@angular/forms";   
  4. // for combo animation  
  5. import { BrowserAnimationsModule } from "@angular/platform-browser/animations";   

And in Import section of app.module.ts file add the following line. See listing 2.

  1. imports : [  
  2.    IgxComboModule,  
  3.    FormsModule,  
  4.    BrowserAnimationsModule   
  5. ]  

Listing 2.

Let’s make a new component where we use IgniteUI-Combo. To create a new component, refer to listing 3.

  1. “ng generate component page1”  
  2.   
  3. or  
  4.   
  5. “ng g c page1”  

Listing 3.

To call this component from the page, go to the app.component.html and delete all the content and simply write the selector of our page1 component which is ‘app-page1’. See listing 4.

  1. <app-page1></app-page1>  

 

Listing 4.

Let’s create a data source for our combo box. We will use JSON data to bind the combo box in page1.components.ts. We are using static but you can call the API and bind dynamic data with combo too. Refer to listing 5.

  1. countriesStaticData = [  
  2.        { 'countryId''1''countryName''India' },  
  3.        { 'countryId''2''countryName''China' },  
  4.        { 'countryId''3''countryName''United States' },  
  5.        { 'countryId''4''countryName''Australia' },  
  6.        { 'countryId''5''countryName''United Kingdom' },  
  7.        { 'countryId''6''countryName''Egypt' }  
  8. ;  

Listing 5.

Now go to the page1.component.html page and add igx-combo control on page1.components.html. See listing 6.

  1. <igx-combo class="input-container" [data]="countriesStaticData" [displayKey]="'countryName'" placeholder="Countries" [valueKey]="'countryId'"> </igx-combo>  

Listing 6.

This is a very basic combo and it’ll work like any other combo box but there are some in-built features that are only provided by Ignite UI as follows,

  • Filter - To make combo filterable via text all you need to do is add property in igx-combo. i.e. [filterable]="true" and to make placeholder in search box searchPlaceholder="Search...".
  • Item Height - We can also set the item height of combo list by add property “itemsMaxHeight”.
  • Custom Value - Custom values can also be added at run time. To add this functionality to combo add the “allowCustomValues” property of igx-combo control.

    To add custom value we can also invoke “(onAddition) = "handleAddition($event)"” to make  custom item permanent.
  • Two-way binding - It also support the two-way binding, we can set the combo value on ngOnInit or we can get the value of combo.

For the example, I’ve set the allowCustomValues to true didn't add the correspondent handling event in page1.component.ts file. It will not give any error, in fact it’ll add the custom value to list temporarily. So the final code for page1.component.html will be like listing 7. I have also bound what value of combo is selected in the page.

  1. <div class="container" style="margin-top: 20px">  
  2.     <div class="row">  
  3.         <div class="col-sm-3">  
  4.             <igx-combo class="input-container" [(ngModel)]="CountryObj" width="270px"                    [data]="countriesStaticData" [displayKey]="'countryName'"  
  5.             [valueKey]="'countryId'" placeholder="Countries" [allowCustomValues]="true"                     [itemsMaxHeight]="250" [filterable]="true" searchPlaceholder="Search...">  
  6.             </igx-combo>  
  7.         </div>  
  8.         <div class="col-sm-4">  
  9.             <span *ngFor="let o of CountryObj">  
  10.                 CountryId :  
  11.                 <b>{{o.countryId}}</b> , CountryName :  
  12.                 <b> {{o.countryName}}</b>  
  13.                 <br>  
  14.             </span>  
  15.         </div>  
  16.     </div>  
  17. </div>  

Listing 7.

To run the app type ng serve --open in terminal and the final output will be like Figure 1.

 

Combobox In Angular Using Ignite UI
Figure 1.

 

Combo With Template

Let’s extend this example more and add another combo for state. In State Combo we will demonstrate the following,

  • Filtering the data based on selected countries.
  • Grouping the states by countries.
  • Custom header, footer and item template.

Let’s add state data for second combo. See listing 8.

  1. statesStaticData = [  
  2.         { 'countryName''India''countryId''1''stateId''1''stateName''Delhi' },  
  3.         { 'countryName''India''countryId''1''stateId''2''stateName''Mumbai' },  
  4.         { 'countryName''India''countryId''1''stateId''3''stateName''Banglore' },  
  5.         { 'countryName''China''countryId''2''stateId''4''stateName''Hunam' },  
  6.         { 'countryName''China''countryId''2''stateId''5''stateName''Yunnan' },  
  7.         { 'countryName''China''countryId''2''stateId''6''stateName''Jiangsu' },  
  8.         { 'countryName''United States''countryId''3''stateId''7''stateName''Texas' },  
  9.         { 'countryName''United States''countryId''3''stateId''8''stateName''New York' },  
  10.         { 'countryName''United States''countryId''3''stateId''9''stateName''Connecticut' },  
  11.         { 'countryName''United Kingdom''countryId''4''stateId''10''stateName''Queensland' },  
  12.         { 'countryName''United Kingdom''countryId''4''stateId''11''stateName''Victoria' },  
  13.         { 'countryName''United Kingdom''countryId''4''stateId''12''stateName''New South           Wales' },  
  14.         { 'countryName''United Kingdom''countryId''5''stateId''13''stateName''England' },  
  15.         { 'countryName''United Kingdom''countryId''5''stateId''14''stateName''Northern            Ireland' },  
  16.         { 'countryName''United Kingdom''countryId''5''stateId''15''stateName''Scotland and            Wales' },  
  17.         { 'countryName''Egypt''countryId''6''stateId''16''stateName''Aswan' },  
  18.         { 'countryName''Egypt''countryId''6''stateId''17''stateName''Cairo' },  
  19.         { 'countryName''Egypt''countryId''6''stateId''18''stateName''Hurghada' }  
  20. ];  

Listing 8

Create another variable to hold the filtered states according to countries. We will use that later in this example .

  1. filterdStates: any[];  

Edit the page1.component.ts. See Listing 9.

  1. <div class="row">  
  2.     <div class="col-sm-3" style="text-align: right">  
  3.         <h5 style="line-height: 45px"> States</h5>  
  4.     </div>  
  5.     <div class="col-sm-4">  
  6.         <igx-combo class="input-container" [(ngModel)]="StateObj" width="300px"                      [data]="filterdStates" [displayKey]="'stateName'"  
  7.         [valueKey]="'stateId'" placeholder="States" [groupKey]="'countryName'"                      [allowCustomValues]="true" [itemsMaxHeight]="250"  
  8.         [filterable]="true" searchPlaceholder="Search...">  
  9. </div>  
  10. <div class="col-sm-4">  
  11.     <span *ngFor="let s of StateObj">  
  12.         StateId :  
  13.         <b>{{s.stateId}}</b> , StateName :  
  14.         <b> {{s.stateName}}</b>  
  15.         <br>  
  16.     </span>  
  17. </div>  
  18. </div>  

Listing 9

Note we also have added the “ [groupKey]="'countryName'" in the igx-combo to group by the list item.

If you run this application by using command ng serve --open, it will work as the last one. See Figure 2.

 

Combobox In Angular Using Ignite UI
Figure 2.

 

To add the filtering with state combo when selecting countries combo, first we need to add the ngModelChange event in country combo. This event will fire every time when the ngModel will get changed and this event will handle it. To filter the country combo data source, see Listing 10.

Add the below code snippets in page1.component.html

  1. (ngModelChange) = "CountryComboChange($event)"d  

Listing 10.

Also add the below code in page1.component.ts

  1. CountryComboChange(obj: any): void {  
  2. // First we blank the array  
  3.         this.filterdStates = [];  
  4. // Check if user unselect all countries then all state will be bind.  
  5.         if(obj.length == 0) {  
  6.         this.filterdStates = this.statesStaticData;  
  7.         return;  
  8. }  
  9. //For each loop for country ngModel  
  10.     obj.forEach(element => {  
  11.         let tempobj = this.statesStaticData.filter((obj) => obj.countryId === element.countryId);  
  12. //We cannot push obj directly to array cause the structure is change (object inside object)  
  13.         tempobj.forEach(e => {  
  14.             this.filterdStates.push(e);  
  15.         });  
  16.         this.filterdStates.push();  
  17.     });      
  18.   }  

Listing 11

Save the file and go back to the browser, you will see the filter. See Figure 3.

 

Combobox In Angular Using Ignite UI
Figure 3.

 

Let’s add the custom template for item list. Here we can create four types of custom templates which are as follows,

  • Item Template
  • Header Template
  • Footer Template
  • Empty Template
Item Template
  1. <ng-template #itemTemplate let-display let-key="valueKey">  
  2.     <div class="item">  
  3.         <span>{{ display.stateName }} - </span>  
  4.         <span> (StateId - {{ display[key] }})</span>  
  5.     </div> 
Header Template

  1. <ng-template #headerTemplate>  
  2.    <div class="header-class">This is Header</div>  
  3. </ng-template>  

 

Footer Template 

  1. <ng-template #footerTemplate>  
  2.    <div class="footer-class">This is Footer</div>    
  3. <ng-template>  
Empty Template

  1. <igx-combo>  
  2. <ng-template #emptyTemplate>    
  3.     <span class="empty-class">No available states</span>    
  4. </ng-template>    
  5. </igx-combo>    

 

We will need to add this inside igx-combo tag. So the Complete Code of page1.component.html. See Listing 11.

  1. <div class="container" style="margin-top: 20px">  
  2.     <div class="row">  
  3.         <div class="col-sm-3" style="text-align: right">  
  4.             <h5 style="line-height: 45px">Countries</h5>  
  5.         </div>  
  6.         <div class="col-sm-4">  
  7.             <igx-combo class="input-container" [(ngModel)]="CountryObj" (ngModelChange)="CountryComboChange($event)" width="300px" [data]="countriesStaticData"  
  8.                        [displayKey]="'countryName'" [valueKey]="'countryId'" placeholder="Countries" [allowCustomValues]="true" [itemsMaxHeight]="250"  
  9.                        [filterable]="true" searchPlaceholder="Search...">  
  10.             </igx-combo>  
  11.         </div>  
  12.         <div class="col-sm-4">  
  13.             <span *ngFor="let o of CountryObj">  
  14.                 CountryId :  
  15.                 <b>{{o.countryId}}</b> , CountryName :  
  16.                 <b> {{o.countryName}}</b>  
  17.                 <br>  
  18.             </span>  
  19.         </div>  
  20.     </div>  
  21.     <br>  
  22.     <div class="row">  
  23.         <div class="col-sm-3" style="text-align: right">  
  24.             <h5 style="line-height: 45px"> States</h5>  
  25.         </div>  
  26.         <div class="col-sm-4">  
  27.             <igx-combo class="input-container" [(ngModel)]="StateObj" width="300px" [data]="filterdStates" [displayKey]="'stateName'"  
  28.                        [valueKey]="'stateId'" placeholder="States" [groupKey]="'countryName'" [allowCustomValues]="true" [itemsMaxHeight]="250"  
  29.                        [filterable]="true" searchPlaceholder="Search...">  
  30.   
  31.                 <ng-template #itemTemplate let-display let-key="valueKey">  
  32.                     <div class="item">  
  33.                         <span>{{ display.stateName }} - </span>  
  34.                         <span> (StateId - {{ display[key] }})</span>  
  35.                     </div>  
  36.                 </ng-template>  
  37.   
  38.                 <ng-template #headerTemplate>  
  39.                     <div class="header-class">This is Header</div>  
  40.                 </ng-template>  
  41.   
  42.                 <ng-template #footerTemplate>  
  43.                     <div class="footer-class">This is Footer</div>  
  44.                 </ng-template>  
  45.   
  46.                 <igx-combo>  
  47.                     <ng-template #emptyTemplate>  
  48.                         <span class="empty-class">No available states</span>  
  49.                     </ng-template>  
  50.                 </igx-combo>  
  51.   
  52.             </igx-combo>  
  53.         </div>  
  54.         <div class="col-sm-4">  
  55.             <span *ngFor="let s of StateObj">  
  56.                 StateId :  
  57.                 <b>{{s.stateId}}</b> , StateName :  
  58.                 <b> {{s.stateName}}</b>  
  59.                 <br>  
  60.             </span>  
  61.         </div>  
  62.     </div>  
  63. </div>  

Listing 12

Save the code and go back to the browser and you will see the header, footer and item text. See Figure 4.

 

Combobox In Angular Using Ignite UI
Figure 4

 

If you select Country which has no state then the empty template will be bound, See Figure 5.

 

Combobox In Angular Using Ignite UI
figure 5

 

Summary

IgCombo is based on JavaScript framework and is very easy to implement. It has built in visualization support and also provides a cascading scenario when user wants to select via drop down. It provides lots of input, output, and events according to our project needs.

Learn more, download a free trial, and get started here,