Live and learn. Maybe that’s my mantra. One thing I can tell you is that the first time I come up with a way to do something, it’s rarely the best. If I look at some old code of mine and think it’s perfect, I worry. We all are learning all the time, and it’s usually the case that we can see a better way to do things the next time we look.
Adding expand/collapse logic to a Data View Web Part (DVWP) is a great example. I’ve done this many, many times, and suddenly last week, I looked at a DVWP and saw it all again for the first time.
Part of the reason I saw it differently was that I was looking at the document Object Model (DOM) in the context of doing some jQuery spiffiness. Because of that, I was looking at how SharePoint itself does the expand/collapse stuff. You know what I mean:
When I set the view above to group by Navigation Area, I get different sections in it for each value of Navigation Area, in this case [Meats, Vegetables].
So how does it work? Well, simply, SharePoint lists the data in table rows (TRs) beneath the Group By values with the style set to display:none; (Assuming you have the view set to collapse by default, which is probably the most common setting.) That’s right, SharePoint just shows each group and item in a table row, no fancy wrapping DIVs logic or anything (which is always what I’d tried to do in the past, successfully, but it was usually pretty messy).
What SharePoint does (yes, SharePoint is anthropomorphic to me and I’m sticking to that) is give the table rows which are group headers IDs like this:
The generate-id() bit is what SharePoint Designer adds for you to make the group IDs unique; the generated IDs look something like:
Each of the group rows contain markup that looks something like this:
In a DVWP I built the other day, I emitted markup like this in my DVWP’s rowview template:
What this does is:
- In line 2, I use the ddwrt:NameChanged function to determine if the value of the @Target column has changed. ddwrt:NameChanged returns the new value if there has been a change and nothing if there hasn’t been.
- In line 3, I test whether there has been a change, and it there has been, I emit a group row.
- Whether there has been a change or not, I emit each item starting in line 13, in this case showing only the value of the @Title column (just to keep the example simple).