Widget Breakdown: Accordion
Newer coders often see a complex feature, and get stopped with a feeling that they don't know where to start coding, and are therefore blocked in work on larger peices of work. I'd like to combat that by stepping through breaking down a common UI widget. My hope is that by going through this examples, this can help build confidence is jumping into complex features.
So let us look at the accordion. You've seen it on many sites - a categorized view of pages or infomation, where you click the category, and it slides open to reveal everything under that category.
New coders might look at this and quickly run to existing widgets, because plenty of them exist. And they work. And if you choose to use one because it is what you need, great. But you should always evaluate the effort to build it yourself. In general, it is unwise to spend half a day integrating someone else's widget when you could do it yourself in 2 hours.
So what does it take to build an accordion? First, look at what an accordion is. When I described it above, I laid out the core requirements:
- List of categories
- List of data organized by each category.
- Display of categories.
- Display of data within each category.
- Click handler to open/close each category.
So let us look at each one of those, and break down exactly what they are:
List of categories
We're just looking at the list itself, not how it show up on-screen. So questions to ask might include "Where does the data come from?", "How do I choose to sort the categories?", "Can new cateogries appear after the app is already loaded?". You also need to know the data format for the category data.
List of data organized by each category.
The questions for the data are going to be similar to the questions for the categories, but with some added nuances: Do you want to receive all the data for all categories when the app loads, or do you want smaller chunks, requesting the data as needed? Is there a single piece of data to display, or do you need to select a specific piece of the data to show in the accordion?
You'll see that there are more questions than answers when looking at the data. That is completely normal - asking questions about what you are doing often drives understanding of the final product. It forces the team to talk about the work and make decisions, which will guide you when you really start coding. Possibly more importantly, those decisions will tell you whether any 3rd party accordion widgets actually work for your needs. It is hard to say whether building your own is better or worse if you don't know what you are building.
For the sake of this breakdown, lets assume we get the following answers, which are simple, but will let us continue the exercise:
We are receiving all the data at once, from a REST API, in JSON format, an array of categories, and an array of text strings inside each category. The text strings will be long, so we will truncate them at 100 characters. The categories and phrases will be sorted alphabetically, Nothing happens when you click a data item inside a category. No new cateogires or data will come into the app after it is loaded.
Now, knowing what we are working with, we can break down the pieces of the UI widget we need to build:
Display of Categories
We have the list of categories, so we need to now display it as an accordion. So we need to:
- Sort the categories, alphabetically.
- Convert each category to an on-screen element.
- Place the category text within that element.
- Give a visual cue whether that element is open or closed.
- Give a visual cue that the open/closed status can be changed.
- Hold a state variable that tells us whether the category is open or not.
Display of data within each category
Again, we know the data comes in via JSON, under its category, so we need to:
- Sort the data points, alphabetically
- Convert each data point to an on-screen element, showing the 1st 100 characters of each item
- Place them all into a single container that can be hidden/shown.
- Choose whether or not to show the container based on the state variable from the category.
Click handler to open/close each category.
When you click a category, we need to work with the above elements to make each container of data and category respons as desired:
- Change the state variable of the clicked category. Turn it on if it was off, and vice versa.
- Show/hide the data container based on the new state variable.
- Update the visual cues on the category based on the new state variable.
- Possibly animate the open/close of containers, based on the new state variable.
Pause for a moment and look at this list. Although 4 things happen when you click a category, 3 of them are based on the state variable of the category, and the 4th is just toggling a value from true to false. To the end user, this feels like the most important piece of the accordion, but to the coders this is simple. This is why breaking things down is so important - what might look complex at the beginning is simple, while what looks simple may be complex.
While we now know what we need to code, there is always a layer of code that I refer to as the "Glue" - how to we pull these pieces together into a single widget? In other words, we're done breaking the widget down, but what pieces are needed to build it back together?
In this case, as we know that the key piece of data to drive the accordion is the state variable, we want everything else to just follow that variable. So we need to decide in what order the tasks above need to be done.
One possible solution would be to:
- Sort the array of categories, and its data.
- Iterate through the array, creating the on-screen elements for each category and its data. Hide/show the data based on whether the category is clsoed, with all categories are intiially set to be closed.
- Create the click handler.
- Set the click handler to re-run step 2 after a value is changed.
The majority of your coding will be in step 2. You also can break it down more efficiently by writing a function that will re-render only the changed category. But those are the 4 steps that need to happen, and as a coder you have the flexibility and responsibility to make it happen in the way that both meets your needs and performs well. My goal here isn't to tell you those answers, it is just to get you to the point that you know the pieces of the puzzle.
I leave design until the end because talking about UX it isn't the goal of this article. But there are design questions that came up even as we broke down the pieces. Do all categories start as closed? Do we close one when we open another? Is loading all the data at once the right answer, or does this data change often enough to pull it from the server each time you act on a category? These types of questions, that impact the experience of working with the widget are often decided as a team.
The look and feel of widgets is also a separate topic. In short, you do need to design how the widget looks. And we could go through an exercise doing exacly that - what colors and fonts are correct? How much padding should exist around each piece of text? Are you using any icons? There are probably as many questions to ask in the design as there were for coding the functionality.
Now that you have read through this article you'll notice that I never actually got into how to build an accordion. But you do know the pieces of such a task. And you might notice that half of the pieces, and all of the decisions and design chocies still need to be made whether you write your own accordion or use a 3rd party. But having gone through this breakdown, you can be confident in either choice - either finding an existing accordion the matches your needs, or coding one up from scratch, knowing that you have thought through the details.
Exercises like this are much of the data-to-day activity of a professional coder. You are handed a feature to code, and you think it through, ask the questions, and design your approach to solving a problem with code.