Create Multilevel Accordion Menu in Ionic 5 Angular App

Last updated on by Digamber

Ionic 5 Angular multilevel accordion menu tutorial; In this tutorial, we will learn how to create a multilevel sidebar accordion menu UI component to navigate between various pages in the Ionic Angular application effortlessly.

A multi-level accordion menu is very useful in dealing with vast navigation items; we often see an accordion menu in eCommerce sites. Ideally, eCommerce platforms have many products, so they use accordion menu items to make the navigation process facile.

Accordion is a GUI component that encompasses vertically stacked nav list items; this is also known as a collapsible menu. It is a vertical list that deflates down to expandable menu titles when illustrated on small devices.

Ionic 5 Angular Multilevel Accordion Menu Example

  • Step 1: Getting Started
  • Step 2: Generate Pages for Multilevel Accordion
  • Step 3: Create Accordion Menu Data
  • Step 4: Create Service for Sidebar Collapsible menu
  • Step 5: Build Multilevel Accordion Navigation in Ionic
  • Step 6: Run App with Ionic Lab

Getting Started

To get started with Ionic app development, do ensure to update or install the latest version of Ionic CLI:

npm install -g @ionic/cli

You are ready to install a blank new Ionic Angular app:

ionic start multilevel-accordion-demo sidemenu --type=angular

Make sure to get inside the app root:

cd multilevel-accordion-demo

Generate Pages for Multilevel Accordion

To add multiple menu items in multilevel accordion, we need multiple pages for that we may execute the recommended command to generate the pages in ionic.

ionic g page menu01
ionic g page menu02
ionic g page menu03
ionic g page menu04
ionic g page menu05
ionic g page menu06
ionic g page menu07
ionic g page menu08
ionic g page menu09
ionic g page menu10
ionic g page menu11
ionic g page menu12
ionic g page menu13
ionic g page menu14
ionic g page menu15

Create Accordion Menu Data

The accordion menu in ionic angular requires navigation menu items that contain menu item name and url. Still, the most important thing is to arrange in the conventional hierarchy. For that, we create a nested array that will manage the data for angular collapsable menu items.

Head over to the assets folder and create the multi-accordion.json file, thereafter update the suggested code in the assets/multi-accordion.json file:

[{
    "name": "Menu 1",
    "nav": [{
        "name": "nav-1-1",
        "nav": [{
            "name": "nav-1-1-1",
            "nav": [{
                "name": "nav-1-1-1-1",
                "url": "/menu01"
              },
              {
                "name": "nav-1-1-1-2",
                "url": "/menu02"
              }
            ]
          },
          {
            "name": "nav-1-1-2",
            "nav": [{
                "name": "nav-1-1-2-1",
                "url": "/menu03"
              },
              {
                "name": "nav-1-1-2-2",
                "url": "/menu04"
              }
            ]
          }
        ]
      },
      {
        "name": "nav-1-2",
        "nav": [{
            "name": "nav-1-2-1",
            "nav": [{
                "name": "nav-1-2-1-1",
                "url": "/menu05"
              },
              {
                "name": "nav-1-2-1-2",
                "url": "/menu06"
              }
            ]
          },
          {
            "name": "nav-1-2-2",
            "nav": [{
                "name": "nav-1-2-2-1",
                "url": "/menu07"
              },
              {
                "name": "nav-1-2-2-2",
                "url": "/menu08"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "name": "Menu 2",
    "nav": [{
        "name": "nav-2-1",
        "nav": [{
            "name": "nav-2-1-1",
            "nav": [{
                "name": "nav-2-1-1-1",
                "url": "/menu09"
              },
              {
                "name": "nav-2-1-1-2",
                "url": "/menu10"
              }
            ]
          },
          {
            "name": "nav-2-1-2",
            "nav": [{
                "name": "nav-2-1-2-1",
                "url": "/menu11"
              },
              {
                "name": "nav-2-1-2-2",
                "url": "/menu12"
              }
            ]
          }
        ]
      },
      {
        "name": "nav-2-2",
        "nav": [{
            "name": "nav-2-2-1",
            "nav": [{
                "name": "nav-2-2-1-1",
                "url": "/menu13"
              },
              {
                "name": "nav-2-2-1-2",
                "url": "/menu14"
              }
            ]
          }
        ]
      }
    ]
  }
]

Create Service for Sidebar Collapsible menu

Next, we generate a separate service file, which helps us handle the HTTP Get request and fetch the accordion menu items from the nested array json file.

ionic g service multilevel

In order to deal with HTTP requests, make sure to import and insert HttpClientModule in imports array within the app.module.ts file:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

// import module
import { HttpClientModule } from '@angular/common/http';


@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule, 
    IonicModule.forRoot(), 
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
  bootstrap: [AppComponent],
})

export class AppModule {}

Afterward, open and place the code in app/multilevel.service.ts file:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})

export class MultilevelService {

  path = 'assets/multi-accordion.json';

  constructor(private httpClient: HttpClient) { }

  fetchMenuItems() {
    return this.httpClient.get(this.path);
  }

}

Build Multilevel Accordion Navigation in Ionic

The MultilevelService has to be added on top, and this will be responsible for getting accordion nested items, so inject them into the constructor method. The navPages array will hold the accordion menu items.

Head over to app.component.ts and place the below code:

import { Component } from '@angular/core';
import { MultilevelService } from './multilevel.service';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})

export class AppComponent {

  menuLevel1 = null;
  menuLevel2 = null;
  menuLevel3 = null;

  public navPages: any  = [ ];

  constructor( private multilevelService: MultilevelService ) {
    this.multilevelService.fetchMenuItems().subscribe((data) => {
      this.navPages = data;
    });
  }

  levelNav1(navX: string) {
    if (this.isNav1Displayed(navX)) {
      this.menuLevel1 = null;
    } else {
      this.menuLevel1 = navX;
    }
  }

  isNav1Displayed(navX: string) {
    return this.menuLevel1 === navX;
  }

  levelNav2(navX: string) {
    if (this.isNav2Displayed(navX)) {
      this.menuLevel2 = null;
    } else {
      this.menuLevel1 = navX;
      this.menuLevel2 = navX;
    }
  }

  isNav2Displayed(navX: string) {
    return this.menuLevel2 === navX;
  }

  levelNav3(navX: string) {
    if (this.isNav3Displayed(navX)) {
      this.menuLevel3 = null;
    } else {
      this.menuLevel2 = navX;
      this.menuLevel3 = navX;
    }
  }

  isNav3Displayed(navX: string) {
    return this.menuLevel3 === navX;
  }

  clearAccordionNav() {
    this.menuLevel1 = null;
    this.menuLevel2 = null;
    this.menuLevel3 = null;
  }

}

Use the ngFor directive to run the iterator to display the nested menu items, so replace the current code with the following code from the Ionic template.

Add following code in app.component.html:

<ion-app>
  <ion-split-pane contentId="main-content">
    <ion-menu contentId="main-content" type="overlay">
      <ion-content>
        <ion-list lines="full">

          <ion-menu-toggle auto-hide="false" class="first-menu"></ion-menu-toggle>

          <ion-item *ngFor="let p of navPages; let i=index;" [routerDirection]="'root'" (click)="levelNav1('navX'+i)" [ngClass]="{active: isNav1Displayed('navX'+i)}">
            <ion-label>
              <ion-icon [name]="isNav1Displayed('navX'+i) ? 'chevron-down-outline' : 'chevron-forward-outline'" slot="end"></ion-icon>
              {{p.name}}
              <ul *ngIf="isNav1Displayed('navX'+i)" class="nav1">
                <li *ngFor="let i1 of p.nav; let j=index;" (click)="levelNav2('navX'+i+'navX'+j)" [ngClass]="{active: isNav2Displayed('navX'+i+'navX'+j)}">
                    <ion-icon [name]="isNav2Displayed('navX'+i+'navX'+j) ? 'chevron-down-outline' : 'chevron-forward-outline'" slot="end"></ion-icon>
                  {{i1.name}}
                  <ul *ngIf="isNav2Displayed('navX'+i+'navX'+j)" class="nav2">
                    <li *ngFor="let i2 of i1.nav; let k=index;" (click)="levelNav3('navX'+i+'navX'+j+'navX'+k)" [ngClass]="{active: isNav3Displayed('navX'+i+'navX'+j+'navX'+k)}">
                      <ion-icon [name]="isNav3Displayed('navX'+i+'navX'+j+'navX'+k) ? 'chevron-down-outline' : 'chevron-forward-outline'" slot="end"></ion-icon>
                      {{i2.name}}
                      <ul *ngIf="isNav3Displayed('navX'+i+'navX'+j+'navX'+k)" class="nav3">
                        <li *ngFor="let i3 of i2.nav; let l=index;" [routerLink]="[i3.url]">
                          <ion-menu-toggle auto-hide="false" class="first-menu">{{i3.name}}</ion-menu-toggle>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </ion-label>
          </ion-item>
        </ion-list>
      </ion-content>    
    </ion-menu>
    <ion-router-outlet id="main-content"></ion-router-outlet>
  </ion-split-pane>
</ion-app>

Finally, add the CSS to style the accordion navigation, hence insert the code in app.component.scss file:

.nav1, 
.nav2, 
.nav3 {
  list-style: none;
  padding: 10px;
  li {
      padding: 10px 0 10px 10px;
      border-top: solid 1px #ccc;
  }
}

Run App with Ionic Lab

We may test our app; hence we need to install the Ionic lab package. It makes the ionic application’s testing facile by opening the app on various screen sizes and platform types.

Execute command to commence the installation:

npm i @ionic/lab --save-dev

Next, execute the serve command to start the app on the browser:

ionic serve -l

Angular Multilevel Accordion

Conclusion

The Ionic 5 Accordion menu tutorial is done for now; in this tutorial, we step by step explained how to create a multilevel sidebar accordion navigation component profoundly. Additionally, we described how to make HTTP Get request to fetch data for the collapsible sidebar menu in the Ionic Angular app.