Add active state to simple jQuery accordion - javascript

I've got this simple accordion jQuery script that's almost there with what I need it for, but I'm struggling with one last thing. The animated bits work fine - i.e. if the corresponding content block is closed, it slides open, and vice versa.
Here's the jQuery code:
$('.accordion-heading').click(function(){
$(this).next().slideToggle(300);
$('.accordion-content').not($(this).next()).slideUp(300);
$('.accordion-heading.active').removeClass('active');
$(this).addClass('active');
});
I want to have an 'active' class on the heading, but I need it to be removed if the same element is clicked twice. At the moment, everything works fine if a non-active heading is clicked. If an already-active heading is clicked again, however, the content block collapses correctly but the heading retains its 'active' class.

All you need to do is remove the .active class from elements that aren't the current element (you can use the same $.not() method you are currently on another element), then $.toggleClass() the .active class on the clicked element.
$('.accordion-heading').click(function(){
$(this).next().slideToggle(300);
$('.accordion-content').not($(this).next()).slideUp(300);
$(this).toggleClass('active');
$('.accordion-heading').not($(this)).removeClass('active');
});
.accordion-content {
display: none;
}
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="accordion">
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
</div>

Instead of Adding the class and removing the class I suggest using .toggleClass() this way if the element has the class it will remove it and if it doesn't it will add it. If you want to have one of the accordions open manually give it the active class, and let your JS do the rest.

You could use 'toggleClass()' but I find its better to be more specific by checking if the item that was clicked has the class active. This way you can branch out and do other functions depending on the state:
$('.accordion-heading').click(function(){
var theHeading = $(this);
var theContent = theHeading.next();
var slideTimer = 300;
if(theHeading.hasClass('active')) {
$('.accordion-heading.active').removeClass('active').next().slideUp(slideTimer);
theContent.slideDown(slideTimer);
$(this).addClass('active');
} else {
theContent.slideUp(slideTimer);
$(this).removeClass('active');
}
});

Related

Insert div id into script

I have a script where clicking on a particular div (eg id=packtoa) will (amongst other things) .addclass('show') to listview items with a class which matches the id of the div clicked.
Which works great, but then I'll want the next div (id=packfhag) to do the same thing, and then the next one. So I've got the same script many times in my js with just the id & class name changed.
I'm sure there's a stupidly obvious way to automate this so that any div with an id starting with "pack" will trigger this script, pull the div id, and insert it into the script where the name of the class is called.
And I'm sure I'm close with trying to adapt this script:
$("div[id^=pack]").each(function() {
var match = this.id.match(/\w+$/)[0];
$(this).addClass('show');
});
But I just can't crack it. Either something above is wrong, or I'm inserting it into the wrong place in the script:
// Tears of Ameratsu menu functions
$(document).bind('pageinit', function() {
// When link is clicked
$('#packtoa').click(function() {
// collapse the expansions menu
$("#expansionsmenu").click();
// hide everything except this expansion
$(".hidden").removeClass('show');
$(".packtoa").addClass('show');
// clear the search, and trigger a blank search
$('input[data-type="search"]').val('');
$('input[data-type="search"]').trigger("keyup");
});
});
What am I missing?
// for selecting div which starts with pack
// not recommended
$("div[id^='pack']");
The best option is to use class attribute, add class attribute to all those div, and then
$('.commonClass').addClass('show');
For Example :
// this is for testing
// say you click
$('#test').on('click',function(){
$('.testclass').addClass('show');
});
.testclass{
display:none;
}
.show {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="testclass">div1</div>
<div class="testclass">div2</div>
<div class="testclass">div3</div>
<input type='button' value='Click me to view div' id='test' />

Toggle class on child elements (and remove siblings)

I have the below code, being used to create an accordion effect by toggling an .active class. Upon click of .section-header, I am toggling a class on both the header and the .section-content. This is working well.
However, as mentioned, this is to create an accordion effect, which is amde up of multiple .accordion-section <div> tags. I need to adjust the jquery in order to remove all .active classes from every .accordion-section other than the one that is currently active. At the moment, the clicking of .section-header toggles an .active class on ALL .section-content <div> tags.
Thanks.
HTML
<div class="accordion-section">
<a class="section-header">
<h3>Title</h3>
</a>
<div class="section-content">
<div>Content</div>
</div>
</div>
JS
$('.accordion-section .section-header').click(function(){
$(this).toggleClass('active');
$(this).siblings().toggleClass('active');
});
$('.accordion-section .section-header').click(function(){
// Check to see the initial state of the element
var isActive = $(this).hasClass('active');
// first remove the active class from all other section headers within this accordion section
$('.accordion-section')
.find('.section-header, .section-content')
.removeClass('active');
// Get the header and content for this section
var sectionHeaderAndContent = $(this)
.closest('.accordion-section')
.find('.section-header, .section-content');
// Toggle Active State: Set final active state based on state when clicked
(isActive) ? sectionHeaderAndContent.removeClass('active'): sectionHeaderAndContent.addClass('active');
});

addClass/removeClass based on selected items data attribute

I'm a little stuck here. I have a ul menu of links. When a user selects from this list, I'm calling up content from another page with ajax. I want to grab a data attribute (data-flag) from the selected anchor and add that attribute as a class to the div that holds the ajax content (#fourteen). The adding class piece is working fine. However, when a new item is selected from the ul menu, I can't seem to remove the other classes from the content div. With each click, it just adds more classes.
Here's my code.
<ul id="langtest" class="tp_lang2">
<li>English</li>
<li>中文(简体)</li>
<li>Nederlands</li>
<li>Français</li>
</ul>
<div id="fourteen" class="cn">
<div id="content">
<div class="main-content">Content being served up here.
</div>
</div>
</div>
<script>
jQuery("ul#langtest li a").click(function() {
jQuery('#fourteen').load($(this).attr("href") + " #content");
jQuery('#fourteen').removeClass.not(this).attr("data-flag");
jQuery('#fourteen').addClass($(this).attr("data-flag"));
return false;
});
</script>
You just need to remove all class in the element like so :
// remove all class
jQuery('#fourteen').removeClass();
// then add class name with data flag selected anchor only
jQuery('#fourteen').addClass($(this).attr("data-flag"));
DEMO(inspect element to see the class actually added & removed)
Your removeClass seems not perfect. Do it like below.
jQuery('#fourteen').removeClass();
On dynamically added element you have to use delegate event binding.
jQuery(document).on("click","ul#langtest li a",function() {
jQuery('#fourteen').load($(this).attr("href") + " #content");
//also change your removeClass code
jQuery('#fourteen').removeClass();
jQuery('#fourteen').addClass($(this).attr("data-flag"));
return false;
});

Remove a Div class that inside a parent Div with jQuery

I have a div on top of a image. I want use jQuery click event to remove (or change the div class) the div on image click.
Div structure.
<div class="post">
<img class="thumb" src="MyImg.jpg">
<div class="show-div"></div>
</div>
I want to toggle class show-div to remove-div.
Here is my jQuery
$(document).ready(function(){
$(".thumb").click( function(){
$(this).parent().('.show-div').toggleClass('remove-div');
});
});
I have made remove-div class to display none in the css style sheet. but this doesnt seems to work. Also i have tried
$(this).parent().find('.show-div').toggleClass('remove-div');
Please note that this is a PHP while loop and there will be more then one div at this page.
If someone can point me out the right way to do this it will be most appropriated.
Try this:
$(document).ready(function(){
$(".thumb").click( function(){
$(this).parent().find('div.show-div').removeClass('show-div').addClass('remove-div');
});
});
The code given works http://jsfiddle.net/4WDet
However, you're not removing .show-div, so if that is display: block AND your CSS rules are in this order that is your problem.
.remove-div{
display:none;
}
.show-div{
display:block;
}
In which case, switch your CSS styles around
.show-div{
display:block;
}
.remove-div{
display:none;
}
or toggle both classes
$(this).parent().find('.show-div').toggleClass('remove-div show-div');
But the problem then is that you won't find that div again, so you need to change the selector:
$(this).parent().find('.show-div, .remove-div').toggleClass('remove-div show-div');
Working example
.show-div is not a parent of .thumb, but a sibling. Have you tried?
$(this).siblings('.show-div').toggleClass('remove-div');
Note, that this will return an array if there are more than one .show-div sibling.
$(this).siblings().toggle("slow");
try this

adding and removing the selected class to a parent div

OK so now I have my sliding open ul revealing all the list elements, and now I want the title bar that is clicked on to have a state of selected added to it, and then remove that state when it's closed...
the div above the UL has a class of .regionHeader
here's an example of the mark up
<div class="regionHeader">title of the region</div>
<ul class="region"><li>the region i'm hiding/showing</li></ul>
here's the javascript
var stockists = {
start: function() {
$('.region').hide();
$('.regionTitle').each(function(){
$(this).click(function(e){
e.preventDefault();
$(this).parent().next('.region').slideToggle(300);
});
});
}
};
$(stockists.start);
I've been trying addClass but it seems to just add the class and not remove it?
Can you not use toggleClass()
This way the class will be added/removed when you need it to be.
$(this).parent().toggleClass("className");
$(this).parent().next('.region').slideToggle(300);
$(this).parent().toggleClass('activeTitle'); // toggling the class on the parent
$(this).parent().next('.region').slideToggle(300);
to remove a class from an element you have to use removeClass
$(element).removeClass("classname");

Categories