How to create a dynamic, hierarchical accordion with .NET
Recently I was working with a client who wanted to display a product catalog with an accordion. I have worked with accordions on several other projects in the past so I said “No problem!”. Once I got to work I noticed that there was a big difference between the accordions I had worked with before and this beast…this one was going to be dynamic. Worse yet…each level of the accordion depended on the one above it (known as hierarchical data). Yuck.
Early on I was still optimistic about the whole thing, but as the hours rolled on and my solution still didn’t work, I began to get frustrated. What started as a tale of woe ends on a happy note because I did get it all working. In order to spare you the pain I will explain how I got it working with a pretty easy solution.
Wrong Turn
So I started this project the way I start most of my accordions. I selected the trusty Stickman Scriptaculous Accordion. I have used this thing many times. Its easy, it works, and it is flexible.
I initially loaded this up just like I did the one on the novella site (cheap plug). I figured I would build the HTML markup on the server side with the data from my database. I got the first level (categories) done without much problem. Once that was up it was time to get level 2 going (subcategories). Problem was, I was having to create javascript on the server side to be fired on the client side. If you have tried that before, you know that it seldom works out well (at least for me).
I think I could have gotten it to work eventually, but the code was getting messy quickly, and I knew it was going to get worse when I tried to get the third level (products) up and running. Time to try something different.
Pete an Repeat are on a boat…Pete falls out…who’s left?
So my next idea was to use a .NET DataList control. This one died out quickly because it generates an HTML Table which caused all sorts of grief for my accordion. Next I tried a .NET Repeater. I figured this way I could use the server controls to handle my click events and load up my levels.
I was on the right path, but in the end to get things kinda sorta working I was having to use PageMethods. PageMethods are a great tool, but since you can’t access any of your form controls they were definitely the wrong way to go for this one.
Eureka!
From what I had learned using the Repeater, I knew that life would be easier if I can get away from javascript and get more into the server controls. While hunting around for a solution I ran into my old friend the ASP.Net Ajax Accordion server control. I tried to merge that guy with a Repeater and quickly learned that just gives you heartburn. After more searching I learned that the Accordion control can actually be databound. Oooh! Now we are getting somewhere.
In the end you get something like this –> Accordion Demo
So now that I have something working, lets break it down to see what I actually ended up doing. To walk through things with me, you probably want to download the code. Nothin’ too fancy…just some markup, a code behind, and a CSS file.
Off we go…into the wild blue yonder…
Lets start with the markup. It breaks down into 2 accordions and a repeater. The first accordion is loaded when the page loads. Everything else is loaded from an ItemDataBound event. If you are unfamiliar with this event, it is worth looking into.
The basic flow of the page is this:
- Page Load : Load the categories
- Category Data Bind : Load the subcategories
- Subcategory Data Bind : Load the products
This basically means that all the data for all the levels will be loaded at one time. If you have a large catalog, then this may not be the best solution, but for most small business sites this should work just fine.
The backbone of the solution is the ItemDataBound method so lets talk about what that is and how to use it.
So what is ItemDataBound? It is basically the event that signifies that an item just got data loaded into it and allows you to respond to that data. You sign up for it by putting a method in the OnDataBound property of the control (in this case our accordion). The event fires for every item. In other words, if you are loading 5 categories, then the ItemDataBound event will be triggered 5 times. Once inside the event you can get access to the goodies in the control (not before…not after).
That was one thing that was difficult for me to grasp when I started with ASP.NET. Say you have a label inside the header of the first accordion there. You would think that you could go server side and just reference that label right? Nope.
The problem with databound controls is that the label isn’t really on the page until it is attached to some data. Therefore you can’t access it like you would a normal control. The only way to get access to that label is with the ItemDataBound. To make matters even more complicated, to find it you have to search for it…
Label lbl = (Label)e.AccordionItem.FindControl("lblEmpty");
To find our label in the accordion control, you have to look inside the item (the item is always sent in the event argument) and then hunt it. Its not difficult, but until you wrap your head around how it works, it can be really confusing. But now you know (and knowing is half the battle…), so you are good to go.
My little demo is only 3 levels deep, but there really isn’t a limit on how far you can go except how much you want to anger the user :P.
The rest of the code you see in the code behind is simply to support the databinds (i.e. getting the sample data). If you run into the same requirements I hope this little tutorial will help.
Let me know if something doesn’t make sense!


Steven Quick said,
Wrote on February 27, 2008 @ 7:52 pm
My concern with using the ASP.NET ajax stuff is the page weight. Just looking at the demo page with firebug & yslow
79.2K 1 HTML/Text
138.8K 8 JavaScript Files
0.2K 1 Stylesheet File
218.3K Total size
10 HTTP requests
Of course after the first load the css and js should be cached but for having almost nothing on the page 219KB is huge. Image a full page with alot of features?
David Baxter said,
Wrote on February 28, 2008 @ 10:00 am
Hey Steven, thanks for writing. You have valid concerns, but lets see if I can break it down a bit to make sense of things.
The 79K for the HTML is because there actually is a good bit of text on the page. Each category has 5 sub categories, each subcategory has 5 products. That means there are basically 125 little paragraphs built into the page. That isn’t a small amount of markup.
The Javascript is what ASP.NET is bringing to the table. That will be cached like you said, but, if you were doing the effect with any javascript library (Prototype alone is 120K) it wouldn’t be much smaller, so ASP.NET isn’t really a hog.
The 10 HTTP Requests are because the page is built with AJAX technology. To get all the goodies, the page is going back to the server a few times. This would be true no matter how you built your ajax.
To have an effect like this does add overhead, no question about it, but using ASP.NET as opposed to another library really doesn’t change the amount of overhead.
On a tangential subject…I have been trolling around some of the most popular sites (IGN, Yahoo, etc.) and checking their page size. Those pages are friggen huge. IGN is over a meg, Yahoo was over 600K. These are some of the most popular sites on the net so this makes me wonder how important page size really is. Now I am not saying to ignore page size, but in the world of broadband, it does seem to be less important on the site’s success.
Hope that helps.
David
website designer melbourne said,
Wrote on March 5, 2008 @ 7:35 pm
hi i am working on one of my client website and i need a accordian effect my probleam is i wnat to bind them with database accordian header and every thing else is comming from database is there any way to do this?
David Baxter said,
Wrote on March 5, 2008 @ 8:22 pm
Hey Melbourne, I have to admit, I am a bit confused by the question. Can you clarify?
David
website designer melbourne said,
Wrote on March 6, 2008 @ 12:41 am
i am using ajax accordian panel and i need to bind with database just like datagrid or repater control.
some thing like this but it will not work as you cant but repater inside accordian ……
but i need some thing to bind accordian with database.
website designer melbourne said,
Wrote on March 6, 2008 @ 12:42 am
i am using ajax accordian panel and i need to bind with database just like datagrid or repater control.
some thing like this
but it will not work as you cant but repater inside accordian ……
but i need some thing to bind accordian with database.
website designer melbourne said,
Wrote on March 6, 2008 @ 12:45 am
hi david its like accordina inside repater i have tried so manny time pasing a code but i think it is not taking as comment….
David Baxter said,
Wrote on March 6, 2008 @ 10:51 am
It is usually best to email me code…something about my comment system here doesn’t like it.
david at creativeui dot com.
David
Jim said,
Wrote on March 30, 2008 @ 10:05 am
Cool. Salute to your nice job.
Telugu Movie Reviews said,
Wrote on May 6, 2008 @ 2:42 am
Thank you
Mike said,
Wrote on July 24, 2008 @ 1:39 pm
I cant access the Accordion Datasource in the codebehind, do you have any idea why that would be?