Expansion Panel In Angular Using Ignite-ui-angular

Ignite-UI’s Angular expansion panel, IgxExpansionPanel, is very useful in situations when we need to show lots of things and we have limited space in a web application, especially in mobile-based applications because mobiles have comparatively small screens to render controls.

The IgxExpansionPanel is a lightweight component which can be rendered in two states - collapsed or expanded. When collapsed, the panel displays a short summary of its contents. The collapsed panel can be toggled using mouse click or keyboard interactions to display the body completely, containing any additional necessary content.

Ignite UI Angular provides an expansion panel which is user-friendly and responsive so that it can adjust to the screen layout accordingly.

What we will cover in this article?

  1. Installation of Ignite UI for Angular
  2. Creating an Angular Project with Ignite UI
  3. Importing the IgxExpansionPanelModule
  4. Adding the igx-expansion-panel-page component
  5. Adding the igx-expansion-panel
  6. Binding property and events
  7. Styling the header
  8. Conclusion

Installing Ignite UI for Angular

You should have node and npm installed on your machine. If you are new to npm, check out the npm documentation here, otherwise open the command prompt and run

“npm install -g igniteui-cli”

Create an Angular project with Ignite UI

To create a new project, run the below command.

“ng new expansion-panel-angular-demo”

To get into the project, use this command.

“cdexpansion-panel-angular-demo”

Now, it’s time to install the Ignite UI for this project. Run the following command.

“npm install igniteui-angular”

Let’s add the required Ignite UI styles and the “HammerJs” library to the angular-cli.json file.

Open the “angular.json” file and add the code snippet as shown in Listing 1.

  1. "styles": ["../node_modules/igniteui-angular/styles/igniteui-angular.css"]  
  2. "scripts": ["../node_modules/hammerjs/hammer.min.js"]  

Listing 1.

Now, we have configured Ignite UI with our Angular project successfully.

Adding Material Icons

  1. /* style.css */  
  2. @import url('https://fonts.googleapis.com/icon?family=Material+Icons');  

Listing 2.

Run the following command on command prompt to execute the Angular application.

ng serve --open

The application will run using the following address and port - “http://localhost:4200”

Import the IgxExpansionPanelModule

Open the “app.module.ts” file and import the IgxDatePickerModule in the import section of @NgModule.

  1. import {  
  2.     IgxExpansionPanelModule  
  3. } from 'igniteui-angular';  
  4. @NgModule({  
  5.     imports: [  
  6.         IgxExpansionPanelModule  
  7.     ],  
  8.     providers: [],  
  9.     bootstrap: [AppComponent]  
  10. })  
  11. export class AppModule {}  

Listing 3.

Add the igx-expansion-panel-page component

Let’s add a new component named igx-expansion-panel-page. To do that, run the below command on command prompt.

ng generate component components/igx-expansion-panel-pag

Expansion Panel in Angular using Ignite-ui-angular 
Figure 1.

Now, add the <app-date-picker-page></app-date-picker-page> tag in app.component.html file.

Adding the <igx-expansion-panel>

Let’s add the <igx-expansion-panel> directive in “date-picker-page.component.html” page, as showing in listing 4.

  1. <igx-expansion-panel>  
  2.     <igx-expansion-panel-header>  
  3.         <igx-expansion-panel-title> Avengers: Endgame </igx-expansion-panel-title>  
  4.         <igx-expansion-panel-description> Avengers: Endgame is an upcoming American superhero film. </igx-expansion-panel-description>  
  5.     </igx-expansion-panel-header>  
  6.     <igx-expansion-panel-body>  
  7.         <p>The film was announced in October 2014 as Avengers Infinity War Part 2. The Russo brothers came on board to direct in April 2015, and by May, Markus and McFeely signed on to script the film. In July 2016, Marvel removed the films title, referring to it simply as Untitled Avengers film. Filming began in August 2017 at Pinewood Atlanta Studios in Fayette County, Georgia, shooting back-to-back with Avengers Infinity War, and ended in January 2018. Additional filming took place in the Downtown and Metro Atlanta areas. The title, Avengers Endgame, was officially revealed in December 2018.</p>  
  8.     </igx-expansion-panel-body>  
  9. </igx-expansion-panel>  

Listing 4.

Add the following CSS in “expansion-panel-page.component.css” under the components directory.

  1. .igx - expansion - panel {  
  2.     font - family: Verdana;  
  3.     margin: 24 px;  
  4.     width: 420 px;  
  5.     box - shadow: 0 1 px 5 px 0 rgba(0, 0, 0, .26), 0 2 px 2 px 0 rgba(0, 0, 0, .12), 0 3 px 1 px - 2 px rgba(0, 0, 0, .08);  
  6. }.igx - expansion - panel__header--expanded {  
  7.     border - bottom: 1 px dashed rgba(0, 0, 0, .74);  
  8. }.igx - expansion - panel__body > * {  
  9.     padding: 8 px 16 px;  
  10.  

Listing 5.

Now, run the application using “ng server --open” command.

Expansion Panel in Angular using Ignite-ui-angular 
Figure 2.

Binding Property and Events

Let’s see how to bind properties in the expansion panel. In the “expansion-panel-page.component.ts”, add the following code.

  1. import {  
  2.     Component,  
  3.     ViewChild  
  4. } from '@angular/core';  
  5. import {  
  6.     IgxExpansionPanelComponent  
  7. } from 'igniteui-angular';  
  8. @Component({  
  9.     selector: 'app-expansion-panel-page',  
  10.     templateUrl: './expansion-panel-page.component.html',  
  11.     styleUrls: ['./expansion-panel-page.component.css']  
  12. })  
  13. export class ExpansionPanelPageComponent {  
  14.     @ViewChild(IgxExpansionPanelComponent, {  
  15.         read: IgxExpansionPanelComponent  
  16.     })  
  17.     public panel: IgxExpansionPanelComponent;  
  18.     public readMore: string;  
  19.     constructor() {  
  20.         this.readMore = 'https://en.wikipedia.org/wiki/Avengers:_Endgame';  
  21.     }  
  22. }  

Listing 6.

In the “expansion-panel-page.component.html”, add these lines.

  1. <igx-expansion-panel-body>  
  2.     <p>The film was announced in October 2014 as Avengers Infinity War Part 2. . . . </p>  
  3.     <a [href]="readMore" target="_blank">Read more</a>  
  4. </igx-expansion-panel-body>  

Listing 7.

To bind the events

To bind the event, add two events in “ExpansionPanelPageComponent ” page - one is for expansion and the other one is for collapse, as shown in Listing 8.

  1. export class ExpansionPanelPageComponent {  
  2.     public handleExpansion(evt ? : {  
  3.         event: Event  
  4.     }) {  
  5.         alert('Expanded Event Fired!');  
  6.     }  
  7.     public handleCollapse(evt ? : {  
  8.         event: Event  
  9.     }) {  
  10.         alert('Collapsed Event Fired!');  
  11.     }  
  12. }  

Listing 8.

Now, bind the above events in HTML for onExpanded and onCollapsed events.

  1. <igx-expansion-panel (onExpanded)="handleExpansion($event)" (onCollapsed)="handleCollapse($event)">  
  2. </igx-expansion-panel> 

Listing 9.

Styling the Header

We can also set the styling in the header of the expansion panel. We can either set it on the left position or the right position.

Set header in the left position

  1. <igx-expansion-panel-header [iconPosition]="'left'">  

Expansion Panel in Angular using Ignite-ui-angular
Figure 3.

 Set header in the right position

  1. <igx-expansion-panel-header [iconPosition]="right">  

Expansion Panel in Angular using Ignite-ui-angular
Figure 4.
  1. <igx-expansion-panel-header [iconPosition]="'left'">  
  2.     <igx-expansion-panel-title> Avengers: Endgame </igx-expansion-panel-title>  
  3.     <igx-expansion-panel-description *ngIf="panel.collapsed"> Avengers: Endgame is an upcoming American superhero film. </igx-expansion-panel-description>  
  4.     <igx-expansion-panel-icon>  
  5.         <span class="example-icon" *ngIf="panel.collapsed">Show more</span>  
  6.         <span class="example-icon" *ngIf="!panel.collapsed">Collapse</span>  
  7.     </igx-expansion-panel-icon>  
  8. </igx-expansion-panel-header>  

Listing 10.

Add the following CSS code to the “expansion-panel-page.component.css” file for proper positions.

  1. .example - icon {  
  2.         font - size: 12 px;  
  3.         font - weight: 600;  
  4.         text - shadow: 1 px #000;  
  5.   
  6. }  

Listing 11.

Creating a registration page using expansion panel

Let’s create a registration page using the expansion panel. This UI will have 3 panels.

  1. Personal Information
  2. Billing Address
  3. Shipping Address

Add the three expansion panels.

The first one is for personal information that will have the control for full name, phone number, and email; the second expansion panel will have controls for billing address; and the last one is for shipping address.
  1. <div class="sample-wrapper" style="margin-left:25px">  
  2.     <div class="content">  
  3.         <igx-expansion-panel class="content__collapsible">  
  4.             <igx-expansion-panel-header (onInteraction)="onInteraction($event)" [disabled]="false">  
  5.                 <igx-expansion-panel-title class="sample-title">Personal Information</igx-expansion-panel-title>  
  6.                 <igx-expansion-panel-icon>  
  7.                     <igx-icon fontSet="material">{{collapsed(0) ? 'expand_more':'expand_less'}}</igx-icon>  
  8.                 </igx-expansion-panel-icon>  
  9.             </igx-expansion-panel-header>  
  10.             <igx-expansion-panel-body class="body">  
  11.                 <igx-input-group class="group">  
  12.                     <input igxInput name="fullName" type="text" [(ngModel)]="user.fullName" />  
  13.                     <label igxLabel for="fullName">Full Name</label>  
  14.                     <igx-suffix>  
  15.                         <igx-icon>person</igx-icon>  
  16.                     </igx-suffix>  
  17.                 </igx-input-group>  
  18.                 <igx-input-group class="group">  
  19.                     <igx-prefix>+359</igx-prefix>  
  20.                     <label igxLabel for="phone">Phone</label>  
  21.                     <input igxInput name="phone" type="text" [(ngModel)]="user.phone" />  
  22.                     <igx-suffix>  
  23.                         <igx-icon>phone</igx-icon>  
  24.                     </igx-suffix>  
  25.                     <igx-hint position="start">Ex.: +359 555 123 456</igx-hint>  
  26.                 </igx-input-group>  
  27.                 <igx-input-group class="group">  
  28.                     <label igxLabel for="email">Email address</label>  
  29.                     <input igxInput name="email" type="email" [(ngModel)]="user.email" />  
  30.                     <igx-suffix>  
  31.                         <igx-icon>email</igx-icon>  
  32.                     </igx-suffix>  
  33.                 </igx-input-group>  
  34.             </igx-expansion-panel-body>  
  35.         </igx-expansion-panel>  
  36.         <igx-expansion-panel class="content__collapsible">  
  37.             <igx-expansion-panel-header (onInteraction)="onInteraction($event)" [disabled]="false">  
  38.                 <igx-expansion-panel-title class="sample-title">Billing Address</igx-expansion-panel-title>  
  39.                 <igx-expansion-panel-icon>  
  40.                     <igx-icon fontSet="material">{{collapsed(1) ? 'expand_more':'expand_less'}}</igx-icon>  
  41.                 </igx-expansion-panel-icon>  
  42.             </igx-expansion-panel-header>  
  43.             <igx-expansion-panel-body class="body">  
  44.                 <igx-input-group class="group">  
  45.                     <input igxInput name="address" type="text" [(ngModel)]="shippingAddress.address" />  
  46.                     <label igxLabel for="address">Billing Address:</label>  
  47.                     <igx-suffix>  
  48.                         <igx-icon>add_location</igx-icon>  
  49.                     </igx-suffix>  
  50.                 </igx-input-group>  
  51.                 <igx-input-group class="group">  
  52.                     <label igxLabel for="city">City:</label>  
  53.                     <input igxInput name="city" type="text" [(ngModel)]="shippingAddress.city" />  
  54.                     <igx-suffix>  
  55.                         <igx-icon>location_city</igx-icon>  
  56.                     </igx-suffix>  
  57.                 </igx-input-group>  
  58.                 <igx-input-group class="group">  
  59.                     <label igxLabel for="state">State:</label>  
  60.                     <input igxInput name="state" type="text" [(ngModel)]="shippingAddress.state" />  
  61.                     <igx-suffix>  
  62.                         <igx-icon>terrain</igx-icon>  
  63.                     </igx-suffix>  
  64.                 </igx-input-group>  
  65.                 <igx-input-group class="group">  
  66.                     <label igxLabel for="zipCode">Zip Code:</label>  
  67.                     <input igxInput name="zipCode" type="text" [(ngModel)]="shippingAddress.zipCode">  
  68.                     <igx-suffix>  
  69.                         <igx-icon>mail_outline</igx-icon>  
  70.                     </igx-suffix>  
  71.                 </igx-input-group>  
  72.             </igx-expansion-panel-body>  
  73.         </igx-expansion-panel>  
  74.         <igx-expansion-panel class="content__collapsible">  
  75.             <igx-expansion-panel-header (onInteraction)="onInteraction($event)" [disabled]="false">  
  76.                 <igx-expansion-panel-title class="sample-title">Shipping Address</igx-expansion-panel-title>  
  77.                 <igx-expansion-panel-icon>  
  78.                     <igx-icon fontSet="material">{{collapsed(2) ? 'expand_more':'expand_less'}}</igx-icon>  
  79.                 </igx-expansion-panel-icon>  
  80.             </igx-expansion-panel-header>  
  81.             <igx-expansion-panel-body class="body">  
  82.                 <igx-input-group class="group">  
  83.                     <input igxInput name="address" type="text" [(ngModel)]="billingAddress.address" />  
  84.                     <label igxLabel for="address">Shipping Address:</label>  
  85.                     <igx-suffix>  
  86.                         <igx-icon>add_location</igx-icon>  
  87.                     </igx-suffix>  
  88.                 </igx-input-group>  
  89.                 <igx-input-group class="group">  
  90.                     <label igxLabel for="city">City:</label>  
  91.                     <input igxInput name="city" type="text" [(ngModel)]="billingAddress.city" />  
  92.                     <igx-suffix>  
  93.                         <igx-icon>location_city</igx-icon>  
  94.                     </igx-suffix>  
  95.                 </igx-input-group>  
  96.                 <igx-input-group class="group">  
  97.                     <label igxLabel for="state">State:</label>  
  98.                     <input igxInput name="state" type="text" [(ngModel)]="billingAddress.state" />  
  99.                     <igx-suffix>  
  100.                         <igx-icon>terrain</igx-icon>  
  101.                     </igx-suffix>  
  102.                 </igx-input-group>  
  103.                 <igx-input-group class="group">  
  104.                     <label igxLabel for="zipCode">Zip Code:</label>  
  105.                     <input igxInput name="zipCode" type="text" [(ngModel)]="billingAddress.zipCode">  
  106.                     <igx-suffix>  
  107.                         <igx-icon>mail_outline</igx-icon>  
  108.                     </igx-suffix>  
  109.                 </igx-input-group>  
  110.             </igx-expansion-panel-body>  
  111.         </igx-expansion-panel>  
  112.     </div>  
  113. </div>  

Listing 12.

  1. import {  
  2.     Component,  
  3.     ViewChildren,  
  4.     QueryList  
  5. } from '@angular/core';  
  6. import {  
  7.     IgxExpansionPanelComponent,  
  8.     IExpansionPanelEventArgs,  
  9. } from 'igniteui-angular';  
  10. import {  
  11.     useAnimation  
  12. } from '@angular/animations';  
  13. @Component({  
  14.     selector: 'app-expansion-panel-registration',  
  15.     templateUrl: './expansion-panel-registration.component.html',  
  16.     styleUrls: ['./expansion-panel-registration.component.css']  
  17. })  
  18. export class ExpansionPanelRegistrationComponent {  
  19.     @ViewChildren(IgxExpansionPanelComponent)  
  20.     public accordion: QueryList < IgxExpansionPanelComponent > ;  
  21.     public user = {  
  22.         email: '',  
  23.         fullName: '',  
  24.         phone: ''  
  25.     };  
  26.     public billingAddress = {  
  27.         address: '',  
  28.         city: '',  
  29.         state: '',  
  30.         zipCode: ''  
  31.     };  
  32.     public shippingAddress = {  
  33.         address: '',  
  34.         city: '',  
  35.         state: '',  
  36.         zipCode: ''  
  37.     };  
  38.     public collapsed(index: number) {  
  39.         if (!this.accordion) {  
  40.             return true;  
  41.         }  
  42.         return this.accordion.toArray()[index] && this.accordion.toArray()[index].collapsed;  
  43.     }  
  44.     public onInteraction(event: IExpansionPanelEventArgs) {  
  45.         const expandedPanels = this.accordion.filter((panel) => !panel.collapsed);  
  46.         expandedPanels.forEach((expandedPanel) => {  
  47.             if (expandedPanel.id !== event.panel.id) {  
  48.                 expandedPanel.collapse();  
  49.             }  
  50.         });  
  51.     }  
  52. }  

Listing 13.

Expansion Panel in Angular using Ignite-ui-angular 
Figure 5.
 
Expansion Panel in Angular using Ignite-ui-angular 
Figure 6.
 
Expansion Panel in Angular using Ignite-ui-angular 
Figure 7.

Conclusion

Expansion panel (IgxExpansionPanelModule) is a light-weight component that provides two features - expand and collapse. It helps the web developers to achieve a functionality in which a user needs to show some content on the control expansion and later, it can be hidden to render other controls. 

To learn more, download a free trial and get started here.