Jquery Expand Collapse all divs on Click - javascript

I know this has been asked a thousand times but I'm still having trouble figuring it out. I have a simple according following this tutorial and I'm trying to add an "expand/collapse all" link. I have found a way to expand all but can't figure out how to collapse them. The problem with a slideToggle() solution is if I open one then click the link it will close/open all of them but the one that was previoiusly active.
I set up a jsFiddle here.
Here is an overview of the code:
HTML:
<h2 class="acc_trigger">Div 1</h2>
<div class="acc_container">
<div class="block"> Yay content!</div>
</div>
<h2 class="acc_trigger">Div 2</h2>
<div class="acc_container">
<div class="block">More Content, Score!</div>
</div>
<h2 class="acc_trigger">Div 3</h2>
<div class="acc_container">
<div class="block">Even More Content</div>
</div>
Expand/Collapse All
JS:
jQuery(document).ready(function($) {
//Set default open/close settings
$('.acc_container').hide(); //Hide/close all containers
//On Click
$('.acc_trigger').click(function(){
$('.acc_trigger').removeClass('active').next().slideUp();
//Remove all "active" state and slide up the immediate next container
$(this).toggleClass('active').next().slideDown();
return false; //Prevent the browser jump to the link anchor
});
$('.acc_expand-all').click(function(){
//expand all on click
$('.acc_trigger').addClass('active').next().slideDown();
return false;
});
});

You have to check in your expand/collapse handler to see how many are open, etc., something like this (updated fiddle):
$('.acc_expand-all').click(function(){
var all = $('.acc_trigger'),
active = all.filter('.active');
if (all.length && all.length === active.length) {
// All open; close them
all.removeClass('active').next().slideUp();
}
else {
// At least some are closed, open all
all.not('.active').addClass('active').next().slideDown();
}
return false;
});
Regarding your question in the comments, you can check to see whether you should be in "exclusive" mode or not by checking how many are open and whether the clicked one is open, e.g. (updated fiddle):
$('.acc_trigger').click(function(){
var $this = $(this),
thisActive = $this.hasClass('active'),
active;
// If this one is active, we always just close it.
if (thisActive) {
$this.removeClass('active').next().slideUp();
}
else {
// Is there just one active?
active = $('.acc_trigger.active');
if (active.length === 1) {
// Yes, close it
active.removeClass('active').next().slideUp();
}
// Open this one
$this.addClass('active').next().slideDown();
}
});

Related

Link does not work on CSS/HTML template

I am using this template
https://codepen.io/candroo/pen/wKEwRL
But the link on button does not work. The close the animation without go to the page.
If I disable the js script the links works, so, I suspect that is something with the Js. script, but I could not find the error.
One card code:
<div class="card-flap flap1">
<div class="card-description">
This grid is an attempt to make something nice that works on touch devices. Ignoring hover states when they're not available etc.
</div>
<div class="card-flap flap2">
<div class="card-actions">
Read more
</div>
</div>
</div>
</div>
The JavaScript code:
$(document).ready(function(){
var zindex = 10;
$("div.card").click(function(e){
e.preventDefault();
var isShowing = false;
if ($(this).hasClass("show")) {
isShowing = true
}
if ($("div.cards").hasClass("showing")) {
// a card is already in view
$("div.card.show")
.removeClass("show");
if (isShowing) {
// this card was showing - reset the grid
$("div.cards")
.removeClass("showing");
} else {
// this card isn't showing - get in with it
$(this)
.css({zIndex: zindex})
.addClass("show");
}
zindex++;
} else {
// no cards in view
$("div.cards")
.addClass("showing");
$(this)
.css({zIndex:zindex})
.addClass("show");
zindex++;
}
});
});

Return the user to their original position on a page when they close navigation

I'm working with manipulating foundations off-canvas navigation to get it to do what I want and it's been causing quite a few issues. One main one I've noticed is that when I stick the header to the top of the page so it scrolls with me as I go down pages, when you open it it opens at the top of the page. So for that I added a .click(function) to get the page to scroll back to the top which can be found here:
jQuery:
jQuery('section.left-small a.menu-icon').click(function() {
var screenTop = jQuery(document).scrollTop();
jQuery('#content').css('top', screenTop);
//console.log(screenTop);
jQuery('body').scrollTop(0);
});
HTML:
<nav class="tab-bar">
<section class="left-small">
<a class="left-off-canvas-toggle menu-icon" href="#"><span></span></a>
</section>
<section class="middle tab-bar-section">
<h1 class="title uppercase">Island Company</h1>
<a href="/checkout/suitcase.html">
<img src="/media/island/suitcase.png" />
<span class="suitcase-item-count">(<?= $quote->getItemCount(); ?>)</span>
</a>
</section>
</nav>
So my question is how do I use the variable "screenTop" to get the page to return to it's stored original position within the body of the page when the user CLOSES the "a.left-off-canvas-toggle" menu?
Here is a working fiddle: http://jsfiddle.net/CMbBC/18/
if i'm right to understand your question you want to scroll original position try this
jQuery(document).ready(function() {
var screenTop=jQuery(document).scrollTop();
//sending page to the top when menu opens up
jQuery('.left-small a.menu-icon').click(function() {
//need to be able to send page back to original position before clicking on menu button
//jQuery('#content').css('top', screenTop);
console.log(screenTop);
temp = jQuery(document).scrollTop();
jQuery('body').scrollTop(screenTop);
screenTop = temp;
//when top menu closes, return page to previous location
//previous location is stored in var screenTop
//jQuery('body').animate(screenTop);
//if ('a.menu-icon')
});
});
DEMO
I think this slution is somewhat close to your answer.
JQuery
$("#check").click(function() {
if ($("#menu").is(":hidden")) {
$(document).scrollTop(lastPos);
} else {
// do that
}
});
var lastPos=0;
$("#getInfo").click(function(){
$("#menu").toggle();
lastPos=$(document).scrollTop();
});
In demo first click on getInfo then click check
DEMO
Update 1:
$( document).scroll(function() {
//store current scroll pos
//lastPos=$(document).scrollTop();
});
var lastPos=0;
$("#getInfo").click(function(){
//store scroll pos befor toggle
lastPos=$(document).scrollTop();
$( "#menu" ).toggle( "slow", function() {
// Animation complete.
if ($("#menu").is(":hidden")) {
$(document).scrollTop(lastPos);
} else {
// do that
}
});
});
DEMO

Back button after a slide

i need to have a back button on my slide to return to the previous div. I did several test but without success.
there is my JS
function SlideOut(element) {
$(".opened").removeClass("opened");
$("#" + element).addClass("opened");
$("#content").removeClass().addClass(element);
}
$("#content div").click(function () {
var move = $(this).attr('data-move');
SlideOut(move);
});
There is the demo link:
http://jsfiddle.net/VA5Pv/
thanks
You could create a history. I edited the fiddle with some dirty code but the idea is there:
var history = [];
var last;
$("#content div").click(function () {
var move = $(this).attr('data-move');
if (last) history.push(last);
last = move;
SlideOut(move);
});
$("#back").click(function () {
SlideOut(history.pop());
return false;
});
http://jsfiddle.net/VA5Pv/1/
Basically: store the "move" variable in a history array. When you want to go back, pop the last value out of the history array.
Reset
If you just want to return to the initial state (no slides opened), just add the following:
$('button.close').click(function() {
$('.opened').removeClass('opened');
});
Tracking a full history is overkill in this case.
Demo: http://jsfiddle.net/VA5Pv/4/
History
Several answers suggested using a history. Most of them used an array which keeps track of the slides the user opened and then simply pop from that to "go back".
var history = [];
$('#content div').click(function() {
var move = $(this).attr('data-move');
history.push(move);
SlideOut();
});
$('button.close').click(function() {
history.pop();
SlideOut();
});
function SlideOut() {
var element = history[history.length - 1];
// ... same as before ...
}
This would be necessary if you wanted to allow the user to open any number of slides in any order and always present them with a button to go back to the previously opened slide.
Sequence
Another solution could have been to store all the slide IDs in an array and keep a counter that tells you at which slide you are. Going back would mean decrementing the counter if it is not already at zero and then switching to that particular slide.
This would be useful if you were trying to create something like a presentation where each slide is opened in sequence and the transitions are entirely linear.
This is why I asked you to clarify what you were trying to build. Depending on the use case, the solutions could have been vastly different and far more complex than what you were actually looking for.
Thanks for accepting my answer and welcome to StackOverflow. Feel free to upvote any answers you found helpful even if they did not answer your question sufficiently.
try the following:
$('.anim button').click(function(){$(this).parent().removeClass('opened');});
I assigned this to the button in div rouge. But the target could be anything in that div you want the user to click on ...
see here: JSfiddle
Here is the DEMO
<div id="fullContainer">
<div id="right" class="anim"></div>
<div id="rouge" class="anim">Hello world!
<button class="close">Close</button>
</div>
</div>
<div id="centerContainer">
<div id="relativeContainer">
<div id="content">
<div data-move="right">Open Right</div>
<div data-move="rouge">Open Rouge</div>
<div id="back">Back</div>
</div>
function SlideOut(element) {
if(element == undefined) {
$('#back').hide();
}
$(".opened").removeClass("opened");
$("#" + element).addClass("opened");
$("#content").removeClass().addClass(element);
}
$("#content div").click(function () {
var move = $(this).attr('data-move');
$('#back').show();
SlideOut(move);
});

Jquery slide down only if not already visible

I have a simple problem using Jquery. I want to display detailed information under menu headings, but the interface isn't so smooth. After a few hours of trying some things out, I've come back to the beginning to see if there is a simple answer
Look at this example
Two problems:
If you mouse over several categories at once to get to the category you want, the animation still runs through all of the other animations instead of stopping the other ones and only animating the one that the mouse is currently hovered over.
If you mouse over a category that is already open, it still runs the animation, but I only want the animation to run if the content is not already visible. Is there a simple if statement that can do this?
$('.content').hide();
var $elms = $('.fruit, .vegetable, .dairy');
$elms.hover(function() {
var $content = $(this).next('.content');
$content.stop(1, 1).slideToggle(400);
});
http://jsfiddle.net/elclanrs/GBkMB/1/
Edit:
To prevent the content from sliding back up you can nest the divs like so:
<div class="fruit">fruit
<div class="content fruit_types">apple<br/>bannana<br/>orange</div>
</div>
<div class="vegetable">vegetable
<div class="content vegetable_types">celery<br/>lettuce<br/>cucumber</div>
</div>
<div class="dairy">dairy
<div class="content dairy_types">milk<br/>cheese<br/>butter</div>
</div>
jQ:
$('.content').hide();
var $elms = $('.fruit, .vegetable, .dairy');
$elms.hover(function() {
var $content = $(this).children('.content'); //<-`children()` not `next()`
$content.stop(1,1).slideToggle(400);
});
Example: http://jsfiddle.net/elclanrs/GBkMB/5/
I've edited your fiddle now to look like this. Should give you an idea of what you want to move forward:
http://jsfiddle.net/GBkMB/4/
$("body").on("hover", ".fruit, .vegetable, .dairy", function(event){
if(event.relatedTarget != $(this).next(".content")[0]){
if(event.type == "mouseenter"){
$('.content').slideUp('slow');
$('.'+$(this).attr("class")+'_types').slideDown('slow');
}else if(event.type == "mouseleave"){
$('.content').slideUp('slow');
}
}
});
$("body").on("mouseleave", ".content", function(event){
if(event.relatedTarget != $(this).prev("div")[0]){
$(this).slideUp('slow');
}
});
or: http://jsfiddle.net/GBkMB/6/ #elclanrs answer ++
$('.content').on("mouseleave", function(event){
if(event.relatedTarget != $(this).prev("div")[0]){
$(this).slideUp('slow');
}
});
var $elms = $('.fruit, .vegetable, .dairy');
$elms.on("hover", function(event) {
var $content = $(this).next('.content');
if(event.relatedTarget != $content[0]){
$content.stop(1,1).slideToggle(400);
}
});

jqueryui accordion disable specific according tab

hi i am trying to make a wizard for first time i want to disable all accordion tabs when i click on the link it enable next tab and open it..
i hve this code but it disable all tabs :(
thanks
$(function() {
$("#list1a").accordion({
autoHeight: false,
navigation: false
});
});
$("#list1a").accordion("disable");
$("#list1a").accordion("activate", 2 );
Don't use the accordion for that, it's not intended for wizardry. And since there's no wizard component available in jquery UI, lets make our own ;)
html:
<ul class="ui-wizard">
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
</ul>
javascript plugin:
$.fn.wizard = function(){
this.find('.ui-wizard-content').hide();
this.find('.ui-wizard-content:first').show();
this.find('.ui-wizard-content:last .ui-wizard-next').hide(); // just in case
this.delegate('.ui-wizard-next', 'click', function(){
// very long jquery chain...
$(this).closest('.ui-wizard-content')
.hide('fast')
.closest('.ui-wizard-panel')
.next()
.find('.ui-wizard-content')
.show('fast');
});
}
javascript impl:
$(".ui-wizard").wizard();
Ofcourse.. you'd have to theme it yourself, though copy/pasting and renaming accordion styles gets you a long way. A nicer way would be to make an official wizard widget out of this.
Can also check out this code: http://github.com/desdev/jWizard/
Think it's exactly what you need.
Try ui-state-disabled class: http://api.jqueryui.com/theming/css-framework/
Consider this piece of code that allows user go back, but not go to next accordion tab:
function disableAccordionNextTabs () {
var $accordion = $(".accordion");
var active = $accordion.accordion('option', 'active');
var $headers = $accordion.find($accordion.accordion('option', 'header'));
$headers.addClass('ui-state-disabled');
for (var i = active; i >= 0; i--) {
$headers.eq(i).removeClass('ui-state-disabled');
}
}

Categories