Remove all element that does not have specific descendandt element in jquery - javascript

So i have the following markup:
<div class="festi-cart-products-content">
<table class="festi-cart-list">
<tbody>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount amount"></span>
</span>
</td>
</tr>
</tbody>
</table>
</div>
there are multiple tr elements, but only some of them have the innermost span with "woocommerce-Price-amount" class. The other have nothing after the "festi-cart-product-price" classed span.
I'm trying to remove all the tr elements that does NOT have the "woocommerce-Price-amount" span inside it using jQuery.
jQuery( document ).ajaxComplete(function() {
jQuery(".festi-cart-product-price:not(:has(>span))").each(function(){
jQuery(this).parent('tr.festi-cart.item').hide();
});
});
I've been trying to use the :not selector, but it doesnt seem to produce anything. I'm really not sure where it goes wrong.
Can any of you spot where my code is going wrong, or if it's a completely hopeless approach to a simple solution?

Use .filter function to match elements with specific requirements.
Use $('tr').find('.woocommerce-Price-amount').length > 0 to check if element exists in tr.
Than simply do .hide() (or .remove()) to filtered elements.
$(document).ready(function() {
var hasWoo = $('.festi-cart-list tr').filter(function() {
return $(this).find('.woocommerce-Price-amount').length !== 0;
});
hasWoo.hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="festi-cart-products-content">
<table class="festi-cart-list">
<tbody>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a>
<br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount amount">WOO</span>
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a>
<br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount amount">WOO</span>
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a>
<br>
<span class="festi-cart-product-price">
EMPTY
</span>
</td>
</tr>
</tbody>
</table>
</div>

You need to use .closest() method of jquery instead of .parent() method.

$('.btn').click(function(){
$('.festi-cart-item').each(function(){
var price = $(this).find('.festi-cart-product-price').children().hasClass('woocommerce-Price-amount');
if(!price)
$(this).hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="festi-cart-products-content">
<table class="festi-cart-list">
<tbody>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount"></span>
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img">
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
</span>
</td>
</tr>
</tbody>
</table>
</div>
<button class="btn">remove</button>

You're so close, your selector is valid and select the festi-cart-product-price that have no span's :
$(".festi-cart-product-price:not(:has('>span'))")
You've just to go up to the parents tr using closest() then hide them :
selector.closest('tr').hide();
Check This fiddle using setTimeout() to see the effect .
Hope this helps.
$(function() {
var selector = $(".festi-cart-product-price:not(:has('>span'))");
selector.closest('tr').hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="festi-cart-products-content">
<table class="festi-cart-list" border=1>
<tbody>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img"> IMAGE 1
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount amount">p1</span>
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img"> IMAGE 2
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img"> IMAGE 3
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
</span>
</td>
</tr>
<tr class="festi-cart-item ">
<td class="festi-cart-product-img"> IMAGE 4
</td>
<td class="festi-cart-product-title">
<a class="festi-cart-title" href="">product name</a><br>
<span class="festi-cart-product-price">
<span class="woocommerce-Price-amount amount">p4</span>
</span>
</td>
</tr>
</tbody>
</table>
</div>

How about this.
$("tr:not(:has(>.woocommerce-Price-amount))").hide()
Not tested.
Comes from this question: How to select elements which do not have a specific child element with JQuery which is worth a read on this type of 'descendant without feature' question.

Related

Hide entire <tr> if child's child

I have a table like this
$('td:contains("label label-primary")').parent().hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tbody>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-primary">
HIDE
</span>
</a>
</td>
</tr>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-danger">
SHOW
</span>
</a>
</td>
</tr>
</tbody>
I just want to be able to hide the table rows in which the span deep inside the tr has a specific class. In this case, label label-primary.
However, this does not seem to work. It hides nothing.
I am using this on tampermonkey to edit a webpage whose code I do not have edition access.
What am I doing wrong?
:contains() selects all elements that contain the specified text. You want to use find() (https://api.jquery.com/find/) or :has() https://api.jquery.com/has-selector/ to select based on a selector. You also have to write ".label.label-primary" to indicate they are classes.
$('td:has(.label.label-primary)').parent().hide();
OR
$('td').find('.label.label-primary').parent().hide();
Try this:
$('span').hasClass('label label-primary').parents('tr:first').hide();
Use jQuery :has() pseudo-class selector to check element contains at least one element that matches the specified selector. Or use has() method to filter out elements.
$('td:has(".label.label-primary")').parent().hide();
// or
$('tr:has("td .label.label-primary")').hide();
// or using has method
$('tr').has("td .label.label-primary").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-primary">
ble> HIDE
</span>
</a>
</td>
</tr>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-danger">
SHOW
</span>
</a>
</td>
</tr>
</tbody>
</table>
Here a one liner solution, hope it helps:
$("tr > td > a").find("span[class*='label label-primary']").closest("tr").hide()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-primary">
HIDE
</span>
</a>
</td>
</tr>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-danger">
SHOW
</span>
</a>
</td>
</tr>
</table>
</body>
May I suggest you this jquery script?
$('td').find(".label.label-primary").closest('tr').hide();
Try this..
$(".table td").filter(function() {
return $('span', this).hasClass('label.label-primary');
}).hide();
Here you go with a solution
$('table tr').each(function(){
$(this).find('span[class="label label-primary"]').hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-primary">
HIDE
</span>
</a>
</td>
</tr>
<tr>
<td>
<a class="pums" rel="tooltip">
<span class="label label-danger">
SHOW
</span>
</a>
</td>
</tr>
</table>
</body>
Just loop through all the tr & then find span with specific class.
Hope this will help you.

How to insert a scroll bar to a dev class

I want to add a scroll bar to the drop-down list of my code.It is actually a cart which shows the items in the cart when I click on the cart. I want to put a scroll bar to it to go down and see the items on it as the drop down box has a fixed size.
The code I used for the cart is:
<ul id="cart-dropdown" class="box-dropdown parent-arrow">
<li>
<div class="box-wrapper parent-border">
<p>Recently added item(s)</p>
<table class="cart-table">
<tr>
<td><img src="img/products/sample1.jpg" alt="product"></td>
<td>
<h6>Lorem ipsum dolor</h6>
<p>Product code PSBJ3</p>
</td>
<td>
<span class="quantity"><span class="light">1 x</span> $79.00</span>
Remove
</td>
</tr>
<tr>
<td><img src="img/products/sample1.jpg" alt="product"></td>
<td>
<h6>Lorem ipsum dolor</h6>
<p>Product code PSBJ3</p>
</td>
<td>
<span class="quantity"><span class="light">1 x</span> $79.00</span>
Remove
</td>
</tr>
<tr>
<td><img src="img/products/sample1.jpg" alt="product"></td>
<td>
<h6>Lorem ipsum dolor</h6>
<p>Product code PSBJ3</p>
</td>
<td>
<span class="quantity"><span class="light">1 x</span> $79.00</span>
Remove
</td>
</tr>
</table>
<br class="clearfix">
</div>
<div class="footer">
<table class="checkout-table pull-right">
<tr>
<td class="align-right">Tax:</td>
<td>$0.00</td>
</tr>
<tr>
<td class="align-right">Discount:</td>
<td>$37.00</td>
</tr>
<tr>
<td class="align-right"><strong>Total:</strong></td>
<td><strong class="parent-color">$999.00</strong></td>
</tr>
</table>
</div>
<div class="box-wrapper no-border">
<a class="button pull-right parent-background" href="#">Checkout</a>
<a class="button pull-right" href="order_info.html">View Cart</a>
</div>
</li>
</ul>
Have you tried adding overflow:scroll to your element's CSS?
You wants something like this ?
See this fiddle
#cart-dropdown { height: 300px; overflow-y: scroll;}

aaSorting in datatables not working properly

I have the following html in my first column. It shows a icon and an anchor tag.
<tr class="even">
<td class=" sorting_1">
<span data-sortvalue="0">
<img title="icon" src="icon.png">
0
</span>
</td>
</tr>
<tr class="odd">
<td class=" sorting_1">
<span data-sortvalue="1">
<img title="icon" src="icon.png">
1
</span>
</td>
</tr>
<tr class="even">
<td class=" sorting_1">
<span data-sortvalue="2">
<img title="icon" src="icon.png">
2
</span>
</td>
</tr>
....................
...................
...................
I am using aaSorting[0, 'asc']
In chrome, the 0 value is always staying at the top if the column is sorted either ascending or descending. All the remaining values are getting sorted accordingly.
In firefox, the sorting is completely broken.
The data attributes for sorting on your span tags need to be on the td tag. They should also be changed to just 'data-sort' or 'data-order'.
Check out DataTables data-attributes docs here
<tr class="even">
<td class=" sorting_1" data-sort="0">
<span>
<img title="icon" src="icon.png">
0
</span>
</td>
</tr>
...
...

JQuery how to fetch 2nd and 3rd TD content depend on 4th td click

Here the html markup having a table, i need to fetch td's content on click and save it into hidden field.
JS FIDDLE DEMO
Html Markup :
<table>
<tr style="color:#333333;background-color:#F7F6F3;" class="odd">
<td style="width:70px;" class=" sorting_1">1</td>
<td class=" "> <span id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_lblworkcategory">Customer Relations</span>
</td>
<td>one</td>
<td align="center" style="width:80px;" class=" ">
<img atl="edit" style="border-width:0px;cursor:pointer" src="images/edt1.png" class="update_1" title="Edit" id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_Image1">
</td>
<td class=" ">View Details
</td>
</tr>
<tr style="color:#333333;background-color:#F7F6F3;" class="odd">
<td style="width:70px;" class=" sorting_1">2</td>
<td class=" "> <span id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_lblworkcategory">Marketing </span>
</td>
<td>two</td>
<td align="center" style="width:80px;" class=" ">
<img atl="edit" style="border-width:0px;cursor:pointer" src="images/edt1.png" class="update_2" title="Edit" id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_Image1">
</td>
<td class=" ">View Details
</td>
</tr>
<tr style="color:#333333;background-color:#F7F6F3;" class="odd">
<td style="width:70px;" class=" sorting_1">3</td>
<td class=" "> <span id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_lblworkcategory">General</span>
</td>
<td>three</td>
<td align="center" style="width:80px;" class=" ">
<img atl="edit" style="border-width:0px;cursor:pointer" src="images/edt1.png" class="update_3" title="Edit" id="ctl00_ContentPlaceHolder1_gvworkcategory_ctl02_Image1">
</td>
<td class=" ">View Details
</td>
</tr>
</table>
<input id="hdid" type="hidden" />
<input id="hdcol2" type="hidden" />
<input id="hdcol3" type="hidden" />
JavaScript:
$("img[class^='update_']").live('click', function (event) {
var getId = $(this).attr("class")
$("#hdid").val(getId);
alert(getId)
});
$(this).closest('tr').find('td').eq(1).text();
and
$(this).closest('tr').find('td').eq(2).text();
Demo -----> http://jsfiddle.net/bpGXp/19/
Updated One -----> http://jsfiddle.net/bpGXp/21/ (with no whitespace)
have a look here: http://jsfiddle.net/bpGXp/18/
CODE
$("img[class^='update_']").live('click', function (event) {
var tr = $(this).closest("tr");
var tds = $(tr).find("td");
alert($(tds[0]).text() + " | " + $(tds[1]).text() + " | " + $(tds[2]).text());
//save col1, col2 and col3 values where you need it
});
hope it helps

Can I simulate a click on a hyperlink with jQuery code?

I have seen a couple of Stack Overflow posts which apparently relate to my question but none of them seem to do what I want.
I have a nested structure to display hierarchies (business units and brands) in a report:
<tr class="BrandRow1">
<td>
</td>
</tr>
<tr class='BrandRow1 StoreRow1'>
...
</tr>
<tr class='BrandRow1 StoreRow2'>
...
</tr>
and within this layout I use A tags to show/hide the 'child' content (by making use of the class attributes.
On load, I want to show all the 'nodes' if $('.StoreRow2').length is less than say 4.
I use a function to do the toggling:
// Allow an item to toggle other items' visibility
$(".VisibilityToggle").click(function () {
var ControlledClass = findClass($(this), "Toggles-");
if (ControlledClass != "") {
$("." + ControlledClass).toggle();
var Text = $(this).attr("rel");
if (Text != "") $(this).attr("rel", $(this).attr("rev")).attr("rev", Text).text(Text);
}
return false;
});
and what I'd like to do is trigger the 'toggling' open by calling this from JS code.
I thought something like '$(".VisibilityToggle").click()` would do what I want but this doesn't seem to work in my code, but does if I call it manually via the JS console in Chrome. I suspect its to do with my code running before the events have been bound to the page.
Can you please assist?
E.g. Markup
...
<tr class='BrandRow TRBrand_2'>
<td class="Level0">
<p>
<a id="DesktopApp0_ctl00_rptReportBrand_ctl01_A_Brand" rel="-" rev="+" class="button toggleButton SummaryToggle VisibilityToggle Toggles-BrandId_2">+</a> <strong>Brand2</strong>
</p>
</td>
<td>
<p>
34</p>
</td>
<td>
<p>
21</p>
</td>
<td>
<p>
22</p>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
0.0%</p>
</td>
<td>
<p>
1
</p>
</td>
<td>
<p>
34.0
</p>
</td>
</tr>
<tr class='SiteRow BrandId_2 TRStore_10'>
<td class="Level1">
<p>
<a id="DesktopApp0_ctl00_rptReportBrand_ctl01_rptSites_ctl00_A_Site" rel="-" rev="+" class="button toggleButton SummaryToggle VisibilityToggle Toggles-TRSiteUser_10">+</a> <span class="Bold">BrandX - Store 10</span>
</p>
</td>
<td>
<p>
14</p>
</td>
<td>
<p>
9</p>
</td>
<td>
<p>
8</p>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
0.0%</p>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
0.0
</p>
</td>
</tr>
<tr class='UserRow TRStoreUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Clarke Kent
</p>
</td>
<td>
<p>
3</p>
</td>
<td>
<p>
3</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_3">1</span><span class=" d5_3">2</span><span class=" d5_3">3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Alexie Sayle
</p>
</td>
<td>
<p>
2</p>
</td>
<td>
<p>
2</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_2">1</span><span class=" d5_2">2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Anders Bottom
</p>
</td>
<td>
<p>
1</p>
</td>
<td>
<p>
1</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_1">1</span><span>2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Daniella Ecclescake
</p>
</td>
<td>
<p>
1</p>
</td>
<td>
<p>
1</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_1">1</span><span>2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Mark E Smith
</p>
</td>
<td>
<p>
2</p>
</td>
<td>
<p>
1</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_1">1</span><span>2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Matthew Bannister
</p>
</td>
<td>
<p>
1</p>
</td>
<td>
<p>
1</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span class=" d5_1">1</span><span>2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
<tr class='UserRow TRSiteUser_10'>
<td class="Level2">
<p>
<img src="/img/icons/spacer.png" alt=" " />
Raj Patel
</p>
</td>
<td>
<p>
3</p>
</td>
<td>
<p>
0</p>
</td>
<td colspan="3" class="Drive5Graphic">
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span class=" plus">+</span>
</td>
<td>
<p>
0</p>
</td>
<td>
<p>
∞</p>
</td>
</tr>
...
you could use trigger:
$(".ABrand").trigger('click');
Is that what you wanted to achieve?
There's nothing wrong with the syntax you have: click() will trigger a click on the element.
$('.ABrand').click();
More markup is required to properly answer your question I would think, but take a look at live() and delegate(), which can be used outside document.ready if you're worried that things aren't getting hooked up in time.
$(".VisibilityToggle").live("click", function() { ... } );
$("#Container").delegate(".VisibilityToggle", click", function() { ... } );
If you're having trouble timing the event bind (i.e. the .click(function(){})) and the event trigger (i.e. the .click()), why not just chain the two together?
$('.ABrand').click(function() {
// do 3 flips, 5 somersaults and a pirouette
}).click();
This way, you're sure the click trigger gets called after the click bind.

Categories