This is an example of using a slightly modified Flex Accordion to create a sweet looking menu. Someone on flexcoders asked how to make a menu like the one found here on Apple’s website.

Here’s the example I came up with to do this:

This movie requires Flash Player 9

The Accordion
This is a Flex Accordion component (well, sort of…). It’s actually a slightly modified Accordion. The cool part is that FlexLib already had a modified Accordion component because I had made the Horizontal Accordion. Because of that there has been a VAccordion in FlexLib as well, which up until now has been exactly the same as the normal Accordion component in the framework.

So I added a new property to both VAccordion and HAccordion called headerLocation, which allows you to specify where the header should appear relative to the content. For VAccordion this property can be either “above” or “below”. Using above means it works just like the normal Accordion. But now you can also specify below, which will render the header below the content, which was the first requirement for this example.

The header renderer
The next problem was that the header of the Accordion needs to be more complex than a normal button. It needs to show two text fields, one for the title of the header and one for the descriptive text. And the description needs to wrap on multiple lines. So as I blogged about previously, I used the CanvasButtonAccordionHeader in FlexLib to easily use a complex header on an Accordion.

The header skin
Next we have the problem of the skin for the button. The skin isn’t too complex, but there are a few things that are hard to do with the standard Button skin. We want rounded corners on the bottom of the button but not the top. And we want nice control over the gradient of the button. What to do? FlexLib has an EnhancedButtonSkin that lets us do all this (and a lot more). Problem solved.

The mouse interaction
The menu we’re trying to emulate responds to mouse over events, not clicks like the normal Accordion does. This is easy enough to fix by simply faking a MouseEvent.CLICK event any time we get a MouseEvent.MOUSE_OVER event. By making our headers dispatch these fake click events we trick the Accordion into opening the child when the mouse rolls over each header.

And there you have it.

View the example in its own window (view-source enabled)
View the source of the example

In the source I’ve bundled a version of flexlib.swc that includes the new headerLocation property for the Accordion components. This is because I haven’t yet released an updated distribution zip on the FlexLib project page that includes this update (but I did commit the changes to SVN if you’re using that).

28 Responses to “Nifty Flex Accordion Menu (like on Apple.com)”

  1. polyGeek says:

    Once again, brilliance. You know Doug. You’re really good at this stuff. You should think about doing it for a living. :-)

  2. Greg says:

    I did an “auto-opening” accordion a while back, but I did it by setting a mouseover event handler on each header that set the Accordion’s selectedIndex (rather than simuating the mouse click). Is there any advantage of one way over the other?

  3. Raghu says:

    Awesome Doug… You are sure Flexing your Muscle ;)

  4. Tony says:

    As the author would say “Fucking Awesome”. Nice job Dude.

  5. ryan says:

    apples one looks kinda jerky on my machine… yours ran smoothly… nice one holmes…

  6. Satish says:

    Cool Component! Thanks for sharing.

  7. Pieter says:

    Doug - very well done. I have a project where I want to get this effect:

    http://www.savuti.com/examples/CMenuAS3.swf

    I have done this in Flash using timeline animation. I now need it in Flex. It seems the easiest way to do this is to have each header width controlled individually. At the moment, all header widths are controlled together with the paddingTop property. Any suggestions on how to control the header widths individually (or any other suggestions on hoe to accomplish this) will be highly appreciated. Thank you in advance.

  8. Justin Winter says:

    Doug - Thank you for the contributions you’ve made to the community through FlexLib and your blog. I’m sure you’ve helped a lot of people improve their Flex/AS3 skills.

    I did want to get your take on the best way to go about developing a component that integrates the functionality of the tree control with the scrollable menu component you did.

    Essentially, I’d like a build a menu that is recursive like a tree/menu but when opening a branch that contains more children than can be displayed in the available space, a control like your scrollable menu would appear. This would give the user the ability to navigate to all nodes by either hovering over the “down arrow” or via detecting the mouse position. The main difference between the control I would like to build and your scrollable menu is that I don’t want to popUp the child menu but rather, move the next parent node(s) down as far as possible in the available space, and scroll the “leaf” nodes via mouse position or up/down arrows on a layer below the parent displayObjects.

    Unlike the Tree control which displays a scrollbar for the entire tree, the component I’d like to develop, would only scroll the level of nodes the user is interacting with.

    I could possibly do something similar by cascading containers and lists, but that seems aweful ugly to me and having a control like this wrapped up into a nice tidy component would pretty sweet.

    Here’s an example of a component I wrote for AS2 which shows the functionality I’d pretty much like to recreate. This component goes bottom-up, but has a flag to switch to top-down which I’d like to add at some point, but top-down would be fine as a starting point! This version does not show the scrolling feature, so I hope my above description makes sense.

    useflashmore.com/accordion-menu-example

    I really think a control like this for Flex would be pretty sweet and I’d love to post it to flexlib if I can pull it off!

    Sorry for the length of this post.

  9. Duane Hardy says:

    I am trying to recreate the mouseover effect with no luck in my accordian. I have a repeater that builds the accordian from xml. What should I be doing differently?

  10. Duane Hardy says:

    My last post the code was stripped out. Here is another try to post the code.

  11. Justin Winter says:

    Doug, I just wanted to thank you for all the source you’ve released on flexlib. I finally got my component working and I couldn’t have done it without studying everything you’ve done. You really write some nice code man! (man that reads a lot more dorky than intended).

    I’d love to get your thoughts on what I’ve got going if you get a chance.

    Here’s the link to the working example for the
    Scrollable Accordion Style Custom Component

    Here’s the full URL if above href doesn’t go through:
    http://www.useflashmore.com/flex-as3-scrollable-accordion-menu/scrollable-accordion-menu-custom-component/main.html

    Best regards and thanks.
    Justin Winter - useflashmore.com

  12. Freelance Jobs - Freelance Gigs » Flash Acordion Menu by pauld581 says:

    […] I would like a Flash accordion system similar to this: http://dougmccune.com/blog/2007/09/22/nifty-flex-accordion-menu-like-on-applecom/ The highlight and top header color must be editable, plus… (Budget: $100-300, Jobs: Flash, XML) […]

  13. https-chase.com » Blog Archive » Flash Acordion Menu by pauld581 says:

    […] I would like a Flash accordion system similar to this: http://dougmccune.com/blog/2007/09/22/nifty-flex-accordion-menu-like-on-applecom/ The highlight and top header color must be editable, plus… (Budget: $100-300, Jobs: Flash, XML) Programmers get paid now to complete this work request. Posted under Work Requests Comments (0) […]

  14. kevin says:

    Is the CanvasButtonAccordionHeader compatible with Fle 3 Beta 3? I have had trouble getting it to compile in the nightly build I am using (form 12/22/07).

  15. Ralph Krausse says:

    I am getting the same prob with Beta 3. Here are the errors…

    Severity and Description Path Resource Location Creation Time Id
    1044: Interface method get creatingContentPane in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079359 72
    1044: Interface method get defaultButton in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 76
    1044: Interface method get horizontalScrollPosition in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 78
    1044: Interface method get verticalScrollPosition in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 74
    1044: Interface method get viewMetrics in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 79
    1044: Interface method set creatingContentPane in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079359 71
    1044: Interface method set defaultButton in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079359 73
    1044: Interface method set horizontalScrollPosition in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 75
    1044: Interface method set verticalScrollPosition in namespace mx.core:IContainer not implemented by class Controls.Menu:Header. GMN/src/Controls/Menu Header.mxml line 7 1201788079375 77

  16. yo says:

    Hi ,
    You are don! I tried to download and run the source, but got error “could not resolve to a component “. What may be wrong?

  17. yo says:

    Sorry It was beacuse of fb3( & i forgot to add swc in library path ) , it runs fine in fb2. Now I am trying to add images at runtime. The added item is selected. It works Ok but problem is that when i add new AccordionItem at first time half of the image is cut. When you select diffrerent item, it becomes ok, but at the initall time of addition it is half cut. What is solution ?

    This is teh code i am adding to main ( AppleAccordionExample ) mxml file

  18. yo says:

    what changes are needed to run it in flex builder 3 ?

  19. manish says:

    hello,
    pls help me the AppleAccordionExample.zip and any one pls help me how to put it in my ASP code..

  20. Greg Landers says:

    Please let me know when there is a fix for this in FB3! Thanks!~

  21. Nag says:

    Just use the latest flexlib from google site. It will work in fb3

  22. Ed says:

    This is very good!…I was changing the text box for a textarea to get the scrolling bar when text is long, but the scrolling doesn’t work, any idea why?

  23. rako says:

    This is very good! but My last post the code was stripped out.

  24. doug says:

    Please do not flame me for asking, but I am ignorant about this flex stuff. I downloaded the file and got it running looking like just on this site, but when I change the info in the mxml file, it does not update the menu. Does this have something to do with the swf file? I was thinking this thing could be modified in xml like other flash type menus. Any assistance with this is appreciated. Thanks!

  25. jastero says:

    Is it possible to preload the images so that the first time you roll over the different items, there is a smooth transition? If you notice, the images kinda pop in the first time, then when you roll back over them, they seem to be cached or something. I am trying to do this on a project using the accordion, but with no luck yet. The client is really crazy about transisitions, so it is a problem for me.

    Thanks!

  26. Proyb says:

    Stolen article from this author?
    http://www.duzengqiang.com/blog/article.asp?id=450

  27. Scott Macdonald says:

    I am getting this error in Header.mxml:

    Severity and Description Path Resource Location Creation Time Id
    1044: Interface method get creatingContentPane in namespace mx.core:IContainer not implemented by class Header. LiveDocTrackerProject/src Header.mxml line 7 1223063665991 209

    I am using Flex 3.

  28. Erich Cervantez says:

    This is great, Doug, thanks for the article.

    I have a simple question, though, for you or anyone else out there in flex-land: what’s a simple or not-so-simple way of defaulting the Accordian to a “closed” state initially? In other words, I’d like for none of the child containers to display until a user clicks a header.

Leave a Reply