jQuery select multiple same attribute value - javascript

I want select DOMs using jQuery.
HTML code
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check"></span>
<img>
<a title="low">zwc</a>
</span>
</li>
I want select "check" class span DOMs what have "a tag" has "high" title in same level.
I tried to click that DOMs using this query:
$('a[title="high"]').each(function() {
$(this).prev().prev().click();
})
but this code have only first match value.
How can I select all DOMs?
My mistake. I want "check" not "con". Thanks.
The point of this question is "all" DOMs what have "high" title attr should be clicked.

you can use .closest().find()
$('a[title="high"]').each(function() {
$(this).closest('.node').find('.con').click();
})
Working Demo

You can use filter() to filter out elements from a set based on condition.
// Get all spans having class `con`
$('span.con').filter(function () {
// If this element has anchor element sibling with `high` as Title
// then return true, else return false
return $(this).siblings('a[title="high"]').length;
}).css('color', 'green');
$('span.con').filter(function() {
return $(this).siblings('a[title="high"]').length;
}).css('color', 'green');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<span class="node">
<span class="con">First</span>
<span class="check"></span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Second</span>
<span class="check"></span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Third</span>
<span class="check"></span>
<img>
<a title="low">zwc</a>
</span>
</li>
</ul>

Instead of .prev().prev() use siblings() to find the items in the same level and filter with .con.
$('a[title="high"]').each(function() {
$(this).siblings('.con').click();
});
If you want to know why actually your code is not working, you called prev() two times. By first one you select img, the second one will select .check. So you need to call prev() third time to reach .con. This is always confusing and may break anytime if you add more element in between. That's why this approach is not recommended.

As CSS and jQuery don't have previous sibling selector, you can use General sibling selector.
You can use General sibling selectors to select elements having specific attribute and then use jQuery's sibling() to select span.con.
$('span.check ~ a[title="high"]') // Select all anchors having `title` as "high"
// Which are next siblings of `span` having class of `check`
.siblings('span.check') // Select sibling `span` having class `con`
.css('color', 'green');
The selector $('span.check ~ a[title="high"]') will select anchor elements, to get the span, use siblings.
$('span.check ~ a[title="high"]')
.siblings('span.check')
.each(function() {
$(this).css('color', 'green').click();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<span class="node">
<span class="con">First</span>
<span class="check">First Check</span>
<img>
<a title="high">abc</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Second</span>
<span class="check">Second Check</span>
<img>
<a title="high">def</a>
</span>
</li>
<li>
<span class="node">
<span class="con">Third</span>
<span class="check">Third Check</span>
<img>
<a title="low">zwc</a>
</span>
</li>
</ul>

Actually your code is working fine. See I tried this,
HTML :
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span :'+1);"></span>
<img onclick="console.log('img :'+1);">
<a id = "m1" title="high" onclick="console.log('a :'+1);">abc</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span :'+2);"></span>
<img onclick="console.log('img :'+2);">
<a id = "m2" title="high" onclick="console.log('a : '+2);">def</a>
</span>
</li>
<li>
<span class="node>
<span class="con"></span>
<span class="check" onclick="console.log('span : low');"></span>
<img onclick="console.log('img : low');">
<a id = "m3" title="low" onclick="console.log('low');">zwc</a>
</span>
</li>
JS:
$(function(){
$('a[title="high"]').each(function() {
// if you want to click all <a>
$(this).click();
// if you want to click all <img>
$(this).prev().click();
// if you want to click all <span> having class check
$(this).prev().prev().click();
});});
Console:
a :1
img :1
span :1
a : 2
img :2
span :2

Related

jQuery if list item contains ''-" .remove()?

I am restyling a list of related articles in a li and I would like to remove the "-" between the a tag and span without messing with the original content on the page (links). I must use jQuery and I'm not sure if there is a simple way of doing this.
<div class="related-articles card">
<h3 class="h2">
<i class="fa fa-book text-brand-primary-dark"></i> Related Articles
</h3>
<ul>
<li>
Title One
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three
-
<span> Some RelatedPreview Text... </span>
</li>
</ul>
Here is my solution, get the children elements and assign it back, so the plain text present (-) will get removed!
$('.related-articles li').each(function() {
$(this).html($(this).children());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="related-articles card">
<h3 class="h2">
<i class="fa fa-book text-brand-primary-dark"></i> Related Articles
</h3>
<ul>
<li>
Title One -
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two -
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three -
<span> Some RelatedPreview Text... </span>
</li>
</ul>
One way would be to loop through each <li>, extract the <a> and <span> elements and stitch them together manually, like this:
$("ul > li").each( (i, li) => {
const $li = $(li);
const $a = $li.find("a");
const $span = $li.find("span");
//create a temp element with just the <a> and <span>
const $tempItem = $("<li></li>");
$tempItem.append( $a ).append( $span );
//copy new HTML into old element
$li.html( $tempItem.html () );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
Title One
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Two
-
<span> Some Related Preview Text... </span>
</li>
<li>
Title Three
-
<span> Some RelatedPreview Text... </span>
</li>
</ul>
One option is:
$('.related-articles li a').map(function() {
return this.nextSibling;
}).remove();

Combine the class selector with nth-child() or eq()

I have a list and I want to get the first item after each heading item. I need to do this all in one line as im using Nightwatch, which hasnt got all the elasticity of using jquery in the browser. What I have is:
// This works
console.log('first item after first header is ');
console.log($('#ul-wrapper li.heading ~ li:first').text());
// This doesnt
console.log('first item after second header is ');
console.log($('#ul-wrapper li.heading:nth-child(2) ~ li:first').text());
So essentially i need to combine the class selector with nth-child() or eq(). Html is:
<ul id="ul-wrapper">
<li class="heading">
Heading 1
</li>
<li>
<label>
<a>
Item 1
</a>
</label>
</li>
<li>
<label>
<a>
Item 2
</a>
</label>
</li>
<li class="heading">
Heading 2
</li>
<li>
<label>
<a>
Item 3
</a>
</label>
</li>
<li>
<label>
<a>
Item 4
</a>
</label>
</li>
</ul>
The fiddle is here
I have a list and I want to get the first item after each heading item
If I understand right you can use Adjacent sibling selectors
$('#ul-wrapper li.heading + li').css("background", "red");
.heading {
background-color: lightgreen;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-wrapper" style="">
<li class="heading">
Heading 1
</li>
<li>
<label>
<a>
Item 1
</a>
</label>
</li>
<li>
<label>
<a>
Item 2
</a>
</label>
</li>
<li class="heading">
Heading 2
</li>
<li>
<label>
<a>
Item 3
</a>
</label>
</li>
<li>
<label>
<a>
Item 4
</a>
</label>
</li>
</ul>
The :nth-child() pseudo class only looks at the index of the element relative to the parent element. Similarly, :nth-of-type() will only look at the index of the element based on the type. Neither the :nth-child()/:nth-of-type() pseudo classes will consider the element's class attribute.
With that being said, the :eq() method will select an element by it's index based on the filtered set (which is exactly what you want in this case). However, it's worth pointing out that :eq() has an index that is zero-based (unlike :nth-child()/:nth-of-type()). In this case, you would need to use eq(1) to access the second li element:
Example Here
$('#ul-wrapper li.heading:eq(1) ~ li:first');
You could also use the adjacent sibling combinator, +:
Example Here
$('#ul-wrapper li.heading:eq(1) + li');

Get Ancestor by class name

I have a component which have buttons and list both of which perform events on click. I need a common way to get the ancestor element for these elements. The structure looks like
<div class='a'>
<button class ='b' data-name="hello">
<span class ='c'>clickMe
<span>somehting</span>
</span>
<button>
<ul class ='d'>
<li data-name="about">
<span class ='e'>something here
<span>somehting</span>
</span>
</li>
<li data-name="home">
<span class ='e'>something elser here
<span>somehting</span>
</span>
</li>
</ul>
</div>
I try to get the element button and li because I need to get data-name information.
e.target is the element that was clicked
var targetel = goog.dom.getAncestorByClass(e.target,null,class??);
Not sure how to get the correct element irrespective if its a button or li. Do i need to add a unique class to all the elements ?
Just use e.currentTarget
var result = document.querySelector('#result');
var clickables = document.querySelectorAll('button, li');
//add click listener to elements
for (var i = 0, l = clickables.length; i < l; i++) {
clickables[i].addEventListener('click', getDataName);
}
function getDataName(e) {
var dataName = e.currentTarget.getAttribute('data-name');
result.textContent = dataName;
}
<div class='a'>
<button class ='b' data-name="hello">
<span class ='c'>clickMe
<span>somehting</span>
</span>
</button>
<ul class ='d'>
<li data-name="about">
<span class ='e'>something here
<span>somehting</span>
</span>
</li>
<li data-name="home">
<span class ='e'>something elser here
<span>somehting</span>
</span>
</li>
</ul>
</div>
<div id="result">data-name of clicked element goes here</div>
https://api.jquery.com/parents/
Use the jquery.parents("li") function. it will select all the parents that match your css filter. so you can do
var parentli = targete1.parents("li");
var button = targete1.parents("div").children[0];
Or something similar to that.
EDIT:
Not sure why i got downvoted, here is my idea in action.
maybe press f12 to inspect element and look at the console log.
var onClick = function () {
var parentEl = $(this).parents("button, li")[0];
console.log(parentEl);
$("#result")[0].innerText = parentEl.getAttribute("data-name");
};
$('span.c').click(onClick);
$('li span.e').click(onClick);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='a'>
<button class='b' data-name="hello">
<span class='c'>clickMe
<span>something</span>
</span>
</button>
<ul class ='d'>
<li data-name="about">
<span class ='e'>something here
<span>somehting</span>
</span>
</li>
<li data-name="home">
<span class ='e'>something elser here
<span>something</span>
</span>
</li>
</ul>
</div>
<div id="result">result goes here</div>

Changing Dom Element in Li without reloading?

I somehow got trouble finding a way to change the Dom Element of Li Object according to the Votes.
So a user could Upvote an Link and if the Link got more Upvotes then another it should go up until it has less then the next higher one basiclly.
Here the Html Code :
<li>
<span><span class="icon icon"></span><a href="http://"
rel="nofollow" target="_blank">Name</a> </span>
<div class="right"><button>+</button><span id="displayCount">(0).
</span></div>
</li>
<li>
<span><span class="icon icon2"></span><a href="http://"
rel="nofollow" target="_blank">Name</a> </span>
<div class="right"><button>+</button><span id="displayCount">(0).
</span></div>
</li>
And the Js:
$('button').click(function () {
var newCount = parseInt($('#displayCount').text()) + 1;
$('#displayCount').text(newCount);
});
So the Button does Count, however I can't figure out how to actually change the li with Icon 2 if the count is higher above the Li with Icon, without reloading the Page. How am I able to do this?
Cheers,
Julian
<li>
<span><span class="icon icon"></span><a href="http://"
rel="nofollow" target="_blank">Name</a> </span>
<div class="right"><button class="add">+</button><span class="displayCount">(0).
</span></div>
</li>
<li>
<span><span class="icon icon2"></span><a href="http://"
rel="nofollow" target="_blank">Name</a> </span>
<div class="right"><button class="add">+</button><span class="displayCount">(0).
</span></div>
</li>
$('button.add').click(function () {
var $element = $(this).parent().find('.displayCount:first');
var newCount = parseInt($element.text()) + 1;
$element.text('('+newCount+')');
});

Find a child tag after getting an array of all parent tags

I have an unordered list and in each item is
<span>
<span>
<img />
<a />
<b />
</span>
</span>
There is other data inside the nodes, but I can't post that.
My problem is that I need to get some attributes is the first <span> and the <a> tag.
I can get the first span successfully with
$NeighborhoodSpans = $(sNeighborhoodHTML).find('span');
$(sNeighborhoodHTML) is the html list
then, I iterate like this:
$NeighborhoodSpans.each(function ()
{
}
I can't get the 'a' tags. I've tried
$neighborhoodAnchorTag = $(this).html().filter('a');
$Hi = $(this).html();
$neighborhoodAnchorTag = $Hi.find('a');
But jquery says that .find and .filter aren't supported functions of the object.
Can someone please help me with getting attributes in both the first <span> tag an attribute in the <a> tag which is in the <span> tag?
if you have something like
<ul>
<li>
<span>
<span>
<img />
<a /> // this text will print
<b />
</span>
</span>
<span>
<span>
<img />
<a />
<b />
</span>
</span>
</li>
<li>
<span>
<span>
<img />
<a /> //and this text will print
<b />
</span>
</span>
</li>
</ul>
loop throught li
$('li').each(function(){
console.log($(this).find('> span:first > span > a').text());
});

Categories