This is an example of a multi-level accordion menu with dynamic data using latest Ionic 3 and Angular 4.
1. Create New Ionic 3 and Angular 4 Side Menu App
We will start this tutorial by creating new Ionic 3 and Angular 4 app. This time we will use generated side menu app. Open and edit the terminal or Node.js command line then type this command.
ionic start ionic3-accordion-menu sidemenu --v2
That command will create new Ionic 3 app with the name 'ionic3-accordion-menu' using default template 'sidemenu'. Go to the newly created app folder.
cd ionic3-accordion-menu
Run the Ionic 3 app on the browser.
ionic serve -l
You should see this side menu.
![Ionic 3 and Angular 4 Multi Level Accordion Menu Example - Side Menu](https://s3-ap-southeast-1.amazonaws.com/djamblog/article-230417214048.png)
Right now, we will skip lazy loading pages configuration because we will focus only on the multilevel accordion menu. You can find more about lazy loading and Ionic 3 getting started here.
2. Create Nested Array of Objects
We have to create nested Array of objects which it's contains multilevel arrays. Create a new folder and JSON file in asset folder.
mkdir src/assets/data
touch src/assets/data/menus.json
Open and edit 'menus.json' then add this lines of data.
[
{
"category":"PC",
"subs": [
{
"subcategory":"Processor",
"manufactures": [
{
"manufacture":"Intel"
},
{
"manufacture":"AMD"
}
]
},
{
"subcategory":"Motherboard",
"manufactures": [
{
"manufacture":"Asus"
},
{
"manufacture":"AMD"
},
{
"manufacture":"GigaByte"
},
{
"manufacture":"Intel"
}
]
},
{
"subcategory":"Memory",
"manufactures": [
{
"manufacture":"Visipro"
},
{
"manufacture":"Crucial"
},
{
"manufacture":"VenomRX"
}
]
}
]
},
{
"category":"Laptop",
"subs": [
{
"subcategory":"Notebook",
"manufactures": [
{
"manufacture":"Lenovo"
},
{
"manufacture":"Dell"
}
]
},
{
"subcategory":"Netbook",
"manufactures": [
{
"manufacture":"Lenovo"
},
{
"manufacture":"Dell"
},
{
"manufacture":"Acer"
},
{
"manufacture":"HP"
}
]
}
]
},
{
"category":"Printer",
"subs": [
{
"subcategory":"Laserjet",
"manufactures": [
{
"manufacture":"HP"
},
{
"manufacture":"Brother"
},
{
"manufacture":"Canon"
},
{
"manufacture":"Samsung"
}
]
},
{
"subcategory":"Deskjet",
"manufactures": [
{
"manufacture":"HP"
},
{
"manufacture":"Canon"
},
{
"manufacture":"Epson"
}
]
}
]
}
]
3. Create and Call Service/Provider for Accessing Data
To access JSON data we have to create new service or provider to keep app modular. Type this command to create it.
ionic g provider DataService
Open and edit 'src/providers/data-service.ts' add 'Response' to 'Http' import.
import { Http, Response } from "@angular/http";
Create this function for call JSON data.
getMenus(){
return this.http.get('assets/data/menus.json')
.map((response:Response)=>response.json());
}
Register this service in 'app.module.ts' by open and edit 'src/app/app.module.ts' then add this import.
import { HttpModule } from '@angular/http';
import { DataService } from '../providers/data-service';
Add 'HttpModule' in '@NgModule' imports.
...
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
],
...
Add 'DataService' in '@NgModule' providers.
...
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler},
DataService
]
...
Because menu holds by component, we have to edit it to call data for the menu from service/provider. Open and edit 'src/app/app.component.ts' then add this import.
import { DataService } from '../providers/data-service';
Replace this line.
pages: Array<{title: string, component: any}>;
With this.
pages: any;
Now, inject 'DataService' in constructor parameter and add this function for calling JSON data inside of constructor.
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public dataService: DataService) {
this.initializeApp();
this.dataService.getMenus()
.subscribe((response)=> {
this.pages = response;
console.log(this.pages);
});
}
4. Create Multilevel Accordion Menu
Now, is the point. Creating multilevel Accordion Menu with Ionic 3 and Angular 4. Open and edit 'src/app/app.html' the add this lines of codes inside '<ion-content>'.
<ion-content>
<ion-list>
<ion-item *ngFor="let p of pages" text-wrap>
{{p.category}}
<ion-list>
<ion-item *ngFor="let s of p.subs" text-wrap>
{{s.subcategory}}
<ion-list>
<ion-item *ngFor="let m of s.manufactures" text-wrap>
{{m.manufacture}}
</ion-item>
</ion-list>
</ion-item>
</ion-list>
</ion-item>
</ion-list>
</ion-content>
After we re-run the Ionic 3 app, the menu should look like this.
![Ionic 3 and Angular 4 Multi Level Accordion Menu Example - Multi Level Menu](https://s3-ap-southeast-1.amazonaws.com/djamblog/article-240417171022.png)
As you can see, there is 3 level of the menu. For that, we have to make accordion to hide child menus. Open and edit 'src/app/app.component.ts' then declare this variable.
showLevel1 = null;
showLevel2 = null;
Create new functions for toggle show/hide level 2 and level 3 of the menu.
toggleLevel1(idx) {
if (this.isLevel1Shown(idx)) {
this.showLevel1 = null;
} else {
this.showLevel1 = idx;
}
};
toggleLevel2(idx) {
if (this.isLevel2Shown(idx)) {
this.showLevel1 = null;
this.showLevel2 = null;
} else {
this.showLevel1 = idx;
this.showLevel2 = idx;
}
};
Also, create the function for check if level 2 and 3 is shown or hidden.
isLevel1Shown(idx) {
return this.showLevel1 === idx;
};
isLevel2Shown(idx) {
return this.showLevel2 === idx;
};
Now, open and edit 'src/app/app.html' then replace all list with this list.
<ion-content>
<ion-list>
<ion-item *ngFor="let p of pages; let i=index" text-wrap (click)="toggleLevel1('idx'+i)" [ngClass]="{active: isLevel1Shown('idx'+i)}">
<h4>
{{p.category}}
<ion-icon color="success" item-right [name]="isLevel1Shown('idx'+i) ? 'arrow-dropdown' : 'arrow-dropright'"></ion-icon>
</h4>
<ion-list *ngIf="isLevel1Shown('idx'+i)">
<ion-item *ngFor="let s of p.subs; let i2=index" text-wrap (click)="toggleLevel2('idx'+i+'idx'+i2)" [ngClass]="{active: isLevel2Shown('idx'+i+'idx'+i2)}">
<h4>
{{s.subcategory}}
<ion-icon color="success" item-right [name]="isLevel2Shown('idx'+i+'idx'+i2) ? 'arrow-dropdown' : 'arrow-dropright'"></ion-icon>
</h4>
<ion-list *ngIf="isLevel2Shown('idx'+i+'idx'+i2)">
<ion-item *ngFor="let m of s.manufactures" text-wrap>
{{m.manufacture}}
</ion-item>
</ion-list>
</ion-item>
</ion-list>
</ion-item>
</ion-list>
</ion-content>
Then re-run the Ionic 3 app and see the results in the browser.
![Ionic 3 and Angular 4 Multi Level Accordion Menu Example - Multi Level Accordion Menu](https://s3-ap-southeast-1.amazonaws.com/djamblog/article-240417194850.png)
please make dynamic accordian in ionic 3. i have multi level json containing childs subchilds grandchild. in future it make have more too. how can i handle
ReplyDelete