flex accordion navigation xml updated for 3.0

Since it seems I get much traffic from the accordion navigation, I decided to come up with a new example updated for flex 3.0.

I left the flexlib out in this version, so the mxml should compile by itself. Also, to make this example even more dynamic, I use some php along with a flash variable to ready the url of the httpService at page load. This makes it possible to load different XML documents, and therefore create different navs based on…well whatever you want. For this example I use rand(1,2) to pick randomly between 2 different properties files.

Here is the example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?xml version="1.0" encoding="utf-8" ?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
layout="vertical" viewSourceURL="srcview/index.html" backgroundColor="#ffffff"
creationComplete="init();">
<mx:Script>
<![CDATA[
 
import mx.collections.ArrayCollection;
import mx.utils.ArrayUtil;
import mx.rpc.events.ResultEvent;
//[Bindable]
//public var navData:ArrayCollection;
 
[Bindable]public var str:String;
 
[Bindable] public var httpServiceURL:String;
[Bindable] public var appHeight:Number;
[Bindable] public var appWidth:Number;
 
[Bindable]public var xmlData:Object = new Object();
[Bindable]public var headingData:Object = new Object();
[Bindable]public var linkData:Object = new Object();
 
private function init():void{
httpServiceURL=Application.application.parameters.httpServiceURL;
appHeight=Application.application.parameters.appHeight
appWidth=Application.application.parameters.appHeight
srv.send();
}
 
private function getHeadings(evt:ResultEvent):void{
xmlData = evt.result;
headingData = xmlData.a_nav;
}
 
private function getLinkObject(a:Number):Object{
linkData = headingData.heading[a];
return linkData;
}
 
]]>
</mx:Script>
 
<mx:Style>
Application {
backgroundGradientColors: #FFFFFF, #FFFFFF;
backgroundGradientAlphas: 1, 1;
vertical-align: top;
horizontal-align: center;
padding-top: 0px;
padding-left: 5px;
padding-right: 0px;
}
 
Accordion {
textRollOverColor: #FFFFFF;
textSelectedColor: #FFFFFF;
color: #FFFFFF;
headerHeight: 35;
vertical-gap: 5;
background-alpha:0;
open-duration:500;
border-style:none;
 
}
 
.gradientHeaderSquare {
font-family: Verdana;
borderColors: #AAB1CD, #AAB1CD;
overBorderColors: #FFFFFF, #FFFFFF;
selectedBorderColors: #FFFFFF, #FFFFFF;
borderThickness: 2;
color: #FFFFFF;
borderAlpha: 1;
fillColors: #7f8182, #7f8182;
fillAlphas: 1, 1;
fillColorRatios: 0, 255;
overFillColors: #FFFFFF, #FFFFFF;
overFillAlphas: 1, 1;
overFillColorRatios: 0, 169;
selectedFillColors:#000000, #000000;
selectedFillAlphas: 1,1;
fontSize: 13;
padding-left: 10px;
padding-top: 0px;
}
 
.gradientHeaderRound {
cornerRadius: 20;
font-family: Verdana;
borderColors: #AAB1CD, #AAB1CD;
overBorderColors: #FFFFFF, #FFFFFF;
selectedBorderColors: #FFFFFF, #FFFFFF;
borderThickness: 2;
color: #FFFFFF;
borderAlpha: 1;
fillColors: #7f8182, #7f8182;
fillAlphas: 1, 1;
fillColorRatios: 0, 255;
overFillColors: #FFFFFF, #FFFFFF;
overFillAlphas: 1, 1;
overFillColorRatios: 0, 169;
selectedFillColors:#000000, #000000;
selectedFillAlphas: 1,1;
fontSize: 13;
padding-left: 10px;
padding-top: 0px;
}
 
LinkButton {
fontSize: 10px;
rollOverColor: #fafafa;
selectionColor: #fafafa;
color: #0B357F;
textRollOverColor: #25bbfc;
textSelectedColor: #0B357F;
padding-left: 15px;
padding-top: 5px;
}
 
.headerBox {
font-weight: bold;
color: #FFFFFF;
}
 
</mx:Style>
 
<mx:HTTPService id="srv" url="{httpServiceURL}" resultFormat="object" result="getHeadings(event);"/>
 
<mx:Accordion id="accordion" width="{appHeight}" height="{appWidth}" headerStyleName="gradientHeaderRound">
 
<mx:Repeater id="rep" dataProvider="{headingData.heading}">
<mx:VBox label="{rep.currentItem.title}" styleName="headerBox" backgroundColor="#fafafa" width="{rep.currentItem.width}" height="{rep.currentItem.height}">
<mx:Repeater id="rep2" dataProvider="{getLinkObject(rep.currentIndex).link}">
<mx:LinkButton buttonDown="navigateToURL(new URLRequest(event.currentTarget.getRepeaterItem()), '_top')" label="{rep2.currentItem.linkname}" />
</mx:Repeater
</mx:VBox>
 
</mx:Repeater>
 
</mx:Accordion>
 
 
</mx:Application>

as you can see for this example I have decided to use Object instead of ArrayCollection. I just found it easier to get the data than using e4x.

Download the complete example to see how the index file that embeds this swf generates the service that will be used to create the navigation.

Here is the result

Here is the full source

Updated: 6-12-08 : I had a needless function that was causing a bug. Works as it should now ;)

flex accordion navigation using xml

Today I would like to share a flex application I think may be very useful to someone. Imagine you need to generate an accordion navigation with dynamic content such as the one used on the second level of cnn’s website. You would like to be able to use the same application over without massive effort, or copying and pasting code blocks all over the place. Sure this could be done with a mountain of javascript, or you might want to consider flex. For those with experience using flex, I present the mxml file free of charge. For those without any experience with flex, you may want to read a tutorial before jumping into this example.

 <?xml version="1.0" encoding="utf-8"?><mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" xmlns:flexlib="http://code.google.com/p/flexlib/"
layout="vertical" viewSourceURL="srcview/index.html" backgroundColor="#ffffff"
creationComplete="srv.send();"<mx:Script>
<![CDATA[
 
import mx.collections.ArrayCollection;
import mx.utils.ArrayUtil;
[Bindable]
public var navData:ArrayCollection;
 
[Bindable]
public var index:int=-1;
 
]]>
</mx:Script>
 
<mx:Style>
Application {
backgroundGradientColors: #FFFFFF, #FFFFFF;
backgroundGradientAlphas: 1, 1;
vertical-align: top;
horizontal-align: center;
padding-top: 0px;
padding-left: 5px;
padding-right: 0px;
}
 
VAccordion {
textRollOverColor: #FFFFFF;
textSelectedColor: #FFFFFF;
color: #FFFFFF;
headerHeight: 35;
vertical-gap: 5;
background-alpha:0;
open-duration:500;
border-style:none;
 
header-style-name: gradientHeader;
 
}
 
.gradientHeader {
 
font-family: Verdana;
cornerRadii: 10, 10, 10, 10;
borderColors: #AAB1CD, #AAB1CD;
overBorderColors: #FFFFFF, #FFFFFF;
selectedBorderColors: #FFFFFF, #FFFFFF;
borderThickness: 2;
color: #FFFFFF;
borderAlpha: 1;
fillColors: #7f8182, #7f8182;
fillAlphas: 1, 1;
fillColorRatios: 0, 255;
overFillColors: #FFFFFF, #FFFFFF;
overFillAlphas: 1, 1;
overFillColorRatios: 0, 169;
selectedFillColors:#000000, #000000;
selectedFillAlphas: 1,1;
 
fontSize: 13;
padding-left: 10px;
padding-top: 0px;
 
}
 
LinkButton {
fontSize: 10px;
rollOverColor: #fafafa;
selectionColor: #fafafa;
color: #0B357F;
textRollOverColor: #25bbfc;
textSelectedColor: #0B357F;
padding-left: 15px;
padding-top: 5px;
}
 
.headerBox {
font-weight: bold;
color: #FFFFFF;
}
 
.students {
padding-top: 0px;
}
 
.medical {
padding-top: 0px;
}
 
.employ {
padding-top: 0px;
}
 
.services {
padding-top: 0px;
}
 
.label {
font-weight: bold;
color: #FFFFFF;
}
 
VBox{
 
}
 
</mx:Style>
 
<mx:HTTPService id="srv" url="properties.xml" resultFormat="e4x" />
 
<mx:XMLListCollection id="headingData" source="{srv.lastResult.heading}" />
<mx:XMLListCollection id="linksData" source="{srv.lastResult.heading.link.@linkname}" />
 
<flexlib:VAccordion id="accordion" headerRenderer="Header" width="238" height="230" >
 
<mx:Repeater id="rep" dataProvider="{headingData}">
<mx:VBox label="{rep.currentItem.@title}" styleName="headerBox"  backgroundColor="#fafafa" width="{rep.currentItem.@width}" height="{rep.currentItem.@height}">
 
<mx:Repeater id="linkrep" dataProvider="{rep.currentItem.link}">
<mx:LinkButton buttonDown="navigateToURL(new URLRequest(event.currentTarget.getRepeaterItem()), '_top')"  label="{linksData.getItemAt(index+=1)}" />
</mx:Repeater>
 
</mx:VBox>
</mx:Repeater>
 
</flexlib:VAccordion>
 
</mx:Application>

What this application does is loads data from an XML properties file containing the titles for the headers, the names for the links, and the URLs. I think the example is pretty straight forward.

To compile this you will need the flexlib.swf added to your flex/frameworks/libs folder as well as the header.mxml file which is used to allow the accordion to activate on mouse-over. The header.mxml file was found on http://dougmccune.com although the exact post escapes me now.

Here is the result

http://www.dreamwagon.com/flex/examples/accordion/

The xml properties file is herehttp://www.dreamwagon.com/flex/examples/accordion/properties.xmlThe source file can be copied from above or downloaded

http://www.dreamwagon.com/flex/examples/accordion/AccordionNavigation.mxml

and the header http://www.dreamwagon.com/flex/examples/accordion/Header.mxml

And finally the flexlib can be found here

http://code.google.com/p/flexlib/downloads/list

Of course you may take out the reference to the header and to the flexlib and complile the AccordionNavigation.mxml alone if you like.

Happy Flexing!