# Multiple Accordion on one page

I have two accordions on the same page

First, I have a page, Freemarker, that includes two other Freemarkers that have the accordion.

[#include "page1.ftl"]
[#include "page2.ftl"]


On page1:

<h3 class="trigger"><div id="toggle-image">&nbsp;&nbsp;&nbsp;&nbsp;Page1</div></h3>
<div class="toggle-container">


On page2:

<h3 class="trigger2"><div id="toggle-image2">&nbsp;&nbsp;&nbsp;&nbsp;Page2</div></h3>
<div class="toggle-container2">


In the Javascript file:

$(document).ready(function(){$('#toggle-image').attr("class", "toggle-image-expand");
//Hide (Collapse) the toggle containers on load
$(".toggle-container").hide();$("h3.trigger").click(function(){
$(this).toggleClass("active").next().slideToggle("slow"); if($('#toggle-image').attr("class") == "toggle-image-collapse") {
$('#toggle-image').attr("class", "toggle-image-expand"); } else {$('#toggle-image').attr("class", "toggle-image-collapse");
}
return false;
});
});

$(document).ready(function(){$('#toggle-image2').attr("class", "toggle-image-expand");
//Hide (Collapse) the toggle containers on load
$(".toggle-container2").hide();$("h3.trigger2").click(function(){
$(this).toggleClass("active").next().slideToggle("slow"); if($('#toggle-image2').attr("class") == "toggle-image-collapse") {
$('#toggle-image2').attr("class", "toggle-image-expand"); } else {$('#toggle-image2').attr("class", "toggle-image-collapse");
}
return false;
});


It works fine, but the redundant code I used in JS is typical and the difference is on the variable it uses. How could I make it dynamic?

1. Don't rely on IDs when your cases are general. Rely on classes.
2. Use the DOM hierarchy to reference elements

page1 (added a container div, "toggle-image" class name):

<div>
<h3 class="trigger">
<div id="toggle-image" class="toggle-image">
&nbsp;&nbsp;&nbsp;&nbsp;Page1
</div>
</h3>
<div class="toggle-container">
</div>
</div>


page2 (same changes):

<div>
<h3 class="trigger">
<div id="toggle-image2" class="toggle-image">
&nbsp;&nbsp;&nbsp;&nbsp;Page2
</div>
</h3>
<div class="toggle-container">
</div>
</div>


JavaScript (generalized with class selectors, sibling selectors, improved class logic):

 $(document).ready(function(){$('.toggle-image').attr("class", "toggle-image-expand");
//Hide (Collapse) the toggle containers on load
$(".toggle-container").hide();$("h3.trigger").click(function(){
$(this).toggleClass("active").next().slideToggle("slow");$(this).children('.toggle-image')
.toggleClass('toggle-image-collapse')
.toggleClass('toggle-image-expand');

return false;
});
});

• Actually the purpose of "toggle-image" to display "+" or "-" to indicate to be Expanded or collapsed respectively.This approach doesn't display the sign at all . It works fine for Accordion but I need the sign to be displayed as well . – Echo Sep 18 '11 at 17:54
• Small Update this approach displays sign but it doesn't change whenever I click on the accordion ..It always"+" – Echo Sep 18 '11 at 18:03
• There is no reason that this approach can't facilitate your image display. In your posted code, is the image displayed for .trigger2 different from the image displayed for .trigger1? If this is the case just add a second class to the divs in my code and then update your css to add the background image for elements that match the two classes. – Jonathan Wilson Sep 18 '11 at 18:06
• Actually, you should display the +/- images based on wether your div.toggle-image also has one of these classes: toggle-image-collapse or toggle-image-expand – Jonathan Wilson Sep 18 '11 at 18:08
• and change $('.toggle-image').attr("class", "toggle-image-expand"); to $('.toggle-image').addClass("toggle-image-expand"); – Jonathan Wilson Sep 18 '11 at 18:09