Jquery Accordion Automatic close - javascript

I'm working on creating a mobile accordion nav for a website. I have a basic accordion set up, the problem I am having is when I open one tab I want the other tabs to automatically close so only one tab can be opened at once. Here is the code
$(document).ready(function() {
// Collapsible Menu
function accordion(trigger) {
//variables
var $button = $(trigger),//trigger firing the event
visible = true;//flag for wayfinding
$button.hover().css({'cursor': 'pointer'});
//event
$button.click(function() {
//conditional check
if ( ! visible ) {
$button.removeClass('active');
$('.panel-title .icon').html('⊕');
$(this).next().slideUp('slow',function() {
$(this).addClass('visuallyhidden').slideDown(0);
$('.panel-content').attr( 'aria-expanded','false' );
});
}else {
$button.addClass('active');
$('.panel-title.active .icon').html('⊗');
$(this).next().slideUp(0,function() {
$('.panel-content').attr( 'aria-expanded','true' );
$(this).removeClass('visuallyhidden').slideDown('slow');
});
}
//flag dude
visible = !visible;
return false
});
}
//call to widget trigger1
accordion('#trigger1');
//call to widget trigger2
accordion('#trigger2');
//call to widget trigger3
accordion('#trigger3');
Codepen link - http://codepen.io/Ahhmmogh/pen/WvMMZN
Any help would be greatly appreciated.

Here's a working codepen: http://codepen.io/alezuc/pen/OVQvMV
I've added a check on panel's visibility and on 'active' title
if ( $(this).find('.panel-content').css('display') == 'none' ) {...}
if ( $(this).hasClass('active') ) {...}

Related

jQuery conditional header class swap

Hope someone can help me out since I don't really know js and would like to build upon an existing function on a WP site...
I have two versions of a site header. On the homepage the alt (transparent background) version loads, and after scrolling, it swaps to the sitewide non-alt (white bg) version.
I would like to add a condition where the header also swaps to the non-alt version when the the menu button is "toggled" (class="main-navigation toggled").
Here's the existing function. Thanks is advance.
jQuery(document).ready(function ($) {
console.log('ready');
var header = $(".site-header");
if( $("body.home").length ) {
header.addClass("site-header-alt");
}
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if( $("body.home").length ) {
if (scroll <= 100) {
header.addClass("site-header-alt");
} else {
header.removeClass("site-header-alt");
}
}
});
});
Just simply put:
$(document).ready(function () {
// check if .main-navigation contains toggled class
if ( $(".main-navigation").hasClass("toggled") )
{
header.addClass("site-header-alt");
}
// Also listen to the click event of the element that does the toggling.
$(".menu-toggle").click( function () {
if ( $(".main-navigation").hasClass("toggled") )
{
header.addClass("site-header-alt");
}
});
// other stuffs
});
hope that helps

Div toggle on checkbox but detect click when outside of the div to toggle off

I'm trying to make my burger menu detect click when outside of the menu (.NavMenu) and change the hamburger checkbox back to unselected.
I've tried using event.stopPropagation(); and trying to detect clicks in the document but my javascript knowledge is really limited so I am either not being able to show .NavMenu at all or .NavMenu closes when clicked outside but the hamburger menu stays as if it was open (X).
Can anyone help me with how to get the menu to close when clicked outside of the div that will also trigger the checkbox?
http://jsfiddle.net/s9ndequ2/
Add id 'burgerMenu' on div with class='NavMenu'.
And modify your JavaScript as
$('#burger').click(function() {
if( $(this).is(':checked')) {
$(".NavMenu").show();
} else {
$(".NavMenu").hide();
}
});
$('body').click(function(event){
removeBurger(event)
})
//this detects that user has clicked outside the menu
function removeBurger(e){
var targ;
if (!e) {
var e = window.event;
}
if (e.target) {
targ=e.target;
} else if (e.srcElement) {
targ=e.srcElement;
}
if(targ.id!="burgerMenu" && targ.id!="burger"){
if ( $('#burger').is(':checked')) {
$(".NavMenu").hide();
$( "#burger" ).prop( "checked", false );
}
}
}
Hope this will help.
You can achieve that by giving some id or class to the main div which will holding your page contents and then in script you can detect whether click has been performed inside that div or not :
Considering your main div has class mainDiv you can add below snippet to your script to achieve what you have asked for :
$(".mainDiv").click(function(){
if($('#burger').is(':checked'))
$('#burger').click();
});
Try this at your fiddle:
$('#burger').click(function(event) {
event.stopPropagation();
if( $(this).is(':checked')) {
$(".NavMenu").show();
} else {
$(".NavMenu").hide();
}
});
$('body').click(function() {
if ( $('#burger').is(':checked')) {
$(".NavMenu").hide();
$( "#burger" ).prop( "checked", false );
}
})
$('.NavMenu').click(function(event) {
event.stopPropagation();
})
http://jsfiddle.net/s9ndequ2/2/

Accordion open/close all content button and more

I have a responsive accordion function inside a website and i want to (open) and (close) all content with one button that also change his content name to (open) when all content is closed and (closed) when all content is open.
Also now the content that already was opened closes again when using the (open) button and the plus and minus icons don't react the right way showing the (minus icon) when the content is closed and visa versa.
Here is the fiddle
Can someone help me with this?
// Accordion //
$('.header').click(function(){
$('.content',$(this).parent()).slideToggle();
$(this).toggleClass('active');
})
$('.toggle-btn').click(function(){
$('.content').slideToggle();
$(this).toggleClass('active');
})
There you go:
http://jsfiddle.net/w3srayj6/21/
// Accordion //
$(document).ready(function() {
$('.header').click(function(){
$('.content',$(this).parent()).slideToggle();
$(this).toggleClass('active');
$('.toggle-btn').addClass('active').trigger("change");
})
});
$(document).ready(function() {
$('.toggle-btn').change(function(){
var headers = $('.header');
var state = 'open';
$.each(headers,function(){
if($(this).hasClass('active'))
state = 'close';
});
if(state == 'open')
$(this).addClass('active')
$(this).text(state);
});
$('.toggle-btn').click(function(){
var current = $(this);
current.toggleClass('active');
current.trigger("change");
var contents = $('.content');
$.each(contents, function(){
if(!current.hasClass('active'))
$(this).slideUp();
else
$(this).slideDown();
});
var headers = $('.header');
$.each(headers, function(){
if(current.hasClass('active'))
$(this).addClass('active');
else
$(this).removeClass('active');
});
current.trigger("change");
})
});
// Read more //
$(window).scroll(function() {
if ($(this).scrollTop() < 20) {
$('.read-more').slideDown(200);
} else {
console.log('there');
$('.read-more').slideUp(200);
}
});
Sometimes working with toggles may be a bit tricky and confusing.
In this case I used "hasClass" in order to determine if items are already open or not.
Since we have only "opened" and "closed" states, we can say that as long that "open" is not "Active" (has class active on it), we should add the "active" class flag to all headers and contents. same in the opposite situation.
this makes sure that already toggled items are not re-toggled.
To change your minus/plus icone with your button, you must select specific .header class with parent() and child() jQuery method like this :
$('.toggle-btn').click(function(){
$('.content').each( function() {
$(this).slideToggle();
$(this).parent().find('.header').toggleClass('active');
});
});
If you check for the class active after the toggle occurs, you can then change the text of the button depending on if the toggled class is active or not.
See this updated fiddle (edited to change the icons also)

sidemenu submenu's limit to 1 open submenu at the time with jquery

I have a sidebar with a few submenu's. I want only one submenu to be active at the time. So if a submenu is active and you select an other submenu the first one needs to close.
this is my jquery so far:
$('.sb-toggle-submenu').off('click').on('click', function () {
$submenu = $(this).parent().children('.sb-submenu');
$(this).add($submenu).toggleClass('sb-submenu-active');
if ($submenu.hasClass('sb-submenu-active')) {
$submenu.slideDown(200);
} else {
$submenu.slideUp(200);
}
});
Also have a JSFiddle
I home someone can fix this for me. I'm new to jquery an javascript but trying to learn.
http://jsfiddle.net/r3fSC/8/
Here you go
$('.sb-toggle-submenu').off('click').on('click', function () {
console.log($('.sb-submenu-active'));
if ($(this).is('.sb-submenu-active')) {
$(this).removeClass('sb-submenu-active').parent().children('.sb-submenu').slideUp(200);
} else {
$('.sb-submenu-active').removeClass('sb-submenu-active').parent().children('.sb-submenu').slideUp(200);
$(this).addClass('sb-submenu-active').parent().children('.sb-submenu').slideDown(200);
}
});
Fiddle: http://jsfiddle.net/s3ag4/
$('.sb-toggle-submenu').off('click').on('click', function () {
var $button = $(this);
var $submenu = $button.next( '.sb-submenu' );
$button.toggleClass('sb-submenu-active');
// Detect and close other menus
$( '.sb-submenu-active' )
.not( $button )
.removeClass('sb-submenu-active')
.next( '.sb-submenu' )
.slideUp(200);
if ( $button.hasClass('sb-submenu-active') ) {
$submenu.slideDown(200);
} else {
$submenu.slideUp(200);
}
});

Set accordion default to collapsed

There's a fiddle here.
I'm trying to have the panels collapsed on default by adding...
$container.active(false);
And it does collapse the panels, but then it also disrupts other jquery plugins on the page.
Here's the full script:
(function() {
var $container = $('.acc-container'),
$trigger = $('.acc-trigger');
$container.hide();
$container.active(false);
$trigger.first().addClass('active').next().show();
var fullWidth = $container.outerWidth(true);
$trigger.css('width', fullWidth);
$container.css('width', fullWidth);
$trigger.on('click', function(e) {
if( $(this).next().is(':hidden') ) {
$trigger.removeClass('active').next().slideUp(300);
$(this).toggleClass('active').next().slideDown(300);
}
e.preventDefault();
});
// Resize
$(window).on('resize', function() {
fullWidth = $container.outerWidth(true)
$trigger.css('width', $trigger.parent().width() );
$container.css('width', $container.parent().width() );
});
})();
Where did I go wrong?
Let's write some negative code. Remove your fix attempt, it was causing an error, thats why all other scripts stopped working.
$container.active(false);
Then remove the next line. Here first item of the accordion was expanded:
$trigger.first().addClass('active').next().show();

Categories