Accordion List in Ionic
In this awesome tutorial, we will build an expandable list in Ionic 3 framework. This tutorial is updated for Ionic 3.5.0.
Before you can continue to create this awesome component, make sure you know the basics. If you are new to Ionic framework I suggest, you go through our Getting started with Ionic tutorial.
1. Generate a New Ionic Application
We begin by generating a new blank Ionic application using Ionic CLI. Just start by running following command in your working directory.
ionic start ion-accordion-list blank
Once completed, make ion-expandable-list your working direcotry.
cd ion-accordion-list
While at terminal, let’s also generate a custom component for our accordion list:
ionic g component AccordionList
If you don’t understand the Ionic CLI commands, I suggest you view our Ionic CLI cheatsheet.
2. Building the Accordion List Component
What we are aiming to build is a component that will look like this:
<accordion-list [height]="itemHeight" [expanded]="item.expanded">
Other Components inside
</accordion-list>
We could then use this component to display an accordion list. We can pass in the desired height with the height option or auto height if the height is 0. The expanded state is togled using expanded input. So, let’s build the component
Let’s modify src/components/accordion-list/accordion-list.html as:
<div #wrapper class='expand-wrapper' [class.collapsed]="!expanded">
<ng-content></ng-content>
</div>
The template for the component is reasonably simple. We are using content projection with to project whatever we add inside of the tags into the component’s template. This means that we can display some content here inside of our component.
We also have a wrapper
<div> that has a template variable of wrapper so that we can access it later, and the collapsed class is being applied conditionally based on the value of expanded. This is how we will toggle the collapsed styling on and off.
Modify src/components/accordion-list/accordion-list.scss to reflect the following:
accordion-list {
.wrapper {
transition: 0.2s linear;
}
.collapsed {
height: 0 !important;
}
}
In the template, we were toggling the collapsed class on and off, and this is where we define that class. When the collapsed class is applied it will force the height of the wrapper to be 0 so it should disappear, and we also add a transition property so that the component will shrink or grow smoothly rather than just snapping in and out of existence.
Modify src/components/accordion-list/accordion-list.ts to reflect the following:
import { Component, Input, ViewChild, ElementRef, Renderer } from '@angular/core';
@Component({
selector: 'accordion-list',
templateUrl: 'accordion-list.html'
})
export class AccordionListComponent {
@ViewChild('wrapper', {read: ElementRef}) wrapper;
@Input('expanded') expanded;
@Input('height') height;
constructor(public renderer: Renderer) {
}
ngAfterViewInit(){
if(this.height){
this.renderer.setElementStyle(this.wrapper.nativeElement, 'height', this.height + 'px');
}
}}
Now we have the class for the component. This is also pretty simple — we set up the two inputs that we wanted, and we also grab a reference to the expandWrapper using the template variable we added earlier. We then use that reference to set the height of the component in the ngAfterViewInit function.
3. Use the Component to Create an Accordion List
The component is complete now, so all we need to do is use it. As I mentioned, we are going to use it to create an accordion list by adding it into a list. It’s mostly just a case of dropping it in there, however, we also need to add a bit of logic to close all other expanded components in the list when a new component is expanded (so that only one is open at a time).
Modify src/pages/home/home.html to reflect the following:
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<button (click)="expandItem(item)" ion-item *ngFor="let item of items">
<ion-thumbnail item-start>
<img src="http://placehold.it/100">
</ion-thumbnail>
<h2>My Neighbor Totoro</h2>
<p>Hayao Miyazaki • 1988</p>
<accordion-list [height]="itemHeight" [expanded]="item.expanded">
<ion-item>
<h2>Hello Everyone</h2>
</ion-item>
<ion-item>
<h2>Hello Everyone</h2>
</ion-item>
</accordion-list>
<button ion-button clear item-end>View</button>
</button>
</ion-list>
</ion-content>
We’ve just added a stock standard list to the template here, except that we’ve added an component inside of it. We bind theexpandedinput to the value of each particular itemsexpandedproperty (which will allow us to toggle them individually), and we also have a click handler that triggersexpandItem` which will allow us to toggle the items expanded state.
Modify src/pages/home/home.ts to reflect the following:
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
items: any = [];
itemHeight: number = 0;
constructor(public navCtrl: NavController) {
this.items = [
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false},
{expanded: false}
];
}
expandItem(item){
this.items.map((listItem) => {
if(item == listItem){
listItem.expanded = !listItem.expanded;
} else {
listItem.expanded = false;
}
return listItem;
});
}
}
We’ve set up an array of item objects here that only have a single expanded property. Of course, you would usually have other properties defined here as well like the title, body, and so on. The itemHeight when set to 0 will height the expandable component to cover all of its items, instead of all having the fixed height.
Our expandItem function maps each element in the array — when it gets to the item that has been clicked, it will toggle its state, and it will set any other expanded items back to the collapsed state.
Modify src/pages/home/home.scss to reflect the following:
page-home {
button {
align-items: baseline;
}
}
This just makes the list look less weird when the component is expanded by aligning the image and the view button to the top of the item. If you load the application up in your browser now and click around a bit, you should be able to view the accordion list
Inspired by Josh Morony Tutorials
Originally published at competenepal.com on July 12, 2017.