Ionic expandable list items

I’ve got a screen in my current project that displays a long list of user selectable workouts. All of them are named and many can be recognised by that name alone, however each workout has some information behind it that would be useful to know if you can’t remember the details. Rather than force my users off to a separate tab where the workouts are created, edited and displayed to see this extra information, I wanted to give them the option of viewing the details but without cluttering the small part of the view allocated to this list.

A generic square placeholder image with rounded corners in a figure.
Full height available to this list, not much space to show information

Since the user needs to tap a workout (WOD) to select it I decided to use a bit of progressive disclosure to teach the user that tapping a WOD will show them information. The form this is part of won’t submit until they select a WOD, this prompts them to tap a WOD to select it, at which point the WOD will both select and expand to reveal a summary of the workout so they know which one they are looking at. It doesn’t show them the full details, but enough information that they know they are selecting the right one.

A generic square placeholder image with rounded corners in a figure.
Reveals a little card with a workout summary and selects the WOD.

To hide the information they have to tap it again. Tapping another WOD will leave the firsts summary open even though it it deselected. I went back and forth on if only the selected WOD should show it’s details and decided that the user may want to open a few and scroll back and forth so it’s fully up to them if they want to leave the information displayed or not.

This is pretty simple to achieve in Ionic so let’s take a look at the code.

There are two components, the main page component that hosts the form and the WOD list and a component for the WOD summary.

I’ve stripped out the ordering and filtering pipes so we can see just what’s needed for this functionality. What’s going on above then?

  • ion-radio-group is for managing the WOD selection and the ion-radio is to show the tick when the WOD is selected.
  • ion-item has an event called (click) that we can bind to and call onWodClick(), a function in the component.
  • We use the template variable #wodSummary to grab a reference to the app-wod-summary and pass into the onWodClick(wodSummary) component method so that in the component we can change the state of the showSummary input variable.
  • app-wod-summary has two input variables [wod]="wod" [showSummary]="false" the summary will be hidden by default.

So the relevant component code for the list is very simple:

onWodClick(wodSummary) {
  wodSummary.showSummary = !wodSummary.showSummary;
}

The the app-wod-summary code is very simple:

export class WodSummaryComponent implements OnInit {
  @Input() wod: WOD;
  @Input() showSummary: boolean;
  constructor() { }
  ngOnInit() {}
}

We can see the input variables into which are passed the WOD and the current showSummary status.

The template code is:

The WOD name will always show and the summary will only show when we tap it.

And that’s it!

The key bit here is the template variable #wodSummary that allows us to change the showSummary state in the parent component and have that propagate immediately to the child component. While the code in the child component is laughably small, without encapsulating the WOD in a component it would be trickier to manage the showSummary state. One of the many benefits of using Angular components!