jquery toggle won't close on click - javascript

I have this code for an accordion style toggle. Works great, only problem is, if you click on an open accordion, it slides up then back down. It doesn't slide closed.
Any thoughts?
Thanks!
//toggles 2
$('body').on('click','.toggle h3 a', function(){
if($(this).parents('.toggles').hasClass('accordion')) return false;
$(this).parents('.toggles').find('.toggle > div').slideUp(300);
$(this).parents('.toggles').find('.toggle h3 a i').attr('class','icon-plus-sign');
$(this).parents('.toggles').find('.toggle').removeClass('open');
$(this).parents('.toggle').find('> div').slideDown(300);
$(this).parents('.toggle').addClass('open');
//switch icon
if( $(this).parents('.toggle').hasClass('open') ){
$(this).find('i').attr('class','icon-minus-sign');
} else {
$(this).find('i').attr('class','icon-plus-sign');
}
return false;
});
<div class="toggles">
<div class="toggle accent-color"><h3><i class="icon-minus-sign"></i>First Accord</h3>
<div>
Content
</div>
</div>
<div class="toggle accent-color"><h3><i class="icon-minus-sign"></i>Second Accord</h3>
<div>
Content
</div>
</div>

It's pretty simple why it does that. Your function always execute slideUp and slideDown. In that order. So when your div is collapsed, it will execute slideUp(which doesn't really make anything because it's already collapsed) and then it will slideDown. Now, when the div is expanded: The div will slideUp (this time it does go Up because it's not collapsed) and then it will go Down.
A better way to do it would be with SlideToggle.
http://api.jquery.com/slidetoggle/
EDIT: Also, you can check if the div is collapsed or not with...
if($(element).is(':visible')){
//expanded
} else {
//collapsed
}

Sorry I didn't really understand what was happening with your code so I rewrote the js part from scratch: http://jsfiddle.net/d503n47r/2/
$('body').on('click','.toggle h3 a', function(e){
e.preventDefault();
if($(this).parents('.toggles').hasClass('accordion')) return false;
if ($(this).parents('.toggle').find('div').eq(0).hasClass('open')) {
$(this).parents('.toggle').find('div').eq(0).removeClass('open').slideUp();
} else {
$('.toggle.open').removeClass('open');
$(this).parents('.toggle').find('div').eq(0).addClass('open').slideDown();
}
});
Please take a look at jquery UI as it helps a lot with all this common things http://jqueryui.com/ (No need to reinvent the wheel)

MinusFour was correct that it was firing both at the same time.
A way to remedy this is to do an if / then statement that checks whether or not it's open, and then fire's the open / close dependent on that.
Here's a link to a JSfiddle
I also added the class "toggle-panel" to the container that was sliding up / down, just so that following would be easier to read.
if($(this).closest('.toggle').hasClass('open')){
console.log('open');
$(this).parents('.toggle').find('.toggle-panel').slideUp(300);
$(this).closest('.toggle').removeClass('open');
return
}
else {
console.log('close');
$(this).parents('.toggles').find('.toggle h3 a i').attr('class','icon-plus-sign');
$(this).parents('.toggle').find('.toggle-panel').slideDown(300);
$(this).parents('.toggle').addClass('open');
}

Related

MegaMenu doesn't close submenu when open another menu item

I have a little problem with my MegaMenu, when i open a submenu (clicking on one item of main menu) i want that submenu to vanish when i click anywhere on the document body or if i choose other menu item, the the previous submenu has to close, if i click on that submenu ('ul'), or one particular item on submenu it works like i want (it closes), but if i click on other menu item the previous submenu keeps opened, creating layers of submenus that i have to click on to make them vanish (or click on the main menus item that make them appear) im not sure i am clear,
The function JS im using:
$(".menu > ul > li").click(function(e) {
if ($(window).width() > 943) {
$(this).children('ul').fadeToggle(15);
$(this).children('ul').toggleClass('center');
e.preventDefault();
}
});
so there's a fiddle of my code:
https://codepen.io/anon/pen/JpBrRp
Break, I believe i understood the problem.
First you have to check if the element wich you want to open is already open. If is open you will to close if not you will open.
$(".menu > ul > li").click(function(e) {
if ($(window).width() > 943) {
if ($(this).children('.menu-list').is(":visible")){
$(this).children('.menu-list').fadeToggle(15);
$(this).children('.menu-list').toggleClass('center');
e.preventDefault();
} else {
$('.menu-list').hide();
$('.menu-list').removeClass('center');
$(this).children('.menu-list').fadeToggle(15);
$(this).children('.menu-list').toggleClass('center');
e.preventDefault();
}
}
});
Then you need another function to verify if the user clicked in another place that was not the menu to close the submenu.
$("body").click(function(e) {
var target = e.target;
if (target.className.indexOf("menu-button") == -1 && target.offsetParent.className.indexOf("menu-button") == -1 ) {
$('.menu-list').hide();
$('.menu-list').removeClass('center');
return;
}
});
See if this help you:
https://codepen.io/beduardo/pen/zReyjj
Tip: I recommend avoid use, only tag to refer your elements in js. This can be a problem in the future.
Thank you my friend Bruno Eduardo, i believe you understand Portuguese!! Obrigado amigo!!
There's only one minor bug, it only work if you click on the button, if you click on image it doesn't work, to fix that you need to add menu-button to every tag inside your link.
ex:
<a role="button" class="button button4 **menu-button**"><i class="icon-crm fs1 icon **menu-button**"></i><span class="button-text rowcenter **menu-button**">{{'MenuItem1' | translate}}</span></a>
Thank you friend!
Yes, i understand portuguese =). This approach is good, an other way is improved the function wich verify if the user clicked in another place.
if (target.className.indexOf("menu-button") == -1 && target.offsetParent.className.indexOf("menu-button") == -1 )
Feel free to choose the better to you =)

How can I close my accordion in a normal slideUp behavior ?

I have an accordion.
If I click on View Report - it will expand like this
If I click Hide Details - it will be back to original state.
JS
$saReport.click(function() {
console.log('R');
$saReport.addClass('hidden'); //hide
$saHide.removeClass('hidden'); //show
});
$saHide.click(function() {
console.log('H');
$saHide.addClass('hidden');
$saReport.removeClass('hidden');
$('.panel-collapse').removeClass('in');
});
Result
My accordion is closing very quick, like flashing hide.
How can I close my accordion in a normal slideUp behavior ?
Any hints / helps / suggestions on that will be much appreciated.
It would be usefull if you could post some relevant html.
If you you desire a simple slide behaviour you could either use the bootstrap accordion which is quite well documented.
If you want to implement it yourself, you could simply use the jquery slideUp() and slideDown() methods, i.e.:
$saReport.click(function() {
console.log('R');
$saReport.addClass('hidden'); //hide
$saHide.removeClass('hidden'); //show
// slide down your report (show)
$('.your-report-container').slideDown(400);
});
$saHide.click(function() {
console.log('H');
$saHide.addClass('hidden');
$saReport.removeClass('hidden');
$('.panel-collapse').removeClass('in');
// slide up your report (hide)
$('.your-report-container').slideUp(400);
});
These slide methods allow you to pass a parameter, which is the time in ms for the animation. The default is 400.

jquery not resetting menu navigation trigger

Currently I have this script that allows a button to open and close a menu whilst also changing it's class to do a little animation state change depending on open/close,... simple but effective.....
$(document).ready(function () {
var $navToggle = $('.nav-toggle');
$(".navbtn").click(function () {
if($navToggle.hasClass('active')){
$('#menu').multilevelpushmenu('collapse');
$navToggle.removeClass('active');
$(this).addClass('active');
}
else{
$('#menu').multilevelpushmenu('expand');
$navToggle.addClass('active');
$(this).removeClass('active');
}
});
within the menu is a list with some options (standard) and when one is clicked it performs the following script based on its tag in the list... here's the html and js for that....
html
<li>
<i class="fa fa-briefcase"></i>Who are Musability?
</li>
JS
$('.fa-briefcase').parent().on('click', function () {
$("#colorscreen").remove();
$( '#menu' ).multilevelpushmenu( 'collapse' );
$("body").append('<div id="colorscreen" class="animated"></div>');
$("#colorscreen").addClass("fadeInUpBig");
$('.fadeInUpBig').css('background-color', 'rgba(13,135,22,0.1)');
$(".tile-area-main").css({width: "720px"}).load("content.html");
$('.nav-toggle').removeClass('active');
$(this).addClass('active');
});
all functions work great separately but when i introduce the functions for the button click fa-briefcase it wont allow me to open the menu again why is this ?
... on another note (therefore probably a new question at another time) this code is repetitive for all buttons and wonder if there is a way of standardizing the stuff that is repeated into one big function ? not sure about how i would go about it but it isn't the focus of this question , although any advice greatly recieved.
What does your content.html file contain?
Because if it contains other JavaScript it could be messing with it.
i.e.
Instead of $(".tile-area-main").load("content.html");
Try $(".tile-area-main").load("content.html#div");
Where #div is the div with the contents you want to load() in
EDIT: Just noticed your comments, seems like you've fixed it yourself, but glad my method worked :)

Scrolling effect on click on a image

I'm trying to make a scrolling effect to a menu. To be precise i want to click on a image and when i click it the menu to scroll down by 1 with a fade effect or what ever effect to the next link.
Ahhh...Like a windmill wheel if u understand what i mean.:)
And couldn't find any info.
Here is my code :
<div class=".img-fade"><img src="http://www.lahondafire.org/nest/Volunteer%20Manual/Signs%20and%20Forms/Arrow.gif" width="180" height="170"><BR>
When i click on the arrow the links below start scrolling down by 1 and contact to be top and about me to be to bottom...</div>
<div class="menu">
About me<BR>
Portofolio<Br>
Contact
</div>
http://jsfiddle.net/WCtQn/242/
So when i click on that arrow to move the links from top to bottom or bottom to top,dosen't matter.
Thank you.
You can try this method. It reorders the list elements when the arrow is clicked
$('.img-fade').click(function() {
var last = $('a')[0];
last.remove();
$('br')[0].remove();
$('.menu').append("<br> " + last['outerHTML']);
});
You should learn how to use javascript/jQuery and show us what you've tried so far and what you're having trouble with next time you post here
If you want something fancier you could look to do something similar to this example, though I'd add some .stop()s to remove some errors it has
I'm no jQuery pro but I've come up with something that is close to what you're looking for. I spiced it up with a fade effect. I also removed the <br> tags and set the links to display: block;. You could modify what I have to something similar to what #Zeaklous has posted to remove them along with the element and add them back in.
http://jsfiddle.net/WCtQn/248/
$('.img-fade').on('click', 'img', function(){
var firstItem = $('.menu a').first();
firstItem.fadeOut(2000, function() {
$(this).remove();
$('.menu').append(firstItem);
$('.menu a').last().fadeIn(2000);
});
});

jQuery toggle content-div from menubar

I'm having trouble getting jQuery to allow only one content-DIV to be visible at a time. So that clicking between the menu buttons (about, newsletter, contact) this will allow only one content-DIV to be visible.
--- Then the content-DIV needs to hide when the associated menu button is clicked (like it does currently).
--- Upon clicking the header 'alliteration', any content-DIVs that are open need to hide.
$('#collapse_about').hide();
$('#collapse_newsletter').hide();
$('#collapse_contact').hide();
$('#menu1').click(function() {
$('#collapse_about').slideToggle(400);
return false;
});
$('#menu2').click(function() {
$('#collapse_newsletter').slideToggle(400);
return false;
});
$('#menu3').click(function() {
$('#collapse_contact').slideToggle(400);
return false;
});
I understand that this is a pretty simple bit of code... but the form of it evades me. Any help is much appreciated.
Off the top of my head I would assign all of the menus the same class such as class1. Then make the div slideUp which has a callback function. When the slideUp is finished it will slide down the correct panel.
$('#menu1').click(function() {
$(".class1").slideUp(function() {
$('#collapse_about').slideDown(400);
});
});
$('#menu2').click(function() {
$(".class1").slideUp(function() {
$('#collapse_newsletter').slideDown(400);
});
});
$('#menu3').click(function() {
$(".class1").slideUp(function() {
$('#collapse_contact').slideDown(400);
});
});
Edit: This is a start but doesn't entirely do as you are asking:(
Here is the demo on jsfiddle: here

Categories