jQuery ToggleClass on multiple buttons - javascript

I am trying to toggle visibility of elements with jQuery. The page should load with all elements active. Then, when you click on one of 3 filter buttons, it should hide the elements that don't match.
I can get it to work with addClass and removeClass, but I want to be able to toggle the elements on and off when you click each button. This is where it falls apart. With toggleClass, it works on the first click, but when I try to toggle the buttons, the classes get all mixed up.
Here is a working fiddle using removeClass (no toggling):
$(".map-filters .heart").click(function() {
$('.blue-marker').addClass('d-none');
$('.green-marker').addClass('d-none');
$('.red-marker').removeClass('d-none');
});
And here is a non-working fiddle where I attempt to toggle the classes –– once you click around a bit, it gets mixed up:
$(".map-filters .heart").click(function() {
$('.blue-marker').addClass('d-none');
$('.green-marker').addClass('d-none');
$('.red-marker').toggleClass('d-none');
});
What am I doing wrong?
Thanks!

1.You have set the default to active to all of them.
2.You have to do make the decision based on the active not active of the button with hasClass()
You don't need code redundancy. You can simplify it by giving each button an id.
$(".map-filters .filter").click(function() {
$('.active').not(this).removeClass('active');
$(this).toggleClass('active');
if ($(this).hasClass('active')){
var color = $(this).attr('id');
$("#map").children().addClass('d-none');
$("." + color + "-marker").toggleClass('d-none');
}
else {
$("#map").children().removeClass('d-none');
}
});
.d-none {
visibility:hidden!important
}
#map {
border:1px solid #000;
padding:20px;
}
#map > div {
width:30px;
height:30px;
display:inline-block;
margin:10px;
}
.map-filters {
margin-top:50px;
}
.map-filters button {
opacity:0.5;
}
.map-filters button.active {
opacity:1;
}
.heart,
.red-marker {background:red;}
.heart-pvl,
.green-marker {background:green;}
.pvl,
.blue-marker {background:blue;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map">
<div class="blue-marker"></div>
<div class="red-marker"></div>
<div class="red-marker"></div>
<div class="green-marker"></div>
<div class="blue-marker"></div>
<div class="green-marker"></div>
</div>
<div class="map-filters">
<button type="button" class="filter heart" id="red">Heart Locations</button>
<button type="button" class="filter heart-pvl" id="green">Heart & PVL Locations</button>
<button type="button" class="filter pvl" id="blue">PVL Locations</button>
</div>

Related

How to prevent addClass and removeClass repetition

I'm adding active class to the buttons, and also i'm adding list/grid class to the cards-wrapper based on the button clicked.
Below is the working code. is there a way to write less code to achieve the same output?
$('.buttons button').click(function(e) {
e.preventDefault();
$('button').removeClass('active');
$(this).addClass('active');
if ($(this).hasClass('list')) {
$('.cards-wrapper').removeClass('grid').addClass('list');
}
else if($(this).hasClass('grid')) {
$('.cards-wrapper').removeClass('list').addClass('grid');
}
});
<div class="buttons">
<button class="grid">Grid</button>
<button class="list active">List</button>
</div>
<div class="cards-wrapper list">
<div>Sample Content</div>
</div>
You can use the jQuery toggleClass method. As the name suggests, this method toggles the given classes for all the elements in the selection.
You can reduce your if/else logic to just one if statement by checking whether the button that was clicked on is not active. Once you have established that the button is not active, you can then just toggle the classes for both of the buttons and for the content wrapper div.
$('.buttons button').click(function(e) {
e.preventDefault();
if (!$(this).hasClass('active')) {
$('button').toggleClass('active');
$('.cards-wrapper').toggleClass('grid list');
}
});
.active {
color: green;
}
.list {
color: red;
}
.grid {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
<button>Grid</button>
<button class="active">List</button>
</div>
<div class="cards-wrapper list">
<div>Sample Content</div>
</div>
Using the toggleClass method in this way will break if you add more buttons, though, so take care with it.
There's not much you can do there as you are having two action buttons, if you can make it into a single one, then you can use jQuery's .toggleClass() method here. Hence, you don't have to check for classes using .hasClass() every time.
$('.buttons button').click(function(e) {
//some of your code here
$('.cards-wrapper').toggleClass('grid list');
});
Try using ternary operator not toggleClass() because it will cost bug.
$('.buttons button').click(function(e) {
e.preventDefault();
$('button').removeClass('active');
$(this).addClass('active');
$(this).hasClass('list') ? $('.cards-wrapper').removeClass('grid').addClass('list') : '';
$(this).hasClass('grid') ? $('.cards-wrapper').removeClass('list').addClass('grid') : '';
});
.active{
color:green !important;
}
.list{
color:red;
}
.grid{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
<button class="grid">Grid</button>
<button class="list active">List</button>
</div>
<div class="cards-wrapper list">
<div>Sample Content</div>
</div>
Try with toggleClass() function of jquery
In your answer addClass() and removeClass() .its right.
But better use with toggleClass().because toggle function to check the class name already present or not.if is it present to remove the class name ,is not add the class.
Its handle with one or more function .See the jquery documentation of
toggleClass()
$('.buttons button').click(function(e) {
e.preventDefault();
$('button').toggleClass('active');
if($(this).hasClass('list')){
$('.cards-wrapper').toggleClass('grid list');
}
else if($(this).hasClass('grid')) {
$('.cards-wrapper').toggleClass('list grid');
}
});
.active{
color:green !important;
}
.list{
color:red;
}
.grid{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
<button class="grid">Grid</button>
<button class="list active">List</button>
</div>
<div class="cards-wrapper list">
<div>Sample Content</div>
</div>

how toggle all div tags

how? when click the .button, hide all .body div tags and show just closest .body tag div
my codes first one works, but when click the .button, show .body, but when click again, does't toggle ( show / hide ) that, any more?
How to do it properly?
Edit : how to change .button > span icon? ( positive or negative )
Edit : jQuery(this).find('positive').toggleClass('negative'); ?
Edit (saitho): JSFiddle: https://jsfiddle.net/nL4sxbj0/2/
HTML
<div class="box">
<div class="header">
<a href="#" class="button">
<span class="positive"></span>
</a>
</div>
<div class="body">
</div>
</div>
CSS
.body {
display:none;
}
.button .positive,
.button .negative {
width:36px;
height:36px;
float:right;
display:block;
cursor:pointer;
}
.button .positive {
background:url('../img/icon-del.png') no-repeat center center / 18px;
}
.button .negative {
background:url('../img/icon-opn.png') no-repeat center center / 18px;
}
JQUERY
jQuery('.button').on('click' ,function(e) {
e.preventDefault(); // Is this necessary? for
jQuery('.body').hide(); // Problem is hear i think
jQuery(this).closest('.box').find('.body').toggle();
});
Picture
add class iconbtn to button span
<div class="box">
<div class="header">
<a href="#" class="button">
<span class="iconbtn positive"></span>
</a>
</div>
<div class="body">
</div>
jQuery('.button').on('click' ,function(e) {
e.preventDefault();
var box = jQuery(this).closest('.box');
var closestBody = box.find('.body');
jQuery('.body').not(closestBody).hide(); // Hide all except above div
jQuery(closestBody).toggle(); // if visible hide it else show it
jQuery('.iconbtn').removeClass('negative').addClass('positive');
var iconBtn = box.find('.iconbtn');
if (jQuery(closestBody).is(':visible')) {
iconBtn.removeClass('positive').addClass('negative');
} else {
iconBtn.removeClass('negative').addClass('positive');
}
});
jsFiddle Link
The issue is that you have:
jQuery('.body').hide();
in your click callback, that means the body div is first being hidden and then toggle works as it should - it shows the div. There is no way it can hide it though, as before toggle you always first hide the div
Remove this line and it should work, check it here: JS Fiddle

Links for triggering a certain <div> to slide up and a link for triggering the <div> to slide down

I'd like to make some (let's say 2) links that will trigger a specific to appear by sliding up , then another link that will trigger the specific to huide by sliding down.
The links are generated dynamically by a certain application (something like looping which I personally don't understand)
After researching in this site, I tried the code below but found some problems:
only the first link for sliding up worked well, other blue links didn't work
Current script is sliding up and down the content for each click on the blue link.
I can't figure out how to break apart the script so I can apply sliding up script only for the blue links and the sliding down script for the red link.
to be noted, the blue links are dynamically generated based on a certain application loop, so practically there is no fix number for the amount of the blue links being displayed.
This is the code :
$(function(){
var list = $('#slidingcontent'),
button = $('#triggerup'),
speed = 500;
list.hide().css('bottom', button.css('top'))
.css('margin-top', list.outerHeight() * -1);
button.toggle(function(e) {
e.preventDefault();
e.stopPropagation();
list.slideDown(speed);
},function(e){
e.preventDefault();
e.stopPropagation();
list.slideUp(speed);
});
});
#slidingcontent{
position:absolute;
}
.linkcontainer{
text-align:center;
}
.sliding_up_link a, .sliding_down_link a, #slidingcontent{
color:white;
margin: 1px;
padding: 1px;
text-decoration:none;
font-weight:bold;
}
.sliding_up_link a{
background:blue;
}
.sliding_down_link a{
background:red;
}
#slidingcontent{
background:green;
}
<body>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.js"></script>
<div class= "linkcontainer">
<span class="sliding_up_link" id="triggerup" >
<a href ="#">
triggerup1 (for sliding upward)</br>
the amount of links(for triggering content to slide up) is uncertain based on conditions (it maybe only 1 link, or 3 links like this, or 7 links, or 15 links, etc)
</a>
</span>
</div>
<div class= "linkcontainer">
<span class="sliding_up_link" id="triggerup" >
<a href ="#">
triggerup2 (for sliding upward)</br>
the amount of links(for triggering content to slide up) is uncertain based on conditions (it maybe only 1 link, or 3 links like this, or 7 links, or 15 links, etc)
</a>
</span>
</div>
<div class= "linkcontainer">
<span class="sliding_down_link" id="triggerdown" >
<a href ="#">
triggerdown (for sliding down)</br>
only one link (for triggering content to slide down) will be displayed
</a>
</span>
</div>
<div id="slidingcontent">
content here
</div>
</body>
Thanks for help :)
This works for me. I corrected the HTML validation errors in your code as well.
jQuery(function ($) {
$(document).ready(function() {
$("#slidingcontent").css({"display": "none", "opacity": "1"});
});
$(window).load(function () {
var speed = 500,
target = $("#slidingcontent");
$(".sliding_up").on("click", function () {
target.slideDown(speed);
});
$(".sliding_down").on("click", function () {
target.slideUp(speed);
});
});
});
#slidingcontent {
position:absolute;
bottom: -2px;
opacity: 0;
padding: 0!important;
}
.linkcontainer {
text-align:center;
}
p.sliding_up, p.sliding_down, #slidingcontent {
color:white;
margin: 1px;
text-decoration:none;
font-weight:bold;
}
p.sliding_up, p.sliding_down {
cursor: pointer;
display:inline-block;
}
p.sliding_up {
background:blue;
}
p.sliding_down {
background:red;
}
#slidingcontent {
background:green;
}
.wrap {
overflow-y: hidden;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="wrap">
<div class="linkcontainer">
<p class="sliding_up">trigger up 1 (for sliding upward)</p>
</div>
<div class="linkcontainer">
<p class="sliding_up">trigger up 2 (for sliding upward)</p>
</div>
<div class="linkcontainer">
<p class="sliding_down">triggerdown (for sliding down)</p>
</div>
<div id="slidingcontent">content here</div>
</div>

onClick div changes color and back to color when clicking on the other

I want to point out which div I clicked on to prevent confusing as the pop up menu that comes out of it on my site will be both the same just different links but same buttons. Now my problem is that i cant figure out how i can manage to do it been stuck on it for quite some time now. My site is in Wordpress for the info. The color of the text doesnt really matter atm.
The code does work but i want that when i hit "juicyplants" the color changes and when i hit "leafyplant" that color changes and "juicyplants" go back to normal. with the changing colors i mean the already presenting ones.
My code:
HTML:
<div id="clickOne" class="clickDesign">
<h2 class="fs20 nobold">Leafy Plants</h2>
</div>
<div id="clickTwo" class="clickDesign">
<h2 class="fs20 nobold">Juicy Plants</h2>
</div>
</div>
<div id="leafyPlants">
Leafy Test
</div>
<div id="juicyPlants">
Juicy Test
</div>
CSS:
#leafyPlants{
display:none;
position:absolute;
top:50px;
cursor:pointer;
}
#juicyPlants{
display:none;
position:absolute;
top:50px;
cursor:pointer;
}
h2 {
float:left;
display:block;
height:40px;
width:150px;
cursor:pointer;
}
jQuery:
$("#clickOne").on('click', function() {
$("#leafyPlants").fadeIn();
$("#juicyPlants").fadeOut();
});
$("#clickTwo").on('click', function() {
$("#leafyPlants").fadeOut();
$("#juicyPlants").fadeIn();
})
Best to change classes and use styling:
jsfiddle: http://jsfiddle.net/TrueBlueAussie/Pcn5a/2/#update
$(function () {
$("#clickOne").on('click', function () {
$('.clickDesign').removeClass("active");
$(this).addClass("active");
$("#leafyPlants").fadeIn();
$("#juicyPlants").fadeOut();
});
$("#clickTwo").on('click', function () {
$('.clickDesign').removeClass("active");
$(this).addClass("active");
$("#leafyPlants").fadeOut();
$("#juicyPlants").fadeIn();
})
});
in style add:
.active{
color: green;
}
It is better to data-drive any menu system and reduce the code:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Pcn5a/3/
JQuery:
$(function () {
$('.clickDesign').on('click', function () {
var $this = $(this);
$('.clickDesign').removeClass("active");
$this.addClass("active");
// Use the id in the data-target attribute
$target = $($this.data('target'));
$(".target").not($target).fadeOut();
$target.fadeIn();
});
});
Html (has data-target attributes)
<div>
<div id="clickOne" class="clickDesign" data-target="#leafyPlants">
<h2 class="fs20 nobold">Leafy Plants</h2>
</div>
<div id="clickTwo" class="clickDesign" data-target="#juicyPlants">
<h2 class="fs20 nobold">Juicy Plants</h2>
</div>
</div>
<div id="leafyPlants" class="target">Leafy Test</div>
<div id="juicyPlants" class="target">Juicy Test</div>

JQuery tabs not switching

I am having an issue with my script that I always use to switch tabs. I am using jquery elsewhere on my page so the library is working. Just will not switch?
Here is my demo:
Fiddle
Here is the code, really not sure why it is failing?
<div id="buttons">
<ul>
<li id="intro" class="selected">Link1</li>
<li id="teachers">Link2</li>
<li id="learners" class="last">Link3</li>
</ul>
</div>
<div id="introcontent" >
<p>lksdjflksdjfklsdjfklsjfkl</p>
</div>
<div id="teacherscontent" >
<p>lsdklfjsdklfjdlsjflkdsj.</p>
</div>
<div id="learnerscontent" >
<p>sdlkhfskldfjhlksdjflksdj/a>.</p>
</div>
#buttons{
float:right;
left:-50%;
position:relative;
text-align:left;
}
#buttons ul{
list-style:none;
position:relative;
left:50%;
margin-top:96px;
font-size:18px;
}
.light #buttons ul {
margin-top:80px;
}
#buttons li{
float:left;
position:relative;
height:38px;
line-height:38px;
margin-right:47px;
border-top:2px solid #E6E8E8;
cursor:pointer;
}
#buttons li.last{
margin-right:0px;
}
#buttons li.selected{
color:#FF5500;
border-top:2px solid #FF5500;
}
#introcontent, #teacherscontent, #learnerscontent {
padding-top:200px;
margin-bottom:180px;
}
#teacherscontent, #learnerscontent {
display:none;
}
// Change tab class and display content
$('#buttons').on('click', function (event) {
event.preventDefault();
$('#introcontent').removeClass('#teachersoontent');
$(this).parent().addClass('tab-active');
$('.tabs-stage div').hide();
$($(this).attr('href')).fadeIn();
});
$('.tabs-nav a:first').trigger('click'); // Default
So there were quite a few reasons why the code in your fiddle wasn't working.
It was looking for an href to know which div to display, but there weren't any.
I updated your HTML like so, adding a common class to all the divs that would display content, to make it easier to manipulate them as a group:
<div id="introcontent" class="tabContent">
<p>lksdjflksdjfklsdjfklsjfkl</p>
</div>
<div id="teacherscontent" class="tabContent">
<p>lsdklfjsdklfjdlsjflkdsj.</p>
</div>
<div id="learnerscontent" class="tabContent">
<p>sdlkhfskldfjhlksdjflksdj.</p>
</div>
And amended the JavaScript to work with the new class on the content, and not to worry about href properties.
// Change tab class and display content
$('#buttons li').on('click', function (event) { // this lets you click on any li element inside #buttons
$(".selected").removeClass('selected'); // remove the selected class wherever it may be
$(this).addClass('selected'); // add the selected class to the clicked element
$(".tabContent").hide(); // hide all the elements with the class tabContent (added above)
$("#" + $(this).prop("id") + "content").show(); // show the content we want, by taking the ID of the list element and concatenating it into a string that will match the id of one of the content divs
});
$('#buttons li:first').click(); // You can trigger a click event like this
Here is the updated fiddle.
http://jsfiddle.net/YH3f4/2/

Categories