Graphic Design solutions that are worth their weight in gold for print, exhibits and the web.
  HOME       INTRODUCTION       PROFILE       PORTFOLIOS       CONTACT  

Now Accepting Major Credit Cards

Solution Graphics

LOGIN | REGISTER

     
 

Free Accordion Expandable Menu Script

You can visit www.dynamicdrive.com to download the original files for this Free Expandable Javascript Menu Script. The script is free to use an alter as long as the credits are contained within the <head> of your web page. DynamicDrive also has the files all zipped and ready for you to download. The choice is yours.

Follow the five easy steps below to create your own

Step 1 - Create the HTML file

Sample of Expandable MenuExpandable Accordion Menu

 

This image is the result of the HTML code below.>>

Cut & Paste the text from the table cell below into a simple text file program like Note Pad* and name it YourWebPage.html

Replace the information highlighted in yellow to the correct paths to the files that will be uploaded to your server.

 

*Under the Start Start/Program/Accessories/notepad of your IBM computer or your Control Panel.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Expandable Menu Sample</title>
</head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://www.yoursite.com/ddaccordion.js">/***********************************************
* Accordion Content script- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
* Visit http://www.dynamicDrive.com for hundreds of DHTML scripts
* This notice must stay intact for legal use
***********************************************/
</script>
<script type="text/javascript">
ddaccordion.init({
headerclass: "submenuheader", //Shared CSS class name of headers group
contentclass: "submenu", //Shared CSS class name of contents group
revealtype: "click", //Reveal content when user clicks or onmouseover the header? Valid value: "click", "clickgo", or "mouseover"
mouseoverdelay: 200, //if revealtype="mouseover", set delay in milliseconds before header expands onMouseover
collapseprev: true, //Collapse previous content (so only one open at any time)? true/false
defaultexpanded: [], //index of content(s) open by default [index1, index2, etc] [] denotes no content
onemustopen: false, //Specify whether at least one header should be open always (so never all headers closed)
animatedefault: false, //Should contents open by default be animated into view?
persiststate: true, //persist state of opened contents within browser session?
toggleclass: ["", ""], //Two CSS classes to be applied to the header when it's collapsed and expanded, respectively ["class1", "class2"]
togglehtml: ["suffix", "<img src='http://www.yoursite.com/images/plus.gif' class='statusicon' />", "<img src=''http://www.yoursite.com/minus.gif' class='statusicon' />"], //Additional HTML added to the header when it's collapsed and expanded, respectively ["position", "html1", "html2"] (see docs)
animatespeed: "fast", //speed of animation: integer in milliseconds (ie: 200), or keywords "fast", "normal", or "slow"
oninit:function(headers, expandedindices){ //custom code to run when headers have initalized
//do nothing
},
onopenclose:function(header, index, state, isuseractivated){ //custom code to run whenever a header is opened or closed
//do nothing
}
})
</script>
<body>
<div class="glossymenu"> <a class="menuitem submenuheader" href="#" >Section</a>
<div class="submenu">
<ul>
<li><a href="#">Link</a></li>
<li><a href="#">Link Two </a></li>
<li><a href="#">Link Three </a></li>
</ul>
</div>
</div>
</body>
</html>

Step 2 - The Script

Cut & Paste the following code after the <head> but before the <body> of your YourWebPage.html page. (See HTML Sample )

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

<script type="text/javascript" src="http://www.yoursite.com.ddaccordion.js">

/***********************************************
* Accordion Content script- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
* Visit http://www.dynamicDrive.com for hundreds of DHTML scripts
* This notice must stay intact for legal use
***********************************************/

</script>

<script type="text/javascript">

ddaccordion.init({
headerclass: "submenuheader", //Shared CSS class name of headers group
contentclass: "submenu", //Shared CSS class name of contents group
revealtype: "click", //Reveal content when user clicks or onmouseover the header? Valid value: "click", "clickgo", or "mouseover"
mouseoverdelay: 200, //if revealtype="mouseover", set delay in milliseconds before header expands onMouseover
collapseprev: true, //Collapse previous content (so only one open at any time)? true/false
defaultexpanded: [], //index of content(s) open by default [index1, index2, etc] [] denotes no content
onemustopen: false, //Specify whether at least one header should be open always (so never all headers closed)
animatedefault: false, //Should contents open by default be animated into view?
persiststate: true, //persist state of opened contents within browser session?
toggleclass: ["", ""], //Two CSS classes to be applied to the header when it's collapsed and expanded, respectively ["class1", "class2"]
togglehtml: ["suffix", "<img src='http://www.yoursite.com/images/plus.png' class='statusicon' />", "<img src='http://www.yoursite.com/images/minus.png' class='statusicon' />"], //Additional HTML added to the header when it's collapsed and expanded, respectively ["position", "html1", "html2"] (see docs)
animatespeed: "fast", //speed of animation: integer in milliseconds (ie: 200), or keywords "fast", "normal", or "slow"
oninit:function(headers, expandedindices){ //custom code to run when headers have initalized
//do nothing
},
onopenclose:function(header, index, state, isuseractivated){ //custom code to run whenever a header is opened or closed
//do nothing
}
})

</script>

Step 3 - The Javascript File

Cut & Paste the text from the table cell row below into a simple text file and save it as ddaccordion.js

You do not have to do anything to the code. Simply ensure your YourWebPage.html file has the correct path to the script <script type="text/javascript" src="http://www.yoursite.com.ddaccordion.js">

//Accordion Content script: By Dynamic Drive, at http://www.dynamicdrive.com
//Created: Jan 7th, 08'
//Version 1.3: April 3rd, 08':
//**1) Script now no longer conflicts with other JS frameworks
//**2) Adds custom oninit() and onopenclose() event handlers that fire when Accordion Content instance has initialized, plus whenever a header is opened/closed
//**3) Adds support for expanding header(s) using the URL parameter (ie: http://mysite.com/accordion.htm?headerclass=0,1)

//April 9th, 08': Fixed "defaultexpanded" setting not working when page first loads

//Version 1.4: June 4th, 08':
//**1) Added option to activate a header "mouseover" instead of the default "click"
//**2) Bug persistence not working when used with jquery 1.2.6

//Version 1.5: June 20th, 08':
//**1) Adds new "onemustopen:true/false" parameter, which lets you set whether at least one header should be open at all times (so never all closed).
//**2) Changed cookie path to site wide for persistence feature
//**3) Fixed bug so "expandedindices" parameter in oninit(headers, expandedindices) returns empty array [] instead of [-1] when no expanded headers found

//Version 1.5.1: June 27th, 08': Fixed "defaultexpanded" setting not working properly when used with jquery 1.2.6

var ddaccordion={

contentclassname:{}, //object to store corresponding contentclass name based on headerclass

expandone:function(headerclass, selected){ //PUBLIC function to expand a particular header
this.toggleone(headerclass, selected, "expand")
},

collapseone:function(headerclass, selected){ //PUBLIC function to collapse a particular header
this.toggleone(headerclass, selected, "collapse")
},

expandall:function(headerclass){ //PUBLIC function to expand all headers based on their shared CSS classname
var $=jQuery
var $headers=$('.'+headerclass)
$('.'+this.contentclassname[headerclass]+':hidden').each(function(){
$headers.eq(parseInt($(this).attr('contentindex'))).trigger("evt_accordion")
})
},

collapseall:function(headerclass){ //PUBLIC function to collapse all headers based on their shared CSS classname
var $=jQuery
var $headers=$('.'+headerclass)
$('.'+this.contentclassname[headerclass]+':visible').each(function(){
$headers.eq(parseInt($(this).attr('contentindex'))).trigger("evt_accordion")
})
},

toggleone:function(headerclass, selected, optstate){ //PUBLIC function to expand/ collapse a particular header
var $=jQuery
var $targetHeader=$('.'+headerclass).eq(selected)
var $subcontent=$('.'+this.contentclassname[headerclass]).eq(selected)
if (typeof optstate=="undefined" || optstate=="expand" && $subcontent.is(":hidden") || optstate=="collapse" && $subcontent.is(":visible"))
$targetHeader.trigger("evt_accordion")
},

expandit:function($targetHeader, $targetContent, config, useractivated){
$targetContent.slideDown(config.animatespeed, function(){config.onopenclose($targetHeader.get(0), parseInt($targetHeader.attr('headerindex')), $targetContent.css('display'), useractivated)})
this.transformHeader($targetHeader, config, "expand")
},

collapseit:function($targetHeader, $targetContent, config, isuseractivated){
$targetContent.slideUp(config.animatespeed, function(){config.onopenclose($targetHeader.get(0), parseInt($targetHeader.attr('headerindex')), $targetContent.css('display'), isuseractivated)})
this.transformHeader($targetHeader, config, "collapse")
},

transformHeader:function($targetHeader, config, state){
$targetHeader.addClass((state=="expand")? config.cssclass.expand : config.cssclass.collapse) //alternate btw "expand" and "collapse" CSS classes
.removeClass((state=="expand")? config.cssclass.collapse : config.cssclass.expand)
if (config.htmlsetting.location=='src'){ //Change header image (assuming header is an image)?
$targetHeader=($targetHeader.is("img"))? $targetHeader : $targetHeader.find('img').eq(0) //Set target to either header itself, or first image within header
$targetHeader.attr('src', (state=="expand")? config.htmlsetting.expand : config.htmlsetting.collapse) //change header image
}
else if (config.htmlsetting.location=="prefix") //if change "prefix" HTML, locate dynamically added ".accordprefix" span tag and change it
$targetHeader.find('.accordprefix').html((state=="expand")? config.htmlsetting.expand : config.htmlsetting.collapse)
else if (config.htmlsetting.location=="suffix")
$targetHeader.find('.accordsuffix').html((state=="expand")? config.htmlsetting.expand : config.htmlsetting.collapse)
},

urlparamselect:function(headerclass){
var result=window.location.search.match(new RegExp(headerclass+"=((\\d+)(,(\\d+))*)", "i")) //check for "?headerclass=2,3,4" in URL
if (result!=null)
result=RegExp.$1.split(',')
return result //returns null, [index], or [index1,index2,etc], where index are the desired selected header indices
},

getCookie:function(Name){
var re=new RegExp(Name+"=[^;]+", "i") //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return null
},

setCookie:function(name, value){
document.cookie = name + "=" + value + "; path=/"
},

init:function(config){
document.write('<style type="text/css">\n')
document.write('.'+config.contentclass+'{display: none}\n') //generate CSS to hide contents
document.write('<\/style>')
jQuery(document).ready(function($){
ddaccordion.urlparamselect(config.headerclass)
var persistedheaders=ddaccordion.getCookie(config.headerclass)
ddaccordion.contentclassname[config.headerclass]=config.contentclass //remember contentclass name based on headerclass
config.cssclass={collapse: config.toggleclass[0], expand: config.toggleclass[1]} //store expand and contract CSS classes as object properties
config.revealtype=/^(click)|(mouseover)$/i.test(config.revealtype)? config.revealtype.replace(/mouseover/i, "mouseenter") : "click"
config.htmlsetting={location: config.togglehtml[0], collapse: config.togglehtml[1], expand: config.togglehtml[2]} //store HTML settings as object properties
config.oninit=(typeof config.oninit=="undefined")? function(){} : config.oninit //attach custom "oninit" event handler
config.onopenclose=(typeof config.onopenclose=="undefined")? function(){} : config.onopenclose //attach custom "onopenclose" event handler
var lastexpanded={} //object to hold reference to last expanded header and content (jquery objects)
var expandedindices=ddaccordion.urlparamselect(config.headerclass) || ((config.persiststate && persistedheaders!=null)? persistedheaders : config.defaultexpanded)
if (typeof expandedindices=='string') //test for string value (exception is config.defaultexpanded, which is an array)
expandedindices=expandedindices.replace(/c/ig, '').split(',') //transform string value to an array (ie: "c1,c2,c3" becomes [1,2,3]
var $subcontents=$('.'+config["contentclass"])
if (expandedindices.length==1 && expandedindices[0]=="-1") //check for expandedindices value of [-1], indicating persistence is on and no content expanded
expandedindices=[]
if (config["collapseprev"] && expandedindices.length>1) //only allow one content open?
expandedindices=[expandedindices.pop()] //return last array element as an array (for sake of jQuery.inArray())
if (config["onemustopen"] && expandedindices.length==0) //if at least one content should be open at all times and none are, open 1st header
expandedindices=[0]
$('.'+config["headerclass"]).each(function(index){ //loop through all headers
if (/(prefix)|(suffix)/i.test(config.htmlsetting.location) && $(this).html()!=""){ //add a SPAN element to header depending on user setting and if header is a container tag
$('<span class="accordprefix"></span>').prependTo(this)
$('<span class="accordsuffix"></span>').appendTo(this)
}
$(this).attr('headerindex', index+'h') //store position of this header relative to its peers
$subcontents.eq(index).attr('contentindex', index+'c') //store position of this content relative to its peers
var $subcontent=$subcontents.eq(index)
var needle=(typeof expandedindices[0]=="number")? index : index+'' //check for data type within expandedindices array- index should match that type
if (jQuery.inArray(needle, expandedindices)!=-1){ //check for headers that should be expanded automatically (convert index to string first)
if (config.animatedefault==false)
$subcontent.show()
ddaccordion.expandit($(this), $subcontent, config, false) //Last Boolean value sets 'isuseractivated' parameter
lastexpanded={$header:$(this), $content:$subcontent}
} //end check
else{
$subcontent.hide()
config.onopenclose($(this).get(0), parseInt($(this).attr('headerindex')), $subcontent.css('display'), false) //Last Boolean value sets 'isuseractivated' parameter
ddaccordion.transformHeader($(this), config, "collapse")
}
})
$('.'+config["headerclass"]).bind("evt_accordion", function(){ //assign custom event handler that expands/ contacts a header
var $subcontent=$subcontents.eq(parseInt($(this).attr('headerindex'))) //get subcontent that should be expanded/collapsed
if ($subcontent.css('display')=="none"){
ddaccordion.expandit($(this), $subcontent, config, true) //Last Boolean value sets 'isuseractivated' parameter
if (config["collapseprev"] && lastexpanded.$header && $(this).get(0)!=lastexpanded.$header.get(0)){ //collapse previous content?
ddaccordion.collapseit(lastexpanded.$header, lastexpanded.$content, config, true) //Last Boolean value sets 'isuseractivated' parameter
}
lastexpanded={$header:$(this), $content:$subcontent}
}
else{
ddaccordion.collapseit($(this), $subcontent, config, true) //Last Boolean value sets 'isuseractivated' parameter
}
})
$('.'+config["headerclass"]).bind(config.revealtype, function(){
if (config.revealtype=="mouseenter"){
ddaccordion.expandone(config["headerclass"], parseInt($(this).attr("headerindex")))
}
else{
$(this).trigger("evt_accordion")
return false //cancel default click behavior
}
})
config.oninit($('.'+config["headerclass"]).get(), expandedindices)
$(window).bind('unload', function(){ //clean up and persist on page unload
$('.'+config["headerclass"]).unbind()
var expandedindices=[]
$('.'+config["contentclass"]+":visible").each(function(index){ //get indices of expanded headers
expandedindices.push($(this).attr('contentindex'))
})
if (config.persiststate==true){ //persist state?
expandedindices=(expandedindices.length==0)? '-1c' : expandedindices //No contents expanded, indicate that with dummy '-1c' value?
ddaccordion.setCookie(config.headerclass, expandedindices)
}
})
})
}
}

Step 4 - The Cascading Style Sheet

Cut & Paste the text below into a simple text file program and name it glossymenu.css You will need to link to the images below. The style names have been highlighted in a bold black colour. You can play with the style sheet to see the varied effects you can obtain.

.glossymenu{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 16px;
font-style: normal;
line-height: 16px;
font-weight: normal;
font-variant: normal;
color: #CC9933;
text-decoration: none;
background-image: url(../images/25_25_dark.png);
background-repeat: repeat;
list-style-type: none;
}

.glossymenu a.menuitem{
color: #FFFFFF;
display: block;
position: relative; /*To help in the anchoring of the ".statusicon" icon image*/
width: auto;
padding-left: 10px;
text-decoration: none;
font-family: "Trebuchet MS";
font-size: 16px;
line-height: 16px;
font-weight: bold;
font-style: normal;
background-image: url(../images/50_75.png);
background-repeat: repeat-x;
padding-top: 25px;
padding-right: 0;
padding-bottom: 4px;
vertical-align: middle;
text-align: left;
background-position: left bottom;
}

.glossymenu a.menuitem:visited, .glossymenu .menuitem:active{
color: white;
font-family: "Trebuchet MS";
font-size: 16px;
line-height: 16px;
font-weight: bold;
}

.glossymenu a.menuitem .statusicon{ /*CSS for icon image that gets dynamically added to headers*/
position: absolute;
top: 5px;
right: 5px;
border: none;
}

.glossymenu a.menuitem:hover{
font-family: "Trebuchet MS";
font-size: 16px;
line-height: 16px;
font-weight: bold;
color: #330000;
}

.glossymenu div.submenu{ /*DIV that contains each sub menu*/
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color: #FFFFFF;
font-style: normal;
line-height: 13px;
font-weight: normal;
background-image: url(../images/btmGrad.png);
background-repeat: repeat-x;
background-position: left bottom;
list-style-type: none;
}

.glossymenu div.submenu ul{ /*UL of each sub menu*/
list-style-type: none;
margin: 0;
padding: 0;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
line-height: 13px;
color: #FFFFFF;
text-align: left;
vertical-align: middle;
}

.glossymenu div.submenu ul li{
background-image: url(../images/30_50.png);
background-repeat: repeat-x;
background-position: left bottom;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
line-height: 13px;
color: #FFFFFF;
font-weight: normal;
text-align: left;
vertical-align: middle;
padding: 5px;
list-style-type: none;
}

.glossymenu div.submenu ul li a{
color: #FFFFFF;
text-decoration: none;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-style: normal;
line-height: 13px;
font-weight: normal;
font-variant: normal;
}

.glossymenu div.submenu ul li a:hover{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
line-height: 13px;
color: #330000;
font-weight: normal;
list-style-type: none;
}.glossymenu div.submenu ul li img {
margin-right: 10px;
text-align: left;
vertical-align: middle;
margin-top: 5px;
margin-bottom: 5px;
margin-left: 0px;
}
.criteria {
font-family: "Trebuchet MS";
font-size: 14px;
font-style: italic;
line-height: 16px;
font-weight: normal;
color: #FFFFFF;
}
.glossymenu a.menuitem a:visited {
font-family: "Trebuchet MS";
font-size: 16px;
line-height: 16px;
font-weight: bold;
color: #FFFFFF;
}


Step 5 - Upload These Images and Files to Your Server.

You can replace the images below with your own versions.

Please note: This table uses the same image for the background.
I have coloured the table cell for you to view the image.

30_50.png
btmGrad.png
50_75.png
25_25_dark.png
plus.gif
minus.gif
ddaccordion.js
glossymenu.css
YourWebPage.html
30_50.png
btmGrad.png
50_75.png
25_25_dark.png
plus.gif
minus.gif
 
 
         
  Home | Site Map | Contact
Copyright © 2003-2010 GuyMercier.com, Inc. All rights reserved. | Last Updated: September 11, 2010
Return to Top of Page