If parent li hasclass append class to child element - javascript

I'm trying to add a class called "animated" to a child div only when the parent li has a class called "current". Additionally, I'm trying to remove the "animated" class if the parent li does not show the "current" class.
$(document).ready(function() {
if ($('ul.itemwrap li').hasClass('current')) {
$( "ul.itemwrap li" ).find( ".caption-text" ).addClass("animated");
}
else {
$( "ul.itemwrap li" ).find( ".caption-text" ).removeClass( "animated" );
}
});
problem*
the code works, somewhat, however, it's only adding the class to all child (.caption-text) elements as well as not removing them when the "current" class is added and removed throughout the carousel loop.
Html*
<ul class="itemwrap">
<li class="current"> <img src="images/img1.jpg" alt="img-description">
<div class="caption">
<div class="caption-holder">
<div class="container">
<div class="caption-text">
<h1>title</h1>
</div>
</div>
</div>
</div>
</li>
<li> <img src="images/img2.jpg" alt="img-description">
<div class="caption">
<div class="caption-holder">
<div class="container">
<div class="caption-text">
<h1>Title</h1>
</div>
</div>
</div>
</div>
</li>
<li> <img src="images/img3.jpg" alt="img-description">
<div class="caption">
<div class="caption-holder ">
<div class="container">
<div class="caption-text">
<h1>Title></h1>
</div>
</div>
</div>
</div>
</li>
</ul>

An issue with your code is that if one <li> has the class 'current', then you're adding the class animated to all ".caption-text" elements, not just the ones below the item with '.current'.
You could fix your code in a couple ways. This way processes each <li> individually:
$(document).ready(function() {
$('ul.itemwrap li').each(function() {
var item = $(this);
var caption = item.find(".caption-text");
if (item.hasClass('current')) {
caption.addClass("animated");
} else {
caption.removeClass("animated");
}
});
});
This way uses selectors to do more of the work for you:
$(document).ready(function() {
// clear .animated from all captions
$('ul.itemwrap li .caption-text').removeClass("animated");
// put back the .animated under .current
$('ul.itemwrap li.current .caption-text').addClass("animated");
});

Related

select grand children elements

I'm struggling to select my img Element in a list so i can switch its class on and off.
I've tried different way to select it but its the first picture of my list that lights up, even when mouseover on the second/third/... div of the list.
<ul>
<li>
<div class="container" onmouseover="toggleImgColor()" onmouseout="toggleImgColor()">
<div class="container-title">
<h3 class="title />
<img id="pic" class="greyImg" />
</div>
...
</div>
</li>
...
</ul>
Javascript
function toggleImgColor() {
$(this).find("img").toggleClass("greyImg");
}
You can do that something like this:
$(document).ready(function(){
$(".container").hover(function() {
$("#pic").toggleClass("greyImg");
});
});
Just pass this inside the toggleImgColor() in html like toggleImgColor(this), and catch that as parameter in javascript function. This will pass current hovered DOM object to toggleImgColor function and you can then use that to show that specific div.
HTML:
<ul>
<li>
<div class="container" onmouseover="toggleImgColor(this)" onmouseout="toggleImgColor(this)">
<div class="container-title">
<h3 class="title />
<img class="greyImg" />
</div>
...
</div>
</li>
...
</ul>
JavaScript:
function toggleImgColor(item) {
$(item).find("img").toggleClass("greyImg");
}

Getting id of collapsible div in Jquery and Bootstrap

I have multiple(it can be 100+) collapsible div (using bootstrap)
<div>
<a href="#id1" data-toggle="collapse">
<div class="col-lg-12">Title</div>
<div class="image">Image</div>
</a>
<div id="id1" class="collapse">
<div class="col-lg-12">Description</div>
</div>
</div>
<div>
<a href="#id2" data-toggle="collapse">
<div class="col-lg-12">Title</div>
<div class="image">Image</div>
</a>
<div id="id2" class="collapse">
<div class="col-lg-12">Description</div>
</div>
</div>
And have Jquery
$('#id1').on('show.bs.collapse', function () {
$(".image").addClass('hidden');
});
$('#id1').on('hidden.bs.collapse', function () {
$(".image").removeClass('hidden');
});
I want to add hidden class on show.bs.collapse(this is from bootstrap) and remove hidden class on hidden.bs.collapse'With the jq code above I can do this just with one div that has id1. But how can I do this independently?
Try not to subscribe on the elements by ids but by element type
$('a').on('show.bs.collapse', function () {
$(this).next().find("div.image")[0].addClass('hidden');
});
$('a').on('hidden.bs.collapse', function () {
$(this).next().find("div.image")[0].removeClass('hidden');
});
Where
$(this)
should return a pointer to the collapsed/uncollapsed element
next()
should move pointer to the next element ( div id="id1" as example)
find("div.image")[0]
will find div with class "image" and take the first found element
then you can hide the image in this block or show it without using ids
If you're using
$(".image").addClass('hidden');
this will hide all the images in all blocks (not only in that one that has been collapsed)
Id refers to one element on the DOM therefore you should use classes instead. Therefore you should select divs based on their classes.
The following is a possible solution:
<div>
<a href="#id1" data-toggle="collapse">
<div class="col-lg-12">Title</div>
</a>
<div class="some-class collapse ad-col-2">
<div class="col-lg-12">Description</div>
<div class="image"></div>
</div>
</div>
<div>
<a href="#id2" data-toggle="collapse">
<div class="col-lg-12">Title</div>
</a>
<div class="some-class collapse ad-col-2">
<div class="col-lg-12">Description</div>
<div class="image"></div>
</div>
</div>
Jquery:
$('.some-class').on('show.bs.collapse', function () {
$(".image").addClass('hidden');
});
$('.some-class').on('hidden.bs.collapse', function () {
$(".image").removeClass('hidden');
});

using $(this) properly in jquery

$(".gear_listing").hover(function(){
$(".overlay_gears").show();
},function(){
$(".overlay_gears").hide();
}
);
above is my jquery code,as u can imagine i am trying to show .overlay_gears div when .gear_listing div is hover,the above code works just fine.the problem is i have many number of .gear_listing divs and many number of .overlay_gears div,when i hover on any div called .gear_listing all the .overlay_gears div is shown which i dont want.i just want to show the .overlay_gears div under that .gear_listing div.i know i have to make use of $(this).i just don't know how.
i tried doing this:
$(".gear_listing").hover(function(){
var this=$(this);
this.$(".overlay_gears").show();
},function(){
this.$(".overlay_gears").hide();
}
);
its not working
below is my div structure:
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"></div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
<img src="images/list_one.jpg">
</div>
</a>
</li>
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"></div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
<img src="images/list_two.jpg">
</div>
</a>
</li>
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"></div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
<img src="images/list_three.jpg">
</div>
</a>
</li>
.overlay_gears is children of .gear_listing so use like this
$(".gear_listing").hover(function(){
$(this).children(".overlay_gears").fadeIn();
},function(){
$(this).children(".overlay_gears").fadeOut();
});
Use .find() and .slideToggle() for animation effects or use .fadeToggle()
$(".gear_listing").hover(function() {
$(this).find(".overlay_gears").stop().slideToggle();
});
or
$(".gear_listing").hover(function() {
$(this).find(".overlay_gears").stop().fadeToggle();
});
Fiddle
Use this as the second-argument in selector which is context
By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function.
Internally, selector context is implemented with the .find() method, so $( "SELECTOR", this ) is equivalent to $(this).find("SELECTOR")
$(".gear_listing").hover(function() {
$(".overlay_gears", this).show();
}, function() {
$(".overlay_gears", this).hide();
});
Since overlay_gears is a child element of gear_listing,you can use .find() method
$(".gear_listing").hover(function() {
$(this).find(".overlay_gears").show();
}, function() {
$(this).find(".overlay_gears").hide();
});
Basically, you first needs to hide all .overlay_gears on hover and just needs to show the particular .overlay_gears that is the child of current hovered parent. And then in 'unhover' event you can simply hide all .overlay_gears divs..
HTML:
<ul>
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"> overlay_gears data1 overlay_gears data1</div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"> overlay_gears data2 overlay_gears data2</div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="gear_listing relative">
<div class="overlay_gears absolute"> overlay_gears data3 overlay_gears data3 overlay_gears data3</div>
<div class="gear_description absolute">
<span>afdfdsfds sfd</span>
</div>
</div>
</a>
</li>
</ul>
JQuery:
$(document).ready(function(){
$( ".gear_listing" ).hover(
function() {
$( ".overlay_gears" ).hide();
$( ".overlay_gears", this ).show();
}, function() {
$( ".overlay_gears" ).hide();
}
);
});
Working Fiddle: http://jsfiddle.net/kfopaj7e/
I have just removed <img> tag for testing purpose and added few css in Fiddle for the visual thingy
you can use
$(".gear_listing").hover(function(){
$(this).children('.overlay_gears').show();
}
here we select all elements inside $(this) with required class
http://www.w3schools.com/jquery/jquery_traversing_descendants.asp
pass an event in function like
function(evt){
var th = $(evt.target);
$(th).find(".overlay_gears").show();
}

How to get closest div html content?

I have multiple ul and li's and want to get the closest div respective html content when click on li.
I have tried this like $(this).closest('div').find('.email-con').show().html() getting undefined.
<div class="col-md-12">
<div class="col-md-3 subs-alrts">
<ul class="cp-expand sent-mails" id="sent-mails">
<li class="clearfix">
<div class="cp-exp-title clearfix col-md-12">Dasara Mail</div>
<div class="cp-exp-con col-md-12">
<ul>
<li class="evnt-mail-cls" >06/01/16</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="col-md-9 email-con" id="email-con" style="display:none">
dasara mail content
</div>
</div>
My script is:
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($(this).closest('div').find('.email-con').show().html());
});
If you are trying to find the content of .email-con then you need to traverse upto .subs-alrts and then pick its next element.
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($(this).closest('.subs-alrts').next('.email-con').show().html());
});
See the final code:
$(function() {
$('#sent-mails .cp-exp-con ul li').click(function() {
var x = $(this).closest('.subs-alrts').next('.email-con');
x.show();
alert(x.html());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-12">
<div class="col-md-3 subs-alrts">
<ul class="cp-expand sent-mails" id="sent-mails">
<li class="clearfix">
<div class="cp-exp-title clearfix col-md-12">Dasara Mail</div>
<div class="cp-exp-con col-md-12">
<ul>
<li class="evnt-mail-cls">06/01/16</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="col-md-9 email-con" id="email-con" style="display:none">
dasara mail content
</div>
</div>
Try this
$('ul li').click(function(){
var a=$(this).closest('div');
a=$(this).closest('div').text();
alert(a);
});
You need :
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($(this).closest('div').parent().find('.email-con').show().html());
});
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($('.email-con').show().html());
});
Change for jquery code with following , it may help you.
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($(this).parents('.subs-alrts').parent('div').find('.email-con').show().html());
});
Try this:
$('#sent-mails .cp-exp-con ul li').click( function(){
alert($(this).parents('.subs-alrts').parent().find('.email-con').show().html());
});
You have two way of doing this explained in code comments :
Note: the second (and easiest) require that you add a class to your top div (because col-md-12 is a bootstrap one that could change in the future)
// if you click there will be 2 alerts because I wrote two way of doing it :
$('#sent-mails .cp-exp-con ul li').click( function() {
var html = $(this)
// Get the parent with class "subs-alrts"
.parents(".subs-alrts")
// get the following element that have the class "email-con"
.next('.email-con')
.show().html();
alert(html);
});
// OR
$('#sent-mails .cp-exp-con ul li').click( function() {
var html = $(this)
// Get the parent with class "MAIN_DIV"
.parents(".MAIN_DIV")
// find the child element that have the class "email-con"
.find('.email-con')
.show().html();
alert(html);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-12 MAIN_DIV">
<div class="col-md-3 subs-alrts">
<ul class="cp-expand sent-mails" id="sent-mails">
<li class="clearfix">
<div class="cp-exp-title clearfix col-md-12">Dasara Mail</div>
<div class="cp-exp-con col-md-12">
<ul>
<li class="evnt-mail-cls" >06/01/16</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="col-md-9 email-con" id="email-con" style="display:none">
dasara mail content
</div>
</div>

Toggle Multiple divs for show hide

ok, So I have multiple divs(7) which I want to toggle for show hide. If one div is open rest should hide and when I open a new div the others should hide. I have been able to accomplish this with the below piece of jquery
function showDivs() {
$(".head").click(function() {
$(".Content").hide();
$(this).next().fadeIn("slow");
})
}
where .head is the header for each div and .Content is the class for divs. I have got it working perfectly, by calling showDivs() from .head() Now the question is that on the left hand side of my page, I have ul li set. I have 7 li items, that correspond to 7 divs. I mean on click of first li the corresponding div should open up and the others should hide, and on click of 2nd li the 2nd div should open up and the others hide.
Does anybody have an idea how to make these divs show hide on the action of li items on left. I know I have to pass parameters for showDivs(), but don't know how?
help is appreciated
I believe this is where .index() comes into play:
$(function() {
$('ul li').each(function() {
$(this).click(function(e) {
var i = $(this).index();
$('div').hide();
$('div:eq('+i+')').show();
});
});
});
That's a pretty basic markup but I'm sure you can work out how to get it working with your code. Hope I helped!
http://jsfiddle.net/Z3Hj7/
EDIT: After having seen your fiddle I think i worked out exactly what you want:
$(function() {
$('ul li').each(function() {
$(this).click(function(e){
e.preventDefault();
var i = $(this).index();
$('.content').hide();
$('.head:eq('+i+')').next().show();
});
});
});
Take a look at the fiddle: http://jsfiddle.net/DTcGD/25/
If I understand your HTML structure correctly, it looks about like this:
<!-- The list... -->
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
<!-- The divs -- note I've assumed there's a container... -->
<div id="container">
<div class="head">Header One</div>
<div class="Content">Content One</div>
<div class="head">Header Two</div>
<div class="Content">Content Two</div>
<div class="head">Header Three</div>
<div class="Content">Content Three</div>
<div class="head">Header Four</div>
<div class="Content">Content Four</div>
</div>
...only with seven items rather than four.
If so, this would do it (live copy):
jQuery(function($) {
$(".Content").hide();
$("li").click(function() {
showDivs($("#container div.head:eq(" + $(this).index() + ")"));
});
$(".head").click(function() {
showDivs($(this));
});
function showDivs(head) {
$(".Content").hide();
head.next().fadeIn("slow");
}
});
There, I'm relating the list to the headers implicitly, by where they are in their container. So the first li relates to the first div with class="head", the second to the second, etc. I'm doing that by using index to know which li was clicked, and then looking up the related div.head using :eq.
Doing it structurally rather than with id values makes it much easier to maintain. Alternately, though, you could do it by giving each li a data-div attribute with the value of the id of the related div:
<ul>
<li data-div="h1">One</li>
<li data-div="h2">Two</li>
<li data-div="h3">Three</li>
<li data-div="h4">Four</li>
</ul>
<div id="container">
<div id="h1" class="head">Header One</div>
<div class="Content">Content One</div>
<div id="h2" class="head">Header Two</div>
<div class="Content">Content Two</div>
<div id="h3" class="head">Header Three</div>
<div class="Content">Content Three</div>
<div id="h4" class="head">Header Four</div>
<div class="Content">Content Four</div>
</div>
Then (live copy):
jQuery(function($) {
$(".Content").hide();
$("li").click(function() {
showDivs($("#" + $(this).attr("data-div")));
});
$(".head").click(function() {
showDivs($(this));
});
function showDivs(head) {
$(".Content").hide();
head.next().fadeIn("slow");
}
});
data-* attributes are valid as of HTML5, but all browsers support them right now. (The data-* thing is an attempt to codify and reign in people's use of invalid attributes, by giving them a valid way to do it without conflicting with future additions to the spec.)
How about asigning an id to each list item and a corosponding id to each item container. So your list items get an id of "item01".."item07" and your content containers gets id of "item01c".."item07c". Then you can do somehing like this:
$("li").click(function() {
showDivs($(this).attr("id"));
})
function showDivs(callerId) {
$(".content").hide();
$(".content", "#" + callerId + "c").fadeIn();
}
Working example can be seen here: http://jsfiddle.net/ECbkd/5/1
If you want to use .index() as suggested by someone earlier, then I belive this would be the simplest approach (check it out here http://jsfiddle.net/ECbkd/7/):
$("li").click(function() {
$(".content").hide();
$('.item').eq($(this).index()).children('.content').fadeIn();
})
You could add this to be able to show content when clickin on header also:
$("h2", ".container").click(function() {
$(".content").hide();
$(this).parent().children('.content').fadeIn();
})
* EDIT START *
To let content toggle on click at header use this:
$("h2", ".container").click(function() {
$(".content").not($(this).parent().children('.content')).hide();
$(this).parent().children('.content').toggle();
})
Updated code here
http://jsfiddle.net/ECbkd/8/
* EDIT END *
This is based on html like this:
<ul>
<li>Item 01</li>
<li>Item 02</li>
<li>Item 03</li>
<li>Item 04</li>
<li>Item 05</li>
<li>Item 06</li>
<li>Item 07</li>
</ul>
<div class='container'>
<div class='item'>
<h2>Header 1</h2>
<div class='content'>Content 1</div>
</div>
<div class='item'>
<h2>Header 2</h2>
<div class='content'>Content 2</div>
</div>
<div class='item'>
<h2>Header 3</h2>
<div class='content'>Content 3</div>
</div>
<div class='item'>
<h2>Header 4</h2>
<div class='content'>Content 4</div>
</div>
<div class='item'>
<h2>Header 5</h2>
<div class='content'>Content 5</div>
</div>
<div class='item'>
<h2>Header 6</h2>
<div class='content'>Content 6</div>
</div>
<div class='item'>
<h2>Header 7</h2>
<div class='content'>Content 7</div>
</div>
</div>
you can show and hide multiple divs by using this simple method
function w3_open() {
document.getElementById("id01").style.display =
"block"; document.getElementById("id02").style.display = "block"
}
make sure that you are using w3.css
<button onclick="w3_open()" class="w3-button w3-opacity w3-black">Yesterday</button>
<div id="id01" class="w3-panel w3-white w3-card w3-display-container">
<span onclick="document.getElementById('id01').style.display='none'"
class="w3-button w3-display-topright">×</span>
<p class="w3-text-blue"><b>email.zip</b></p>
<p>https://www.w3schools.com/lib/email.zip</p>
<p class="w3-text-blue">Show in folder</p>
</div>
<div id="id02" class="test w3-panel w3-white w3-card w3-display-
container">
<span onclick="document.getElementById('id02').style.display='none'"
class="w3-button w3-display-topright">×</span>
<p class="w3-text-blue"><b>email.zip</b></p>
<p>https://www.w3schools.com/lib/email.zip</p>
<p class="w3-text-blue">Show in folder</p>
</div>
If you give the li's and the corresponding divs the same class, then you can say something like
function showDivs() {
$("li").click(function() {
$(".Content").hide();
clickedID = $(this).attr("class");
$('div#'+clickedID).fadeIn("slow");
})
}

Categories

Resources