AccordionPortfolio

July 08, 2008
I'm scrubbing up my resume page, moving off the normal boring details to my LinkedIn profile, so I can build up a fancy portfolio with a whole lot more boring details.

For the fancy part, I decided to experiment with some JavaScript. I wanted to do a nested accordion bit, and my initial googling was not too encouraging. I did find some libs that would do nested accordions and started with one I found at Dynamic Drive that works with jQuery. Probably more due to my novice JavaScript skills than the lib, it seemed awkward to work with, so I hunted for another one.

I ran across a scriptaculous lib made by stickmanlabs and started having better success. At the same time I realized that trying to inline the amount of data I had into html myself was becoming a beating, and my code gen nose started twitching. Now I've got a Ruby script with a YAML data section at the end of it that'll spit out all the div markup I need to work with stickmanlabs Accordion v2.0.

So far so good, except I'm pushing the library a bit beyond the demo by having many nested accordions (which might be a smell that my UI approach here for all this data isn't a good one). The library expects only one nested accordion, and for that div to have the id “vertical_nested_container”. I actually blew right past that while building things the first time (even though Tidy complained about my having many unique ids that are not actually ... well ... unique), and things worked fine ... in Firefox and Safari at least. But IE7, well, wasn't so kind in accommodating my many redundant unique ids.

My first thought was to try and change the id to a class, and see if that works. It didn't, because of how the code in the accordion.js library is structured for initializing the accordions. Since my JS hacking skills are limited for the time being, I realized the shortest way home at this point was to make separate ids for each nested accordion.

Since I'm already doing code-gen for the div section of the page, changing to unique ids in that section is a breeze. The problem then becomes, what to do with all of the initialization code? Here's the initialization code for one nested accordion:

var nestedVerticalAccordion = new accordion('vertical_nested_container', {
classNames : {
toggle : 'vertical_accordion_toggle',
toggleActive : 'vertical_accordion_toggle_active',
content : 'vertical_accordion_content'
}
});

Not bad for one, but I've got 8, and that sort of repetition is not programming. Since I'm already generating the div sections, why not generate the javascript initialization section? A little ugly (and it makes for a longer page with the repetition), but it'll work. I did look a little into writing some init code that would scan the DOM for everything I needed, but I needed a getElementById with a wildcard or somesuch and I couldn't find anything out of the box for that sort of thing.

So - wire up the new code-gen, and ... well it doesn't quite work. Well, it works, but it doesn't look right. That's when I remember the css - it has special formatting for the nested according based on id. If I'm going to code gen 8 separate nested accordions with 8 separate ids, then I'll now need 8 separate css entries for each id. Sigh. Code gen's cool, but this seems to be getting out of hand. Fortunately, after poking around in Firebug for a bit, I realized I could put the styling into the tag itself.

At this point, things are looking good. Nested accordion support without modifying the original library, and taking care of DRY issues through code gen.

Things were working pretty well now, and I needed a color scheme makeover. I Googled around and found kuler, a nice tool for coming up with color schemes. I fed it the background color of my site as a base color, and through various experiments came up with a scheme that I liked.

I started filling up the accordion with content, and as I started accruing a bit of text, I start noticing an annoyance with the presentation. Many times, an expanded accordion of text wouldn't be visible without having to scroll to view it all. This brought to mind a recent 37signals post showing how they added autoscrolling to Backpack to make sure when a selected action would reveal content below the scroll, the page now scrolls the new stuff into view.

Searching for a way to do this with scriptaculous was a bit frustrating at first, none of the effects listed in the wiki docs included the base ScrollTo effect. They recently moved their wiki to github, so maybe that's what happened to it. Fortunately, I kept plugging and eventually ran across other mentions of this effect, which I found in the source. After losing way too much time experimenting with adding this effect inside the accordion.js library, it suddenly clicked and started working -- I wasn't feeding it the correct element for a while.

I was much happier with the accordion with this effect added in. Makes it pretty smooth to work with. There are still a couple of issues I'd like to tighten up:

- The effect is always triggered, even if there's no need to scroll to the div, so after a while it's a little annoying to see a small page scroll take place to move something which was entirely in view a few lines to keep it still entirely in view.

- Sometimes, especially in the top sections of the overall accordion, the title is scrolled out of view for some reason.

And one last issue that I'd like to correct for multiple nested accordion support:

- Opening a section inside a new nested accordion doesn't close anything in the prior nested accordion.

So ... we'll see where I go from here, be nice to get rid of all the code gen, fix these existing issues and submit some patches to stickman.

tags: ComputersAndTechnology
comments powered by Disqus