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

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();

Related

How should I populate nested elements using jquery?

I want to display NEWS headines on my website. I want to populate it using Jquery. I have written the code but nothing is displayed on webpage.
HTML code:
<div class="col-md-4">
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<strong>Latest Headines</strong>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
</ul>
</div>
</div>
JS code:
$(document).ready(function() {
$.getJSON('https://newsapi.org/v1/articles?source=techcrunch&sortBy=top&apiKey=my-api-key',function(json) {
console.log(json);
console.log(json.articles.length);
function headlines (json) {
for(var i=0;i<5;i++){
$('.sidebar-nav li a h2').eq(i).html(json.articles[i].title);
}
}
});
});
I have made a class called sidebar then inside class I have placed list and anchor followed by <h2></h2> tag. I want to populate h2 tag with NEWS headlines but nothing is displayed on my webpage.
$('.sidebar-nav li').eq(i).find('h2').html(...)
li is the Nth element you're looking for, not h2.
For that matter, you should cache the nav element or the lis, to avoid hammering the DOM :
var $lis = $('.sidebar-nav li')
for(var i=0;i<5;i++){
$lis[i].find('h2').html(json.articles[i].title);
}
First of all: You don't call your function headlines so nothing goes to output ;)
Second one:
$('.sidebar-nav li a h2').eq(i)
will only work for the first item i think, because there is only 1 H2-Tag within the a-Tag.
I suggest giving all H"-Tag a class like ".headline" and itterating over them.
I hope this helps ;)

Traversing up and finding a child element with attribute equal to a specific value

I have a list UL that contains an element article that has an attribute data-level. I am traversing in Javascript through the articles. I am adding a replyto symbol to comments that have a data-level larger than 1, but to get the username of the parent, I need to traverse the comment list up and find an article element that has data-level="0" and get the username from that element.
I can't use jquery closest() because it doesn't check inside the element. If I use parent().parent() it will run closest() on the parent, which is also not good.
How can I run a closest() function or something familiar on the article element (red arrow in the image) to find the first article element above it that has its attribute equals to 0 (data-level="0").
Here's an the HTML code:
<ul>
<li>
<article itemprop="comment" itemscope="itemscope" itemtype="http://schema.org/Comment" data-user-id="28" id="comment-40" data-comment-id="40" class="comment-wrapper" data-level="0">
<header>
<p class="comment-title"> <span class="submitted-by"><span itemprop="author" itemscope="itemscope" itemtype="http://schema.org/Person"><span itemprop="name">yariv</span></span><span class="karma" title="Karma"><span class="fa fa-star"></span>0</span> •
<meta itemprop="dateCreated" content="2015-12-09T06:28:59Z">
<time class="date-submitted" datetime="2015-12-09T06:28:59Z">7 months ago</time>
</span>
</p>
</header>
<div class="comment-content">
<p class="comment-body" itemprop="text">fgdfg </p>
</div>
<div class="comment-options"><span data-already-voted="false" class="upvote"><span class="fa fa-thumbs-up"></span><span class="upvote-num" itemprop="upvoteCount">1</span></span><span class="reply" data-user-id="28" data-comment-id="40">Reply</span><span class="flag-comment">Flag</span>
</div>
<div class="notification"></div>
</article>
</li>
<li>
<article itemprop="comment" itemscope="itemscope" itemtype="http://schema.org/Comment" data-user-id="28" id="comment-42" data-comment-id="40" class="comment-wrapper" data-level="2">
<header>
<p class="comment-title"> <span class="submitted-by"><span itemprop="author" itemscope="itemscope" itemtype="http://schema.org/Person"><span itemprop="name">yariv</span></span><span class="karma" title="Karma"><span class="fa fa-star"></span>0</span> •
<meta itemprop="dateCreated" content="2015-12-09T06:28:59Z">
<time class="date-submitted" datetime="2015-12-09T06:28:59Z">7 months ago</time>
</span>
</p>
</header>
<div class="comment-content">
<p class="comment-body" itemprop="text">fgdfg </p>
</div>
<div class="comment-options"><span data-already-voted="false" class="upvote"><span class="fa fa-thumbs-up"></span><span class="upvote-num" itemprop="upvoteCount">1</span></span><span class="reply" data-user-id="28" data-comment-id="40">Reply</span><span class="flag-comment">Flag</span>
</div>
<div class="notification"></div>
</article>
</li>
</ul>
Note: There can be several comments with data-level="0" and I need the closest one above the article I am currently checking. In other words. For an <article> element, I need to find the closest (from above) <article> element that exists above it inside an li element that it's attribute data-level equals to zero.
You can use closest to get the li around the reply, and then prevAll with a :has([data-level=0]) filter, and then first to get the nearest (prevAll returns them in order of nearness rather than the usual document order):
var main = startingElement
.closest("li")
.prevAll(":has([data-level=0])")
.first()
.find("[data-level]");
Simplified example:
// Get our starting point:
var startingElement = $("#start");
// Find the "nearest" data-level=0
var main = startingElement
.closest("li")
.prevAll(":has([data-level=0])")
.first()
.find("[data-level]");
// Show what we got
console.log(main.text());
<ul>
<li>
<div data-level="0">first level 0</div>
</li>
<li>
<div data-level="1">first level 1</div>
</li>
<li>
<div data-level="2">first level 2</div>
</li>
<li>
<div data-level="0">second level 0</div>
</li>
<li>
<div data-level="1">second level 1</div>
</li>
<li>
<div data-level="2" id="start">second level 2</div>
</li>
<li>
<div data-level="0">third level 0</div>
</li>
<li>
<div data-level="1">third level 1</div>
</li>
<li>
<div data-level="2">third level 2</div>
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Note how our starting point was the li two siblings away from the one containing data-level="0", but we skipped the one in-between because it didn't match the :has condition.
To add a reply widget to each comment as mentioned, I'd do something like this. Keep in mind that each related comment references the original w/ [data-comment-id]
$(function() {
$("[data-level][data-level!='0']").each(function() {
var id = $(this).data('commentId'),
$comment = $('#comment-'+ id +''),
author = $comment.find('[itemprop="name"]').text();
$('<span> Reply to: </span>')
.appendTo($(this))
.append($(''+author+''));
});
})

jQuery select multiple same attribute value

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

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');

How to find nth p element?

I want to find the 3rd p tag of each category, based on first p tag's value.
e.g. The first p tag value is Tie, then find the quantity of it.
If the html element tree should be formatted in a better way, I am open to it. The html for all ul is written from code behind at C# to load items from database.
$("#wel div ").each(function(index, element) {
if ($(this).('p:nth-of-type(1)').html() == "Tie")
{
$(this).('p:nth-of-type(3)').css('background-color','red');
}
}
<div id="fel">Category1
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p> <!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
<div id="wel">Category2
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p><!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
JSFiddle
You can 2 top level elements with different ids fel and wel so need to use #wel div, #fel div to find the category div elements, then need to use .find() to find the p
$("#wel div, #fel div").each(function (index, element) {
if ($(this).find('p:nth-of-type(1)').html().trim() == "Tie") {
$(this).find('p:nth-of-type(3)').css('background-color', 'red');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="fel">Category1
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
<div id="wel">Category2
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
You can also do
$("#wel div, #fel div ").each(function (index, element) {
var $ps = $(this).find('p');
if ($ps.eq(0).html().trim() == "Tie") {
$ps.eq(2).css('background-color', 'red');
}
})
Demo: Fiddle
Here's the generic way of doing it
$(document).ready(function(){
var div = $('p:contains("Tie")').parent()
$('p:contains("Tie")').parent()
var price = $(div).find("p:contains('Price')").css('background-color','red');
console.log(price)
});
Please refer the fiddle here

Categories