Reputation: 13448
I have the following code which toggles fine. I can toggle individually and toggle all together at the same time.
the problem arises when i have one of the individual items open, so when i select toggle all. it closes the opened ones and opens the closed one.. which i dont want to happen.
I want all opened items to close and also keep the existing closed items close and same for open, open all item and also keep any exiting items open.
Here is my fiddle demo and code below:
Javascript
function toggle() {
$("#showhide").click(function(){
$("#lorem1").toggle(1000,function(){
$("#231-minus").toggle();
$("#231-plus").toggle();
});
$("#lorem2").toggle(1000,function(){
$("#500-minus").toggle();
$("#500-plus").toggle();
});
$("#lorem3").toggle(1000,function(){
$("#850-minus").toggle();
$("#850-plus").toggle();
});
});
}
$(document).ready(function(){
toggle();
$("h3.viol-header1").click(function(){
$("#lorem1").toggle(1000,function(){
$("#231-minus").toggle();
$("#231-plus").toggle();
});
});
$("h3.viol-header2").click(function(){
$("#lorem2").toggle(1000,function(){
$("#500-minus").toggle();
$("#500-plus").toggle();
});
});
$("h3.viol-header3").click(function(){
$("#lorem3").toggle(1000,function(){
$("#850-minus").toggle();
$("#850-plus").toggle();
});
});
});
Upvotes: 0
Views: 357
Reputation: 206102
There's so many odd things in your code, I can only hope to cover them all. Let's start.
align
attribute is deprecated. Use CSS instead (text-align
property)h3.viol-he...
inside a JS logic. One day that h3
could change to h4
inside HTML, and you'll find yourself asking why jQuery suddenly broke.jQ-accordion-trigger
or something more descriptive and unbreakable.h3.viol-header1
, h3.viol-header2
etc... that actually perform a similar task should be avoided. Like I said earlier, use a single specific class, don't rely in ID unless you're completely sure that you need them for your JS code.style="blah blah"
. Use your stylesheet for styling,One principle I'll show you (might not be the best cause I'm using the jQuery's .next()
selector) is to make your Triggers and the slideable DIVs as sibling elements:
<h3 class="toggleNext">Lorem 1</h4>
<div>111....</div>
<h3 class="toggleNext">Lorem 2</h4>
<div>222....</div>
<h3 class="toggleNext">Lorem 3</h4>
<div>333...</div>
See how nice the HTML looks now?
How are that DIV elements hidden by default?
Using the Adjacent Sibling selector +
:
.toggleNext + * { /* hides adjacent sibling element */
display: none;
}
Where are the buttons gone?
Create them using CSS's :after
pseudo:
.toggleNext:after{ /* THE +/- SYMBOLS */
font-family: Helvetica, Arial, sans-serif;
letter-spacing: 1px;
border-radius: 50%;
line-height: 19px;
font-weight: 400;
text-align: center;
transition: background .4s;
height: 20px;
width: 20px;
float: right;
color: #fff;
background: #369335; /* Green (Default) */
content: "+";
}
.toggleNext.opened:after{ /* Class toggled by jQuery */
background: #A83C3D; /* Red */
content: "-";
}
What about my Show/Hide All button?
Don't use ID, probably one day you'll want to have two or more such buttons (see demo). Use class:
<p class="text-right">
<a href="#" class="toggleAll">Show/Hide All </a>
</p>
See? I've removed the unnecessary ID and added a class you can use everywhere in your document:
/* ::: HELPER CLASSES */
.text-right { text-align: right; }
jQuery (see how fun now is to play with JS logic)
var $togglers = $(".toggleNext"); // Cache your toggler elements
// ::: SLIDE-TOGGLE BUTTONS (...all it takes)
$togglers.click(function( event ){
// event.preventDefault(); // prevent page jumps (if you'll use `a` elements one day)
$(this).toggleClass("opened").next().slideToggle();
});
// ::: TOGGLE ALL BUTTONS
// (now it's a class, so you can have more than one)
// This buttons are a bit specific in logic, think about it,
// If user opened all items, would make sense to OPEN-ALL
// after a first click? NO.
$('.toggleAll').click(function( event ){
event.preventDefault(); // prevent page jumps
// The below variable will return `true` if
// at least one $trigger element has a class "opened"
var isOneOpened = $togglers.hasClass("opened");
if(isOneOpened){ // If one was opened: CLOSE ALL
$(".opened").click(); // Perform a click (only .opened togglers)
}else{
$togglers.click(); // All are closed: OPEN ALL
}
});
Now you can click even directly in the +/- symbol cause it's part of the trigger element (h3
in your specific case)
Principle2
If you don't want to use sibling triggers and slidables, than you can use data-*
attribute to target a specific element distant in the DOM tree.
Upvotes: 2