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"> Page1</div></h3>
<div class="toggle-container">
On page2:
<h3 class="trigger2"><div id="toggle-image2"> 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 Answer 1
- Don't rely on IDs when your cases are general. Rely on classes.
- 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">
Page1
</div>
</h3>
<div class="toggle-container">
</div>
</div>
page2 (same changes):
<div>
<h3 class="trigger">
<div id="toggle-image2" class="toggle-image">
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;
});
});
-
\$\begingroup\$ 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 . \$\endgroup\$Echo– Echo2011年09月18日 17:54:20 +00:00Commented Sep 18, 2011 at 17:54
-
\$\begingroup\$ Small Update this approach displays sign but it doesn't change whenever I click on the accordion ..It always"+" \$\endgroup\$Echo– Echo2011年09月18日 18:03:18 +00:00Commented Sep 18, 2011 at 18:03
-
\$\begingroup\$ 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. \$\endgroup\$Jonathan Wilson– Jonathan Wilson2011年09月18日 18:06:18 +00:00Commented Sep 18, 2011 at 18:06
-
\$\begingroup\$ Actually, you should display the +/- images based on wether your
div.toggle-image
also has one of these classes:toggle-image-collapse
ortoggle-image-expand
\$\endgroup\$Jonathan Wilson– Jonathan Wilson2011年09月18日 18:08:55 +00:00Commented Sep 18, 2011 at 18:08 -
\$\begingroup\$ and change
$('.toggle-image').attr("class", "toggle-image-expand");
to$('.toggle-image').addClass("toggle-image-expand");
\$\endgroup\$Jonathan Wilson– Jonathan Wilson2011年09月18日 18:09:33 +00:00Commented Sep 18, 2011 at 18:09