I have managaged to count the total replies for one grandparent comment. The problem is that I have repeating markup and would like to count and display the replies for every grandparent comment. Here is what I have, also available as a fiddle:
<ol class="commentlist">
<li class="comment byuser comment-author-admin even thread-even depth-1" id="li-comment-677">
<div id="comment-677" class="grandparent">
<div class="comment-inner">comment-677
<div class="reply-info">
<div class="reply-has">has</div>
<div class="reply-count"></div>
<div class="reply-text">replies:</div>
</div>
</div>
<ul class="children">
<li class="comment byuser comment-author-admin odd alt depth-2" id="li-comment-678">
<div id="comment-678" class="parent">
<div class="comment-inner">comment-678</div>
<ul class="children">
<li class="comment byuser comment-author-admin even depth-3" id="li-comment-680">
<div id="comment-680">
<div class="comment-inner">comment-680</div>
</div>
</li>
<li class="comment byuser comment-author-admin odd alt depth-3" id="li-comment-686">
<div id="comment-686">
<div class="comment-inner">comment-686</div>
</div>
</li>
<li class="comment byuser comment-author-admin even depth-3" id="li-comment-688">
<div id="comment-688">
<div class="comment-inner">comment-688</div>
</div>
</li>
<li class="comment byuser comment-author-admin odd alt depth-3" id="li-comment-689">
<div id="comment-689">
<div class="comment-inner">comment-689</div>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li class="comment byuser comment-author-admin odd alt thread-odd thread-alt depth-1" id="li-comment-679">
<div id="comment-679" class="grandparent">
<div class="comment-inner">comment-679
<div class="reply-info">
<div class="reply-has">has</div>
<div class="reply-count"></div>
<div class="reply-text">replies:</div>
</div>
</div>
<ul class="children">
<li class="comment byuser comment-author-admin even depth-2" id="li-comment-682">
<div id="comment-682" class="parent">
<div class="comment-inner">comment-682</div>
</div>
</li>
<li class="comment byuser comment-author-admin odd alt depth-2" id="li-comment-690">
<div id="comment-690" class="parent">
<div class="comment-inner">comment-690</div>
</div>
</li>
<li class="comment byuser comment-author-admin even depth-3" id="li-comment-691">
<div id="comment-691">
<div class="comment-inner">comment-691</div>
</div>
</li>
</ul>
</div>
</li>
</ol>
The javascript:
var count = $("#li-comment-677 > .grandparent > .children > li").length
var count2 = $("#li-comment-677 > .grandparent > .children > .depth-2 > .parent > .children > li").length
var count3 = +count + +count2;
$('.reply-count').text(count3);
Try this dynamic logic,
$(".grandparent").each(function(ind, val){
var nTotalComment = $(val).find(".children .comment-inner").length;
$(val).find(".reply-count").html(nTotalComment);
});
Check this jsfiddle
You should iterate through the collection. You can use the text callback function which is executed once for each element in the collection. text method calls the each method behind the scenes, so it also implicitly iterates through the collection.
$('.commentlist .reply-count').text(function() {
return $(this).closest('.comment-inner')
.next('.children')
.find('.comment')
.length;
});
http://jsfiddle.net/tzLz6/
Related
I need to hide the children of siblings of the grand parent. I am stuck in complex situation where I have three <li> inside the <ul> . Now the structure of the html looks like this
<ul>
<li>..</li>
<li>..</li>
<li>..</li>
</ul>
inside each li this is the html
<div class="chbs-vehicle chbs-clear-fix">
<div class="chbs-vehicle-image chbs-vehicle-image-has-gallery" style="opacity: 1;">
</div>
<div class="chbs-vehicle-content">
<div class="chbs-vehicle-content-header">
<span>Sedan</span>
<a href="#" class="chbs-button chbs-button-style-2">
Select
<span class="chbs-meta-icon-tick"></span>
</a>
</div>
<div class="chbs-vehicle-content-price">€42.00</div>
</div>
</div>
So when I click on the chbs-button-style-2 I want to hide chbs-vehicle-content-price div inside all the other li which are the children of siblings of grandparent of this.
this is I where I am stuck
<script type="text/javascript">
jQuery(document).ready(function($){
$('.chbs-button-style-2').on('click', function() {
alert($(this).closest('li').siblings().children().find('.chbs-vehicle-content-price').html());
//Here I am getting Undefined
});
});
</script>
Use the .hide() method:
jQuery(document).ready(function($) {
$('.chbs-button-style-2').on('click', function() {
$(this).closest('li').siblings().children().find('.chbs-vehicle-content-price').hide();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>
<div class="chbs-vehicle chbs-clear-fix">
<div class="chbs-vehicle-image chbs-vehicle-image-has-gallery" style="opacity: 1;">
</div>
<div class="chbs-vehicle-content">
<div class="chbs-vehicle-content-header">
<span>Sedan</span>
<a href="#" class="chbs-button chbs-button-style-2">
Select
<span class="chbs-meta-icon-tick"></span>
</a>
</div>
<div class="chbs-vehicle-content-price">€42.00</div>
</div>
</div>
</li>
<li>
<div class="chbs-vehicle chbs-clear-fix">
<div class="chbs-vehicle-image chbs-vehicle-image-has-gallery" style="opacity: 1;">
</div>
<div class="chbs-vehicle-content">
<div class="chbs-vehicle-content-header">
<span>Sedan</span>
<a href="#" class="chbs-button chbs-button-style-2">
Select
<span class="chbs-meta-icon-tick"></span>
</a>
</div>
<div class="chbs-vehicle-content-price">€42.00</div>
</div>
</div>
</li>
<li>
<div class="chbs-vehicle chbs-clear-fix">
<div class="chbs-vehicle-image chbs-vehicle-image-has-gallery" style="opacity: 1;">
</div>
<div class="chbs-vehicle-content">
<div class="chbs-vehicle-content-header">
<span>Sedan</span>
<a href="#" class="chbs-button chbs-button-style-2">
Select
<span class="chbs-meta-icon-tick"></span>
</a>
</div>
<div class="chbs-vehicle-content-price">€42.00</div>
</div>
</div>
</li>
</ul>
I want to run a script where I can specifically select ID tag where parameters are _string_n_n where '_string' = release (in this case) and 'n' = are numbers # e.g. _release_8_3
Here's my code... where I wan to run the script and get content of tag where ID matches _string_n_n
<div class="sect2">
<h3 id="_release_8_3">Release 8.3</h3>
<div class="sect3">
<h4 id="_qa_test_release_1_2_4_to_take_a_look_at_manifest">QA TEST release 1.2.4 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_test_release_1_2_3_to_take_a_look_at_manifest">QA TEST release 1.2.3 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_release_8_3_1">QA release 8.3.1</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
<li>
<p>Bugs fixed in this release</p>
</li>
<li>
<p>Package updates:</p>
<div class="literalblock">
<div class="content">
<pre>user-portal 8.2</pre>
</div>
</div>
</li>
<li>
<p>Database migration scripts to run:</p>
<div class="literalblock">
<div class="content">
<pre>none</pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_release_8_2">Release 8.2</h3>
<div class="sect3">
<h4 id="_qa_test_release_1_2_4_to_take_a_look_at_manifest_2">QA TEST release 1.2.4 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_test_release_1_2_3_to_take_a_look_at_manifest_2">QA TEST release 1.2.3 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_release_8_2_6">QA release 8.2.6</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
<li>
<p>Bugs fixed in this release</p>
</li>
<li>
<p>Package updates:</p>
<div class="literalblock">
<div class="content">
<pre>user-portal 8.2</pre>
</div>
</div>
</li>
<li>
<p>Database migration scripts to run:</p>
<div class="literalblock">
<div class="content">
<pre>none</pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
Select all elements with an ID containing the following string (in this case _release_:
document.querySelectorAll("[id*='_release_']");
In jQuery: $("[id*='_release_']")
Here are more wildcards if you need a different reaction.
console.dir(document.querySelectorAll("[id*='_release_']"))
<div class="sect2">
<h3 id="_release_8_3">Release 8.3</h3>
<div class="sect3">
<h4 id="_qa_test_release_1_2_4_to_take_a_look_at_manifest">QA TEST release 1.2.4 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_test_release_1_2_3_to_take_a_look_at_manifest">QA TEST release 1.2.3 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_release_8_3_1">QA release 8.3.1</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
<li>
<p>Bugs fixed in this release</p>
</li>
<li>
<p>Package updates:</p>
<div class="literalblock">
<div class="content">
<pre>user-portal 8.2</pre>
</div>
</div>
</li>
<li>
<p>Database migration scripts to run:</p>
<div class="literalblock">
<div class="content">
<pre>none</pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_release_8_2">Release 8.2</h3>
<div class="sect3">
<h4 id="_qa_test_release_1_2_4_to_take_a_look_at_manifest_2">QA TEST release 1.2.4 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_test_release_1_2_3_to_take_a_look_at_manifest_2">QA TEST release 1.2.3 (to take a look at manifest)</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="_qa_release_8_2_6">QA release 8.2.6</h4>
<div class="ulist">
<ul>
<li>
<p>Release Manifest</p>
</li>
<li>
<p>Bugs fixed in this release</p>
</li>
<li>
<p>Package updates:</p>
<div class="literalblock">
<div class="content">
<pre>user-portal 8.2</pre>
</div>
</div>
</li>
<li>
<p>Database migration scripts to run:</p>
<div class="literalblock">
<div class="content">
<pre>none</pre>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
e.g. _release_8_3
var string = 'release';
var number1 = 8;
var number2 = 3;
var selector = '#_'+ [ string, number1, number2 ].join( '_' );
var element = $(selector);
element = document.querySelector(selector);
element = document.getElementById('_'+ [ string, number1, number2 ].join( '_' ) );
Have you tried any of these?
If instead you are wanting to find all ids that match a pattern, use a class instead. You can do pattern matching in lookups, however it is less performant and javascript will have to examine every single element in the dom to see if it matches your attribute pattern. Instead by giving like patterned id elements the same class, you can perform a class lookup which, along with id and tagName lookups, are some of the fastest lookups your browser can perform.
Otherwise if you feel you absolutely must do this, I would instead try to steer you towards using one of the more efficient selectors, and then using filter to find what you want. For instance in your example it looks like the pattern you gave is associated with h3 elements, so you could do.
$('h3').filter(function(){
return /^[_]release[_][0-9]+[_][0-9]+$/.test(this.id);
});
Provided I got my regex right, this would find all the h3 elements and then filter to return only those that match the pattern _release_#_# where # is any number
I have a list of images and separate list where each item is related to an image. Is it possible to have a hover event that fades the related image in and out using JQuery? I.e. when you hover over listid-1, image-1 fades in.
This is the best I could do:
$(document).ready(function(){
$( ".options li" ).hover(function( event ) {
$('.image-' + (this - ".listid")).toggleFade( "300" );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class='images'>
<img class='image-1' src='1.jpg'>
<img class='image-2' src='2.jpg'>
<img class='image-3' src='3.jpg'>
<img class='image-4' src='4.jpg'>
<img class='image-5' src='5.jpg'>
</div>
<div class="options">
<nav>
<ul>
<li class='listid-1'>One</li>
<li class='listid-2'>Two</li>
<li class='listid-3'>Three</li>
<li class='listid-4'>Four</li>
<li class='listid-5'>Five</li>
</ul>
</nav>
</div>
</div>
You have a couple of issues. Firstly concatenating the this reference with a string isn't going to give you a valid selector. Secondly, the method name is fadeToggle(), not toggleFade().
To fix the problems you could first group the li and img elements by giving them all the same respective classes, then relate the hovered li to the img by their indexes, something like this:
$(document).ready(function() {
$(".options .listid").hover(function(event) {
$('.image').eq($(this).index()).fadeToggle("300");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class='images'>
<img class='image' src='1.jpg'>
<img class='image' src='2.jpg'>
<img class='image' src='3.jpg'>
<img class='image' src='4.jpg'>
<img class='image' src='5.jpg'>
</div>
<div class="options">
<nav>
<ul>
<li class='listid'>One</li>
<li class='listid'>Two</li>
<li class='listid'>Three</li>
<li class='listid'>Four</li>
<li class='listid'>Five</li>
</ul>
</nav>
</div>
</div>
You can get class of current li and split at - to get number and use it as selector for image.
$('img').hide()
$(".options li").hover(function() {
$('.image-' + ($(this).attr('class').split('-')[1])).fadeToggle("300");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class='images'>
<img class='image-1' src='1.jpg' alt="1">
<img class='image-2' src='2.jpg' alt="2">
<img class='image-3' src='3.jpg' alt="3">
<img class='image-4' src='4.jpg' alt="4">
<img class='image-5' src='5.jpg' alt="5">
</div>
<div class="options">
<nav>
<ul>
<li class='listid-1'>One</li>
<li class='listid-2'>Two</li>
<li class='listid-3'>Three</li>
<li class='listid-4'>Four</li>
<li class='listid-5'>Five</li>
</ul>
</nav>
</div>
</div>
If you have multiple classes on images instead you can use data attributes to select images.
$('img').hide()
$(".options li").hover(function() {
$('img.image-' + $(this).data('img')).fadeToggle(300)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class='images'>
<img class='image-1' src='1.jpg' alt="1">
<img class='image-2' src='2.jpg' alt="2">
<img class='image-3' src='3.jpg' alt="3">
<img class='image-4' src='4.jpg' alt="4">
<img class='image-5' src='5.jpg' alt="5">
</div>
<div class="options">
<nav>
<ul>
<li data-img="1" class='listid-1'>One</li>
<li data-img="2" class='listid-2'>Two</li>
<li data-img="3" class='listid-3'>Three</li>
<li data-img="4" class='listid-4'>Four</li>
<li data-img="5" class='listid-5'>Five</li>
</ul>
</nav>
</div>
</div>
i try to add jQuery script that will toggle my footer columns, my problem is how I can make to stop toggling all items. Now when someone click on H4 tags all H4 tags are toggle together.
HTML:
<div class="row footer-cols">
<div class="col-sm-7 five-three">
<div class="row">
<div class="col-sm-4">
<h4>Information<span class="toggle"></span></h4>
<div class="footer-cols-content">
<ul>
<li>About Us</li>
<li>Customer Service</li>
<li>Privacy Policy</li>
</ul>
</div>
</div>
<div class="col-sm-4">
<h4>Why buy from us<span class="toggle"></span></h4>
<div class="footer-cols-content">
<ul>
<li>Shipping & Returns</li>
<li>Secure Shopping</li>
<li>International Shipping</li>
</ul>
</div>
</div>
</div>
</div>
</div>
jQuery SCRIPT
jQuery('.footer .footer-cols h4').append('<span class="toggle"></span>');
jQuery('.footer h4').on("click", function(){
if (jQuery(this).find('span').attr('class') == 'toggle opened') { jQuery(this).find('span').removeClass('opened').parents('.footer-cols').find('.footer-cols-content').slideToggle(); }
else {
jQuery(this).find('span').addClass('opened').parents('.footer-cols').find('.footer-cols-content').slideToggle();
}
});
You could also try the following code:
jQuery('.footer .footer-cols h4').append('<span class="toggle"></span>');
jQuery('.footer-cols h4').on("click", function(){
if (jQuery(this).find('span').attr('class') == 'toggle opened') { jQuery(this).find('span').removeClass('opened').parent().next().slideToggle();
}
else {
jQuery(this).find('span').addClass('opened').parent().next().slideToggle();
}
});
The problem with your selector is that with
parents('.footer-cols')
You basically select
<div class="row footer-cols"></div>
element on top. Thus
find('.footer-cols-content')
selects all child elements in it resulting all of them to slideToggle()
on the click handler change .parents('.footer-cols') for .parents('.col-sm-4')
You will need to add content to the span to give the user something to click
This one changes the plus/minus and hides other content
$(function() {
$(".footer-cols").find("h4").on("click", function() {
var $content = $(this).parent().find(".footer-cols-content");
var $span = $(this).find("span");
if ($span.length==0) $(this).append('<span class="toggle" />');
$(".footer-cols-content").not($content).hide();
$content.slideToggle();
$span.text($span.text() == "-" ? "+" : "-");
});
});
To add the span on the fly:
if ($span.length==0) {
$span=$('<span class="toggle" />');
$(this).append($span);
}
$(function() {
$(".footer-cols").find("h4").on("click", function() {
var $content = $(this).parent().find(".footer-cols-content");
var $span = $(this).find("span");
if ($span.length==0) {
$span=$('<span class="toggle" />');
$(this).append($span);
}
$(".footer-cols-content").not($content).hide();
$content.slideToggle();
$span.text($span.text() == "-" ? "+" : "-");
});
});
.footer-cols-content {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="row footer-cols">
<div class="col-sm-7 five-three">
<div class="row">
<div class="col-sm-4">
<h4>Information </h4>
<div class="footer-cols-content">
<ul>
<li>About Us
</li>
<li>Customer Service
</li>
<li>Privacy Policy
</li>
</ul>
</div>
</div>
<div class="col-sm-4">
<h4>Why buy from us <span class="toggle">+</span></h4>
<div class="footer-cols-content">
<ul>
<li>Shipping & Returns
</li>
<li>Secure Shopping
</li>
<li>International Shipping
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
I am not sure why are you appending span class but If I am not worng only slide toggle should do the work that you intend to do.
jQuery('.footer-cols h4').on("click", function(){
$(this).find('span').toggleClass('opened').end().next().slideToggle();
});
jQuery('.footer-cols h4').on("click", function(){
$(this).find('span').toggleClass('opened').end().next().slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row footer-cols">
<div class="col-sm-7 five-three">
<div class="row">
<div class="col-sm-4">
<h4>Information<span class="toggle"></span></h4>
<div class="footer-cols-content">
<ul>
<li>About Us</li>
<li>Customer Service</li>
<li>Privacy Policy</li>
</ul>
</div>
</div>
<div class="col-sm-4">
<h4>Why buy from us<span class="toggle"></span></h4>
<div class="footer-cols-content">
<ul>
<li>Shipping & Returns</li>
<li>Secure Shopping</li>
<li>International Shipping</li>
</ul>
</div>
</div>
</div>
</div>
</div>
The above code will work only when the footer-cols-content div is always next to h4. To avoid as such you can use parent().
jQuery('.footer h4').on("click", function(){
$(this).parent().find('footer-cols-content').slideToggle();
});
How can I remove div.count if the ul.elements has less than three li?
The html:
<ul class="list">
<li class="element level-1">
<div class="top">
<div class="content">dsssd</div>
<div class="count"></div>
<ul class="elements">
<li class="element level-2">
<div class="parent">
<div class="content">assd</div>
<ul class="elements">
<li class="element level-3">
<div id="dssd">
<div class="content">dssd</div>
</div>
</li>
<li class="element level-3">
<div id="fddd">
<div class="content">gfddg</div>
</div>
</li>
<li class="element level-3">
<div id="fdff">
<div class="content">ddee</div>
</div>
</li>
<li class="element level-3">
<div id="gfgggf">
<div class="content">hghg</div>
</div>
</li>
</ul>
</div>
</li>
<li class="element level-2">
<div id="gfgf" class="parent">
<div class="content">eeer</div>
</div>
</li>
</ul>
</div>
</li>
<li class="element level-1">
<div id="hjjh" class="top">
<div class="content">hjhj</div>
<div class="count"></div>
<ul class="elements">
<li class="element level-2">
<div id="yuyuu" class="parent">
<div class="content">uyyu</div>
<ul class="elements">
<li class="element level-3">
<div id="trtrrt">
<div class="content">trtrtr</div>
</div>
</li>
</ul>
</div>
</li>
<li class="element level-2">
<div id="opop" class="parent">
<div class="content">opop</div>
</div>
</li>
<li class="element level-2">
<div id="kjkj" class="parent">
<div class="content">kjkj</div>
</div>
</li>
</ul>
</div>
</li>
<li class="element level-1">
<div id="qwwq" class="top">
<div class="content">qwqw</div>
<div class="count"></div>
<ul class="elements">
<li class="element level-2">
<div id="ytty" class="parent">
<div class="content">tyty</div>
<ul class="elements">
<li class="element level-3">
<div id="ghghgh">
<div class="content">jhhj</div>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
the script:
$('.list .count').text(function() {
var length = $(this).closest('.count')
.next('.elements')
.find('.element')
.length
;
if (length > 2) {
return length;
}
});
css:
.elements {
clear: both;
}
.level-1 {
margin-bottom: 10px;
}
.count {
background-color: pink; float: left; padding: 5px;
}
fiddle
$('div.count').find('ul.elements').filter(function() {
return $(this).children('li').length < 3;
})
.end().remove();
EDIT
The following should work with the updated markup:
$('div.count').each(function() {
var that = $(this),
upUL = that.next('ul.elements');
upUL.add( upUL.find('ul.elements') ).filter(function() {
return $(this).children('li').length < 3;
}).length === 0 || that.remove();
});
JS FIDDLE DEMO
Just add $(this).remove() to remove div in else part in your exisiting text() function like this:
if (length > 2) {
return length;
}
else {
$(this).remove(); // less than 3 remove it
}
UPDATED FIDDLE
or add another if:
if (length < 3) {
$(this).remove();
}
Alternative to selected answer: rather than removing the "count" entirely (in case you are live-updating the contents of those lists with JavaScript later,) why not just hide it? Then you can display it again if the length situation changes.
This seemed to work:
$('.list .count').text(function() {
var length = $(this)
.closest('.count')
.next('.elements')
.find('.element')
.length;
if (length > 2) {
return length;
} else {
$(this).closest('.count').hide();
}
});
http://jsfiddle.net/qxD7W/