jQuery trouble: add class /remove class nested inside show / hide - javascript

I'm a beginner and I have a problem.
Could you please help me?
I made to divs on top of each other.
I made two other divs ("buttons")with paragraphs and I use jQuery show / hide effect to switch the two divs.
This part is working very well.
Nevertheless I want to add a nother effect (add class/ remove class) inside of this effect to show witch one is active.
But It's not changing the outlook of the "buttons".
Could you please help me where I made the mistake?
Here is my Code:
$(document).ready(function(){
$( "#click2" ).click(function(){
$( "#two" ).show();
$("#click2").removeClass(".passive").addClass(".active");
});
$( "#click1" ).click(function(){
$( "#two" ).hide();
$("#click1").removeClass(".passive").addClass(".active");
});
});
.active, .passive{
cursor: pointer;
font-weight: bold;
}
.active{
border-bottom: 2px solid blue;
color: blue;
}
.passive{
border-bottom: 2px solid gray;
color: gray;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
So the show / hide is wirking but the add/ remove class isn'n.
Could you please help me where I made the mistake?

Remove '.' (dot) from the css class name. jQuery addClass and removeClass only takes the name of the css class.
addClass("className") -- correct
addClass(".className") -- wrong
In your case it will be like:
$("#click2").removeClass("passive").addClass("active");

you have to remove the dot from the class ,
and also add the changing calls for the other button as below code
$(document).ready(function() {
$("#click2").click(function() {
$("#two").show();
$("#click2").removeClass("passive").addClass("active");
$("#click1").removeClass("active").addClass("passive");
});
$("#click1").click(function() {
$("#two").hide();
$("#click1").removeClass("passive").addClass("active");
$("#click2").removeClass("active").addClass("passive");
});
});
.active,
.passive {
cursor: pointer;
font-weight: bold;
}
.active {
border-bottom: 2px solid blue;
color: blue;
}
.passive {
border-bottom: 2px solid gray;
color: gray;
}
`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
<div class="row">
<div id="two" class="col-xs-12 active">
<p class="text-center text-uppercase">Div content </p>
</div>
</div>

While using removeClass and addClass, you only need to provide classname, . is not needed.
$(document).ready(function() {
$("#click2").click(function() {
$("#two").show();
$(this).removeClass("passive").addClass("active");
$("#click1").removeClass("active").addClass("passive");
});
$("#click1").click(function() {
$("#two").hide();
$(this).removeClass("passive").addClass("active");
$("#click2").removeClass("active").addClass("passive");
});
});
.active,
.passive {
cursor: pointer;
font-weight: bold;
}
.active {
border-bottom: 2px solid blue;
color: blue;
}
.passive {
border-bottom: 2px solid gray;
color: gray;
}
`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div id="click1" class="col-xs-6 active">
<p class="text-center text-uppercase">referencies a</p>
</div>
<div id="click2" class="col-xs-6 passive">
<p class="text-center text-uppercase">referencies b</p>
</div>
</div>
<div class="row">
<div id="two" class="col-xs-12 active">
<p class="text-center text-uppercase">Div content </p>
</div>
</div>

Here is the updated code:
<script type="text/javascript">
$(document).ready(function(){
$( "#click2" ).click(function(){
$( "#two" ).show();
$("#click2").removeClass("passive").addClass("active"); // Removed `.` from class names
});
$( "#click1" ).click(function(){
$( "#two" ).hide();
$("#click1").removeClass("passive").addClass("active"); // Removed `.` from class names
});
});
</script>

You don't need to use dot when use jQuery class methods, as already mentioned;
You could try to keep it simplier by using toggleClass instead of addClass and removeClass:
$( "#click3" ).click(function(){
$("#click3, #click4").toggleClass("active passive");
});
$( "#click4" ).click(function(){
$("#click3, #click4").toggleClass("active passive");
});
You could mention differencies in behavior (now active element become passive on click).
To simplify even more, we could add just one listener, but check what exactly we clicking:
$(document).on('click', '.passive', function() {
$('#click1, #click2').toggleClass("active passive");
});
https://jsfiddle.net/aakochar/u3c34b48/
As an alternative (or if you want to investigate the code), take a look at bootstrap tabs:
http://getbootstrap.com/javascript/#tabs

Related

Javascript : finding a specific previous element on list and adding class

I have a list like this.
Inside each .list item there is a html button :
<div class="list">
<button>.list</button>
</div>
Also, each item can be inside a .bloc element
<div class="list"><button>.list</button></div>
<div class=bloc>
<div class="list"><button>.list</button></div>
</div>
When I click on the button, I would like the previous .list item to have the .active class like so :
Well it’s pretty easy with jquery and i've done that, it’s work pretty well :
$('.list button').on('click', function() {
$(this).closest('.list').prev('.list').addClass('active');
});
BUT i have some specific cases :
Sometimes the list items can be hidden and a list with hidden class can’t have .active class :
Or more complicated. You have to go up on each item one by one and put the active class to the first which does not have the hidden class :
I did the mechanics for items without class hidden, but I'm afraid I'm going in the wrong direction because the number of cases is getting bigger and bigger. Ain't there a smarter way ? :o
$('.list button').on('click', function() {
if ($(this).closest('.list').prev().length === 0) {
if ($(this).closest('.bloc').length) {
$(this).closest('.bloc').prev('.list').addClass('active');
$(this).closest('.bloc').prev('.bloc').find('.list:last-child').addClass('active');
} else {
$(this).closest('.list').next('.list').addClass('active');
}
}
if ($(this).closest('.list').prev('.bloc').length) {
$(this).closest('.list').prev('.bloc').find('.list:last-child').addClass('active');
}
$(this).closest('.list').prev('.list').addClass('active');
}
Rather than use .closest .prev and .next you can use the overload to .index which will give you the index within an existing collection.
var idx = collection.index(element);
select all your .list items into a jquery object/collection
when clicking get the index within that collection
subtract 1 to get the previous .list item within that collection
The basic scenarios are covered with $(".list") :
// collate the list first
var list = $(".list");
// add click handler
list.click(function() {
// confirm there are no duplicates
// comapred with $(this).index() which is the index within the parent
console.log(list.index(this), $(this).index())
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>
All the other use-cases are then just a case of providing the correct selector up-front, with otherwise exactly the same code
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)");
I've tried to recreate some of your scenarios, but if there's one that's missing, please comment and I'll ensure it fits (within the remit of the question).
Giving:
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)")
list.click(function() {
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
.hidden { background-color: #ccc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list hidden'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list hidden'></div>
</div>
<div class='list'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
<div class='bloc hidden'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>

Css on clickable element (*[onclick]:hover)

I want to use to style my clickable element (javascript function onclick), when they hovered.
So far I have this :
*[onclick]:hover{
background-color: red ;
color: blue;
}
It works fine for most of my elements as you can see :
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*[onclick]:hover{
background-color: red ;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement" >Don't click me :( Z</div>
<div id="C" >Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>
But it only work for element where the onclick function is written in the Html page, and not added via Javascript.
Is there a way to properly select all clickable elements ?
The browser know a handful of elements that can be clicked by default, like the <a> and <button> elements. It is usually a good practice to use these elements if you want the user the click them, as they require little work to modify.
Other than that you could just add a class to the elements which to target them with as there is not a selector for an element that can be clicked.
However, it is a good practice to add a tabindex attribute to the elements that can be clicked as it makes them focusable. Users without a mouse (they exist) can use the Tab key to cycle through the clickable elements and click them with Enter or Spacebar. The elements mentioned in the first paragraph already incorporate this natively. With <div> elements you'll have to add this behavior manually.
The example below targets all clickable elements with a class and adds the :focus selector for the focussed styles.
document.getElementById('C').onclick = function() {
alert('I am clickable too !')
}
div {
background-color: green;
margin: 2px
}
.clickable:hover {
background-color: red;
color: blue;
}
.clickable:focus {
background-color: blue;
color: red;
}
<div id="A" class="clickable" onclick='alert("A")' tabindex="0">Click me ! A</div>
<div id="B" class="clickable" onclick='alert("B")' tabindex="0">Click me ! B</div>
<div id="notAclickableElement">Don't click me :( Z</div>
<div id="C" class="clickable" tabindex="0">Click me ! C</div>
<div id="D" class="clickable" onclick='alert("D")' tabindex="0">Click me ! D</div>
Sure. Just remove the [onclick] in the CSS.
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*:hover{
background-color: red ;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement" >Don't click me :( Z</div>
<div id="C" >Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>
However, that also changed the background too, so we can designate a specific class to the divs like so:
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
.hoverme:hover{
background-color: red ;
color: blue;
}
<div class="hoverme" id="A" onclick='alert("A")'>Click me ! A</div>
<div class="hoverme" id="B" onclick='alert("B")'>Click me ! B</div>
<div class="hoverme" id="notAclickableElement" >Don't click me :( Z</div>
<div class="hoverme" id="C" >Click me ! C</div>
<div class="hoverme" id="D" onclick='alert("D")'>Click me ! D</div>
Designating the hover to a single class is much more efficient, because you can define different hover effects for different things. All you have to do is add class="hoverme"
You can use .class in CSS.
document.getElementById('C').onclick = function(){alert('I am clickable too !')}
div {
background-color: green ;
margin : 2px
}
*[onclick]:hover{
background-color: red ;
color: blue;
}
.click {
background-color: green;
}
.click:hover {
background-color: red;
}
<div class="click" id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div class="click" id="notAclickableElement" >Don't click me :( Z</div>
<div class="click" id="C" >Click me ! C</div>
<div class="click" id="D" onclick='alert("D")'>Click me ! D</div>
I hope I have been helpful
var x = document.querySelectorAll("div");
for (let i = 0; i < x.length; i++) {
if (x[i].id !== 'notAclickableElement') {
x[i].setAttribute('class', 'clickclass');
}
}
document.getElementById('C').addEventListener("click", hoverMe);
function hoverMe() {
alert('I am clickable too !')
}
div {
background-color: green;
margin: 2px
}
.clickclass:hover {
background-color: red;
color: blue;
}
<div id="A" onclick='alert("A")'>Click me ! A</div>
<div id="B" onclick='alert("B")'>Click me ! B</div>
<div id="notAclickableElement">Don't click me :( Z</div>
<div id="C">Click me ! C</div>
<div id="D" onclick='alert("D")'>Click me ! D</div>

How do I make one element appear without triggering other elements of the same class

I have to make a set of buttons that appear and disappear.
How it is supposed to work:
I click on link 1 (link 2 is invisible at this point).
link 2 should then appear.
the problem here is there can be multiple elements of the same type with the same classes and I can't figure out how to distinguish between just showing the "link2"
that corresponds to the clicked "link1" without triggering the other "link2".
there is some code showing the progress I have made.
thank you in advance!
<style>
.hideaction{
visibility: hidden;
}
.showaction{
visibility: visible;
}
</style>
<script>
$(document).ready(function(){
$(".elem_action_showing").click(function(){
$(".elem_action_hiding").removeClass("hideaction").addClass("showaction");
});
</script>
</head>
<body>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
</body>
The solution should work irregardless of how many ".elem_card" and ".hideaction" elements are there.
The issue is because you're selecting all .elem_action_hiding elements. To fix this use DOM traversal to find only the one which is related to the .elem_action_showing which was clicked. Try this:
$(".elem_action_showing").click(function() {
$(this).closest('.elem_showing').prev().find(".elem_action_hiding").toggleClass("hideaction showaction");
});
.hideaction {
visibility: hidden;
}
.showaction {
visibility: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>
<div class="elem_card card_set_click" style=" border: 1px solid black">
<div class="elem_hidden">
<p class="hideaction elem_action_hiding">%link2%</p>
</div>
<div class="elem_showing ">
<p class="elem_action_showing set_click">%link1%</p>
</div>
</div>

Background image div clickable

I have a div with a background image. How can i make the div (the background image) clickable? I want to unhide an other div when clicked on the div (image). Onclick code: onclick="javascript:unhide('kazen')"
var clickit = document.getElementsByClassName("fh5co-grid")[0];
var kazen = document.getElementById("kazen");
clickit.addEventListener("click", function(){
if (kazen.style.display === "none") {
kazen.style.display="block";
} else {
kazen.style.display="none";
}
});
kazen.addEventListener("click", function(){
this.style.display="none";
});
#kazen {
background-color: #cc9;
display: none;
width: 100px;
height: 100px;
position: absolute;
top: 15px;
left: 15px;
}
.fh5co-grid {
}
<div class="col-md-4 col-sm-6 ">
<div class="fh5co-grid" style="background-image: url(images/PREVIEW_Shop_02-29.jpg);">
<a class="image-popup text-center" >
<div class="prod-title ">
<h3>Kaas</h3>
<h4>in ons aanbod hebben we verse en harde kazen - binnenkort meer hierover</h4>
</div>
</a>
</div>
</div>
<div id="kazen" >
<div class="col-md-12">
<div class="fh5co-grid" style="background-image: url(images/Melkerhei_Dag2-16-4.jpg);">
<a class="image-popup text-center" >
<div class="prod-title ">
</div>
</a>
</div>
</div>
</div>
You can have a look at the fiddle I created if this is what you want.
$(document).ready(function() {
$("div.fh5co-grid").click(function() {
$("div.next").css("display", "block");
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-4 col-sm-6 ">
<div class="fh5co-grid" style="background-image: url(http://placehold.it/350x150);">
<a class="image-popup text-center">
<div class="prod-title ">
<h3>cheese</h3>
<h4>tekst</h4>
</div>
</a>
</div>
</div>
<div style="background-color: #000; display:none" class="next">Next div</div>
From what you're describing, this seems pretty close. The background image isn't clickable, it's the div itself. And this could be done with jQuery, yes, but it's trivial enough that pure javascript is pretty easy here. Clicking in the red-boxed area will display the div with the id kazen, and clicking in either kazen or the red-boxed area again will hide it.
Note, there was a weird glitch to my solution. I changed the display if/else to check if it's currently displayed and hide it, rather than if it's currently hidden to display it. That was causing a strange effect of re-hiding the kazan div on the first click.
Within stackoverflow, you'll need an absolute url to display an image. If you aren't seeing your image here, that may be why.
var clickit = document.getElementsByClassName("fh5co-grid")[0];
var kazen = document.getElementById("kazen");
clickit.addEventListener("click", function(){
if (kazen.style.display === "block") {
kazen.style.display="none";
} else {
kazen.style.display="block";
}
});
kazen.addEventListener("click", function(){
this.style.display="none";
});
#kazen {
background: url("https://static.pexels.com/photos/6832/waterfall-beauty-lets-explore-lets-get-lost.jpg");
background-size: 100%;
display: none;
width: 100px;
height: 100px;
position: absolute;
top: 15px;
left: 15px;
color: #fff;
}
.fh5co-grid {
border: 1px dotted red;
}
<div class="col-md-4 col-sm-6 ">
<div class="fh5co-grid" style="background-image: url(images/PREVIEW.jpg);">
<a class="image-popup text-center">
<div class="prod-title ">
<h3>cheese</h3>
<h4>tekst</h4>
</div>
</a>
</div>
</div>
<div id="kazen">
Click me to hide!
</div>

How to hide div when it's already open?

I couldn't think of any better title, so I will try to explain my question here as clear as possible. I'm quite a newbie in JQuery so this is probably a very easy question.
I have some divs with a button on it. When you click the button, another div should pop-up.
My question is: How can I make the div, which is already open, close when clicking on another button?
I made a fiddle with some example code: http://jsfiddle.net/zuvjx775/1/
And the example code here:
HTML:
<div class="wrapper">
<div class="test">
<input type='button' class='showDiv' id="1" value='click!' />
</div>
<div class="show_1">
</div>
</div>
<br>
<div class="wrapper">
<div class="test">
<input type='button' class='showDiv' id="2"value='click!' />
</div>
<div class="show_2">
</div>
</div>
JQuery:
$('.showDiv').on('click', function(){
var id = $(this).attr('id');
$('.show_'+id).show();
});
When show_1 for example is visible, and I click on the button in div2, I want show_2 to come up, which it does, but show_1 to dissapear.
Can someone point me in the right direction?
You can hide all divs that their class starts with 'show' before show the one you want. For example:
$('.showDiv').on('click', function() {
var id = $(this).attr('id');
$("div[class^='show']").hide();//find div class starts with 'show' and hide them
$('.show_' + id).show();
});
.test {
border: 1px solid black;
height: 100px;
width: 450px;
float: left;
}
.show_1 {
width: 50px;
height: 50px;
background-color: yellow;
float: left;
display: none;
}
.show_2 {
width: 50px;
height: 50px;
background-color: green;
float: left;
display: none;
}
.wrapper {
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="test">
<input type='button' class='showDiv' id="1" value='click!' />
</div>
<div class="show_1">
</div>
</div>
<br>
<div class="wrapper">
<div class="test">
<input type='button' class='showDiv' id="2" value='click!' />
</div>
<div class="show_2">
</div>
</div>
Is the structure of the document fixed?
is so... I guess the easiest way of doing this is to just do the following:
$('.showDiv').on('click', function(){
var id = $(this).attr('id');
if(id == 1){
$('.show_1').show();
$('.show_2').hide();
}else{
$('.show_2').show();
$('.show_1').hide();
}
})

Categories