8.3 CSS/jQuery: Building an accordion style menu

jQueryUI is a website that provides lot’s of bells and whistles for user interface design implementations. ┬áThe following tutorial will take you through the steps of using the jQueryUI library to generate an accordion style menu.

Starter code

The following code has three elements in the side panel:

side panel

side panel

We want to change this to look like this:

accordion menu

accordion menu

Let’s start with some starter code. This site has a map search, a directions search, and some map layers from ArcGIS Server:

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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <title>8.3 - Accordion Menu's</title>
    <style type="text/css">
        html { height: 100% }
        body { height: 100%; margin: 0px; padding: 0px }
        #map_canvas { height: 100% }
    </style>
 
    <!-- API links -->
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript" src="http://yohman.bol.ucla.edu/jquery-1.5.2.min.js"></script>
    <script type="text/javascript" src="http://www.yohman.com/students/rychen88/Scripts/arcgislink.js"></script>  
   
    <script type="text/javascript">    
        //declare namespace
        var yoh = {};
 
        //declare map
        var map;
       
        //declare geocoder
        var geocoder;
               
        //declare direction variables
        var directionDisplay;
        var directionsService = new google.maps.DirectionsService();
       
        //ArcGIS Server layers
        var serviceUrlOne = 'http://whippet.ats.ucla.edu/ArcGIS/rest/services/up206b/week7.1/MapServer';
        var agsMapOne = new gmaps.ags.MapOverlay(serviceUrlOne, {opacity:0.5});
       
        var serviceUrlTwo = 'http://whippet.ats.ucla.edu/ArcGIS/rest/services/up206b/Metro_stops/MapServer';
        var agsMapTwo = new gmaps.ags.MapOverlay(serviceUrlTwo);
       
        var serviceUrlThree = 'http://whippet.ats.ucla.edu/ArcGIS/rest/services/up206b/week7.12/MapServer';
        var agsMapThree = new gmaps.ags.MapOverlay(serviceUrlThree, {opacity:0.5});
       

        function trace(message)
        {
            if (typeof console != 'undefined')
            {
                console.log(message);
            }
        }
 
 
        //toggle single layers on/off
        yoh.toggleLayer = function(layer,id)
        {
            if ($('#'+id).is(':checked'))
            {
                layer.setMap(map);
            }
            else
            {
                layer.setMap(null);
            }
        }
       
        yoh.geocode = function()
        {
            var address = $('#address').val();
            geocoder.geocode( { 'address': address}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK)
                {
                    map.setCenter(results[0].geometry.location);
                    var marker = new google.maps.Marker({
                        map: map,
                        position: results[0].geometry.location
                    });
                }
                else
                {
                    alert("Geocode was not successful for the following reason: " + status);
                }
            });
        }
               
        //function to get directions
        yoh.getDirections = function()
        {
            //grab the direction values from user input
            var from = $('#from').val();
            var to = $('#to').val();
            var selectedMode = $('input[name="mode"]:checked').val();
           
            //set the direction parameters
            var request = {
                origin:         from,
                destination:    to,
                travelMode:     google.maps.DirectionsTravelMode[selectedMode]
            };
           
            //send the direction request and display on the map
            directionsService.route(request, function(response, status) {
                if (status == google.maps.DirectionsStatus.OK)
                {
                    directionsDisplay.setDirections(response);
                    directionsDisplay.setMap(map);
                    directionsDisplay.setPanel(document.getElementById("directionsPanel"));
                }
            });
        }
         
        //Function that gets run when the document loads
        yoh.initialize = function()
        {
            //set the geocoder
            geocoder = new google.maps.Geocoder();
           
            //set directions
            directionsDisplay = new google.maps.DirectionsRenderer();
           
            var latlng = new google.maps.LatLng(34.070264, -118.4440562);
            var myOptions = {
                zoom: 13,
                center: latlng,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

            //Get AGS Layers
            agsMapOne.setMap(map);
            agsMapThree.setMap(map);
            agsMapTwo.setMap(map);
        }
    </script>
</head>
<body onload="yoh.initialize()">
 
    <!-- side panel div container -->
    <div style="position:absolute; width:330px; height: 100%; overflow:auto; float:left; padding-left:10px; padding-right:10px;">
        <h1>Tutorial 8.3: Accordion Menu's</h1>
       
                <!-- search box -->
                <div style="border:1px solid #ccc; background:#e5e5e5; padding:10px;">
                    <span style="width:50px; display: inline-block;">Find:</span>
                    <input type="text" id="address" value="90230">
                    <input type="button" value="find" onClick="yoh.geocode()">
                </div>

                 <!-- user input options -->  
                <div style="border:1px solid #ccc; background:#e5e5e5; padding:10px; margin:10px 0;">
                    <span style="width:50px; display: inline-block;">From:</span>
                    <input type="text" id="from" value="90230">
                    <br>
                    <span style="width:50px; display: inline-block;">To:</span>
                    <input type="text" id="to" value="90095">      
                    <br>
                    <span style="width:50px; display: inline-block;">Mode:</span>
                    <input name="mode" type="radio" value="DRIVING" checked>drive
                    <input name="mode" type="radio" value="WALKING">walk
                    <input name="mode" type="radio" value="BICYCLING">bicycle
                    <br>
                    <input type="button" value="get directions" onClick="yoh.getDirections()">
                </div>
                <!-- display directions -->
                <div id="directionsPanel"></div>

                <div style="border:1px solid #ccc; background:#e5e5e5; padding:10px;">
                    <input type="checkbox" id="basemap" onClick="yoh.toggleLayer(agsMapOne, 'basemap')" checked> Year 2000 Population<br>
                    <input type="checkbox" id="basemap2" onClick="yoh.toggleLayer(agsMapThree, 'basemap2')" checked> Year 2000 Ages 22-29 Population<br>
                    <input type="checkbox" id="pointmap" onClick="yoh.toggleLayer(agsMapTwo, 'pointmap')" checked> All LA Metro Stops
                </div>
    </div>
    <!-- map div container -->
    <div id="map_canvas" style="height:100%; margin-left:350px;"></div>
</body>  
</html>

Adding the jQueryUI links

The official documentation to add accordion style menu’s is here.

Before getting started, we need to download the relevant jQueryUI javascript library files and add them to our server.

  1. Go to http://jqueryui.com/download
  2. Click on “deselect all components”, and only select the “accordion” checkbox
  3. Select a theme from the drop down (you can see which one you like by going to the “theme” page)
  4. Click on “download”

Now that you have downloaded your jQueryUI library, extract the zip file. You will notice that you have the following content:

  • css (folder)
  • development-bundle (folder)
  • js (folder)
  • index.html

Open up index.html in a browser and inspect the source code.

Upload the css folder and the js folder to the root of your server space on yohman.com. You do not have to upload the development-bundle folder or the index.html file.

Now, add the following links to the header portion of the code (just under the script that calls for the ArcGIS Server link). Copy and paste your portion from YOUR index.html file (it may be different from what is shown below depending on the choices you made:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- jQuery UI -->
<link type="text/css" href="css/south-street/jquery-ui-1.8.12.custom.css" rel="stylesheet" />  
<script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.12.custom.min.js"></script>
<script type="text/javascript">
    $(function(){

        // Accordion
        $("#accordion").accordion({ header: "h3" });
        //hover states on the static widgets
        $('#dialog_link, ul#icons li').hover(
            function() { $(this).addClass('ui-state-hover'); },
            function() { $(this).removeClass('ui-state-hover'); }
        );
    });
</script>

This adds the jQuery UI library, the css for your theme choice, and it also assigns an element with the ID name “accordion” to be the parent container for your menu items. The markup of your accordion container needs pairs of headers and content panels:

1
2
3
4
5
6
7
8
<div id="accordion">
    <h3><a href="#">First header</a></h3>
    <div>First content</div>
    <h3><a href="#">Second header</a></h3>
    <div>Second content</div>
    <h3><a href="#">Third header</a></h3>
    <div>Third content</div>
</div>

This means that you first have to wrap the collapsible menu items in <div id="accordion"></div>. Then, every element that you want as a trigger and header for your collapsible menu needs to be put in an <h3></h3> tag, immediately followed by a <div></div> container for its content.

All three menu sections of the sample code are already in their own DIV’s. Therefore, the structure that needs to be implemented would look like this:

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
<div id="accordion">
    <h3><a href="#">Find an address</a></h3>
    <div>
        <!-- search box -->
        <div style="border:1px solid #ccc; background:#e5e5e5; padding:10px;">
            <span style="width:50px; display: inline-block;">Find:</span>
            <input type="text" id="address" value="90230">
            <input type="button" value="find" onClick="yoh.geocode()">
        </div>
    </div>
    <h3><a href="#">Get directions</a></h3>
    <div>
         <!-- user input options -->  
        <div style="border:1px solid #ccc; background:#e5e5e5; padding:10px; margin:10px 0;">
            <span style="width:50px; display: inline-block;">From:</span>
            <input type="text" id="from" value="90230">
            <br>
            <span style="width:50px; display: inline-block;">To:</span>
            <input type="text" id="to" value="90095">      
            <br>
            <span style="width:50px; display: inline-block;">Mode:</span>
            <input name="mode" type="radio" value="DRIVING" checked>drive
            <input name="mode" type="radio" value="WALKING">walk
            <input name="mode" type="radio" value="BICYCLING">bicycle
            <br>
            <input type="button" value="get directions" onClick="yoh.getDirections()">
        </div>
        <!-- display directions -->
        <div id="directionsPanel"></div>
    </div>
    <h3><a href="#">Map layers</a></h3>
    <div>
        <input type="checkbox" id="basemap" onClick="yoh.toggleLayer(agsMapOne, 'basemap')" checked> Year 2000 Population (By Census Tract)<br>
        <input type="checkbox" id="basemap2" onClick="yoh.toggleLayer(agsMapThree, 'basemap2')" checked> Year 2000 Ages 22-29 Population (By Census Tract)<br>
        <input type="checkbox" id="pointmap" onClick="yoh.toggleLayer(agsMapTwo, 'pointmap')" checked> All LA Metro Stops
    </div>
</div>

(full sample code)

That’s it! There are many, many more jQuery UI implementations that you can incorporate into your sites. Go crazy!

Leave a Reply