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');
});
Related
I have a long page, where one section is tabbed content. However, at the same time as showing tabs, I'd like for other sections further down the page to be visible or hidden, depending on which tab is clicked. Since each tab would display about 4 containers further down the page, I'd like to use classes for this rather than ID's. This is a rough outline of what I have so far (tab content removed, as it's unnecessary):
<div class="horisontal-tabs">
<ul class="tabs">
<li class="tab-label active person-sam" rel="tab1">Sam</li>
<li class="tab-label person-bob" rel="tab2">Bob</li>
<li class="tab-label person-jack" rel="tab3">Jack</li>
<li class="tab-label person-kelly" rel="tab4">Kelly</li>
</ul>
</div>
<div class="container-sam section-visible">Custom content only for Sam</div>
<div class="container-bob section-hidden">Custom content only for Bob</div>
<div class="container-jack section-hidden">Custom content only for Jack</div>
<div class="container-kelly section-hidden">Custom content only for Kelly</div>
<div class="container-sam section-visible">Other content for Sam</div>
<div class="container-bob section-hidden">Other content for Bob</div>
<div class="container-jack section-hidden">Other content for Jack</div>
<div class="container-kelly section-hidden">Other content for Kelly</div>
And I have jquery as per below for each person, but it doesn't seem to be working, and I can't figure out how to simplify it down. The idea is that when you click on one person's tab, all the other people's sections will be hidden and that person's will be visible.
$('.horizontal-tabs ul.tabs li.person-sam').click(function (event) {
$('.container-sam').removeClass('section-hidden').addClass('section-visible');
$('.container-sam.section-visible').removeClass('section-visible').addClass('section-hidden');
event.stopPropagation();
});
I have opted to not use ID on the sections and use a class instead, because multiple will need to show at once, so they wouldn't be unique.
Any tips will be greatly appreciated! :)
So the question is how to make simpler?
What comes to mind is you don't need active and inactive classes, you just need one of them, and then you can make the other be the default state . That is, add a default class .section to all sections and either use .section as the visible state and add .section-hidden to hide it, or use .section as the hidden state and add .section-visible to show it.
Say you go with .section-visible, the css would be something like this:
.section { display: none }
.section.section-visible { display: block }
This would also simplify your javascript because now you can reset all sections and just turn on/off the ones you need.
If you go, again, with .section-visible, run this on click:
$('.section').removeClass('section-visible'); // reset all sections
$('.container-sam').addClass('section-visible'); // add visible class to specific sections
You can see you only need one extra class, not two.
BONUS 1: you can use BEM to make it clearer.
BONUS 2: it looks like you have one click listener for each person, but instead you can use the HTML dataset API and the jQuery .data() function to detect which person's button you're pressing. That way you would have only one click listener, and you can detect which li was clicked by checking the data- attribute. Like <li data-person="sam">sam</li> and const containerSelector = `.container-${$(this).data('person')}`;. $(this) will select the li clicked, and .data('person') will return 'sam'. So the selector will be .container-sam.
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');
}
});
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;
});
I'm a newbie so i hope my question will have some logic :)
i wish to add a class "active" to "li" (in this case a portfolio filter item in the page) by clicking on a link from the nav menu.
the "li" is not a part of the nav menu, how do i assign a "li" with a class if the "li" is in the deep tree - it's a whole different part of my site.
the "li" is in:
<div class=""section"
<ul id="portfolio-filter" class="list-inline">
<li <--- the place i wish the "active" be added
i have checked other question but couldn't figure out how to implement the specific need.
thanks for the help
You have to create a listener for the link of the menu. In JQuery, to create a listener, you have the 'on' function.
Example :
$("myElement").on("click",function(){});
After that, add an id attribute for the 'li' tag.
For example:
<li id="myLI">
So, when the user will click on the link of the menu, it will go to the listener. And in the listener, you will do :
$("#myLI").addClass("active")
Don't forget to create the css class.
First you have to specify .active in your CSS.
.active {
//add styles here
}
Then using javascript you have to grab #myLI and set class .active to it using onclick event:
var element = document.getElementById("myLI");
element.onclick = function() {
element.setAttribute('class','active');
}
I have 5 a link items in a row, encapsulated within a h4 and the h4 within li element and the li within ul which it's finally nested in a nav element.
At the moment, the role of a (thanks to a very helpful example that I found here) when clicked is to change the content of the divs (that contain images and text).
What I would like to do in addition, is that when you click the link and the content changes, I would like a link to receive the "active" class, which has white color and certain other css attributes.
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
the function that swaps the content
<nav id="nav2">
<ul class="tabz">
<li><h4>Szenario 1</h4></li>
<li><h4>Szenario 2</h4></li>
<li><h4>Szenario 3</h4></li>
<li><h4>Szenario 4</h4></li>
<li><h4>Szenario 5</h4></li>
</ul>
</nav>
When the page loads, everything displays correctly. When I click the second link I would like the "active" class to be removed from first link and go to the sencond.
(The css of the active class is just some color and border differences.)
Thank you very much in advance.
Attach handler for those anchor tags by using the attribute starts with selector, since you are having href with same beginning. And by using the $(this) reference set the active class and remove the active class from all of its anchor siblings.
Try,
$('[href^="#tabs"]').click(function(){
$(this).addClass('active');
$(this).closest('.tabz').find('a').not($(this)).removeClass('active');
});
$('[href^="#tabs"]').click(function(e){
$(this).addClass('active').parents('li').siblings().find('a').removeClass('active');
});
With the markup you have, the clicked a element won't have any sibling, but its li parent will, so this code will work as expected, see here : DEMO