jQuery select all children of closest - javascript

I want to add the .red-border class to a #container div and all <td>s in the closest <tr>.
But by using .closest() I only get the elements immediate parent <td>.
Is there a way I can target all children of the closest <tr>?
My code is below.
My current erroneous JS:
$('#myelement').closest('.container, tr td').addClass('red-border');
Obviously, this only targets 1 td. I want to encompass all of them.
My HTML:
<div id="container">
<span class="myelement">element</span>
</div>
<table>
<tr>
<td></td>
<td><span class="myelement">element</span></td>
<td></td>
</tr>
</table>
Edit: normally I might use the .find() function but this wouldnt work with the or operator.

I hope this is what you are expecting. You need to iterate through each tr and add red-border class to its first td with td:first selector as below
$(document).ready(function() {
$('#container').addClass('red-border');
$('tr').each(function(){
$(this).find('td:first').addClass('red-border');
})
})
.red-border{
border:red 2px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<span class="myelement">element</span>
</div>
<table>
<tr>
<td>First row First TD</td>
<td><span class="myelement">element</span>
</td>
<td></td>
</tr>
<tr>
<td>Second row First TD</td>
<td><span class="myelement">element</span>
</td>
<td></td>
</tr>
</table>

According to your structure you can go for this:
$(".myelement").parents("#container").addClass('red-border').siblings("table").find("tr").eq(0).children().addClass('red-border');
target the parent #container using parents(). This will give nothing for the span inside td. Then target its sibling table and the first tr by using eq(0).

why do you want it in a single line? just split it to two, it will be simpler.
$('.myelement').closest('#container').addClass('red-border');
$('.myelement').closest('tr').find('td').addClass('red-border');
by the way, you called #myelement when your tag had a class myelement. It should be called using .myelement. And the container is an id so #container

Call class element using .myelement instead of #myelement
$('.myelement').closest('.container, tr td').css({"color": "red", "border": "2px solid red"});
or
$('.myelement').closest('.container, tr td').addClass('red-border');

Related

How do I display the content of closest <td> on javascript?

I have looked everywhere, but my code does not work at all. I simply want to display the content of the td I'm clicking on.
I have this table:
<tr class='rowData' tooltip='{caracteristicas}'>
<td nowrap class='Body'><a href='{caracteristicas}' target="_blank" style="color:black" onClick='return confirm("VOCÊ SERÁ REDIRECIONADO PARA:\r\r {caracteristicas}")'>{inputDescItem}</a></td>
<td nowrap class='Body' align='right'>{quantidade} {hiddenCodigoItem}</td>
<td nowrap class='Body' align='center'>{grupoEstoque}</td>
<td nowrap class='Body' align='center'>{inputCodigoItem}</td>
<td nowrap class='Body' align='center'>{btnAtualizaItem}</td>
<td nowrap class='Body' align='center'><button type="button" class="btnTest">Assign</button></td>
<td nowrap class='Body' align='center' class="testNameClass" name="output" style="display:none;">{caracteristicas}</td>
</tr>
I want it so that when I click on the CLICK ME tag, it will display (in a pop-up, alert, modal or anything) the content of the below tag (that I'm not displaying).
I have the following javascript:
$("btnTest").on("click", function() {
alert($(this).closest('tr').find('testNameClass').val());
});
I'm not very good at JS so please go easy on me.
Look like you missing
$(".btnTest") instead of $("btnTest")
and just try
$(".btnTest").on("click", function() {
alert($(this).parents('tr').find('.testNameClass').val());
});
To target specific elements using a class you need to use a dot in front of the class name. In your case .btnTest and .testNameClass.
$(".btnTest").on("click", function() {
alert($(this).closest('tr').find('.testNameClass').text());
});
As you are looking for the text inside the td element you should use .text() instead of .val()
In the below example column ent_3 is hidden and you will get its values using the script mentioned above.
$(".btnTest").on("click", function() {
alert($(this).closest('tr').find('.testNameClass').text());
});
.testNameClass {
display: none;
}
table {
border-collapse: collapse;
}
th, td { border: 1px solid #000; padding: 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" id="dataTable">
<thead>
<tr>
<th>pk</th>
<th>ent_1</th>
<th>ent_2</th>
<th>ent_3</th>
</tr>
</thead>
<tbody>
<tr>
<td>PK Row 0</td>
<td>Ent_1</td>
<td><button type="button" class="btnTest">Assign</button></td>
<td class="testNameClass">Row 0 Ent_3</td>
</tr>
<tr>
<td>PK Row 1</td>
<td>Ent_1</td>
<td><button type="button" class="btnTest">Assign</button></td>
<td class="testNameClass">Row 1 Ent_3</td>
</tr>
<tr>
<td>PK Row 2</td>
<td>Ent_1</td>
<td><button type="button" class="btnTest">Assign</button></td>
<td class="testNameClass">Row 2 Ent_3</td>
</tr>
</tbody>
</table>
Your method will be handed a reference to the MouseEvent which represents details of the click. Since it is an Event, it has a currentTarget which represents an "element" in the so-called DOM ... an internal data-structure which represents the HTML. This data structure is in the form of a tree, where each node has one parent, two siblings, and some children. You can now write code to "walk up the tree" until you encounter a td node. The first one you come to is the innermost containing td.
I think you are targeting is incorrect use a . before the class name - also I see two classes in one element I set this up for you here have a look
https://jsfiddle.net/hw0ansyj/1/
$(".btnTest").on("click", function() {
alert($('.testNameClass').html());
});

jQuery selector for sibling of a label in a table

I'm writing a user-script for a third-party website and looking to select value inside a table which has a preceding TD with a label.
Question: I'm looking to get value1 as the result, but it's selecting the containing TD as well, so I get something else too.
Limitations
Can't modify the HTML to be more query-friendly (duh, it's not my site ;)
The table has no ids (I added them for easier discussion), not even the <table> itself has an id.
The count of the rows is dynamic, so no tr:nth-child.
Tried
I found this question: Selecting an element which has another element as direct child and used the direct selector (tr:has(> td:contains), but it still selects more than needed, because the outer TD also transitively contains label1 and has a sibling.
Notice that the background I set is transparent to show that multiple TDs are selected.
$(function() {
$('#result').text($('tr:has(td:contains("label1")) > td:nth-child(2)').text())
$('tr:has(td:contains("label1"))').css("background", "rgba(255,0,0,0.3)");
});
table { border-collapse: collapse; }
table, th, td { border: 1px solid black; }
td { padding: 4px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<tr>
<td id="outer">
<table>
<tr><td id="known-info">label1</td><td id="want-to-select">value1</td></tr>
<tr><td>label2</td><td>value2</td></tr>
</table>
</td>
<td id="outer-sibling">something else</td>
</tr>
</table>
<br/>
This should be "value1": "<span id="result"></span>"
You could use :not(:has(td)) in your selector so it should be
$('td:contains("label1"):not(:has(td))').next().text()
This will select td that contains label1 text, but it will ignore parent td because it has another td inside.
var el = $('td:contains("label1"):not(:has(td))').next()
$('#result').text(el.text())
el.css('background', 'blue')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td id="outer">
<table>
<tr>
<td id="known-info">label1</td>
<td id="want-to-select">value1</td>
</tr>
<tr>
<td>label2</td>
<td>value2</td>
</tr>
</table>
</td>
<td id="outer-sibling">something else</td>
</tr>
</table>
<br/> This should be "value1": "<span id="result"></span>"

How to apply CSS to children of TR based on TD content?

I'd like to hide a <div> or <td> inside the <tr> based on the content inside that <tr>.
If Stackoverflow is found inside a <tr>, hide .buttons from that <tr>.
This is what I've got so far.
<table class="sites">
<tbody>
<tr>
<td>
<div class="name">Stackoverflow</div>
</td>
<td>
<div class="buttons">
buttons
</div>
</td>
</tr>
<tr>
<td>
<class name="">Stackexchange</class>
</td>
<td>
<div class="buttons">
buttons
</div>
</td>
</tr>
</tbody>
</table>
var t = $(".sites tr .name:contains('Stackoverflow')");
var d = t.parent('tr').children('.buttons');
d.css( "display", "none" );
I've made a fiddle: https://jsfiddle.net/3jk8e3b2/3/
Your traverses are not going to appropriate levels.
parent() is only immediate parent element, children() are only immediate child nodes
In your case parent of .name is a <td> not <tr> and the buttons are not immediate children of <tr> either.
Use closest() or parents() to allow going up more than one level. Use find() to allow going deeper than children()
Try:
var t = $(".sites tr .name:contains('Stackoverflow')");
t.closest('tr').find('.buttons').hide();
DEMO

jQuery - Selecting the first <a> in the first <td> of a <tr>

I have the following markup:
<tr>
<td>
<a>foo</a>
</td>
<td>bar</td>
<td>
<a class="delete-btn">delete</a>
</td>
</tr>
I've already hooked up a click event handler using jquery $(".delete-btn") the problem is that inside the click event handler I need the text of the first element (foo).
I'm already getting the value I need with this call:
$(this).closest("tr").children().first().children().first("a")
but I feel it's too verbose. Is there a better way to accomplish this?
I don't like this either, but... it's exactly what you're looking for:
$(this).closest("tr").find("> td:first-child > a");
You can make use of jQuery's :first pseudo-selector.
In this instance, your entire selector would be:
$('tr td:first a:first') (for the first <tr> only)
$('tr').find('td:first a:first') (for every <tr>)
Example:
$(document).ready(function(){
$('.delete-btn').click(function(){
$('tr').find('td:first a:first').hide();
})
});
table, tr, td {
border: 1px solid rgb(191,191,191);
border-collapse: collapse;
}
td {
padding: 12px;
}
.delete-btn {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td><a>foo</a></td>
<td>bar</td>
<td><a class="delete-btn">delete</a></td>
</tr>
<tr>
<td><a>foo</a></td>
<td>bar</td>
<td><a>baz</a></td>
</tr>
</table>

Select element if contains text

I can't get this one to work and I can't find any similar question that does the same what I want.
I have a table with rows like this:
<div class="gui-table">
<table>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><p class="customfields">Size</p></td>
<td></td>
</tr>
//etc...
I want to check if all the second cells have the text "size" in it! If so then hide the third td.
So what I thought what would work is this:
$('.gui-table tr').each(function(){
if ($('td:nth-child(2) .customfields:contains("Size")').length > 0) {
$(this).css('visibillity', 'hidden');
}
});
This doesn't work! Does anybody see what is wrong with this?
Just do:
$('.gui-table .customfields:contains("Size")').css('visibility', 'hidden');
Fiddle: http://jsfiddle.net/cfmrngcc/2/
Assuming I understand your question correctly the following should do it:
$('.gui-table p.customfields:contains("Size")').parent().next().hide();
td { border: 1px solid black; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gui-table">
<table>
<tr>
<td></td>
<td></td>
<td>Shown</td>
</tr>
<tr>
<td></td>
<td><p class="customfields">Size</p></td>
<td>Hidden</td>
</tr>
</table>
</div>
This will hide the next table cell after any table cell containing a p tag with the text Size.
It works by finding the P tags containing size inside the gui-table - $('.gui-table p.customfields:contains("Size")')
Then using .parent() to select it's parent table cell.
And finally .next() and .hide() to select the next table cell and hide it.
I banged around on this and came up with this JSFiddle that should get you going again. The essential function is much like you started with but modified like this:
function doItNow(e)
{
$('.gui-table tr').each(function ()
{
$('td:nth-child(2) .customfields:contains("Size")').each(function ()
{
$(this).parents('tr').children('td:nth-child(3)').css('visibility', 'hidden');
});
});
}
Note that the inner each() is passing the paragraph element and not the cell element. So I traversed up the parents() chain until I find the row and hide the 3rd child. You might be able to code this without the inner each but I am too lazy to be that complicated!
If you only want to hide the third column, when there is the word 'size' in the second one you can do this in that way:
$('.gui-table td:nth-child(2):contains("Size")').next().css('visibility', 'hidden');
Here is a jsfiddle:
http://jsfiddle.net/0qczvak5/
The explanation:
Select all elements with the class name .gui-table, select all second tds with td:nth-child(2), filter them with :contains("Size"). Now you have all second tds with the word "Size" and with .next() you get the following cell (the third one) and you hide it with .css('visibility', 'hidden').
$(".gui-table tr td:nth-child(2)").each(
function (index,tag){
if ($(tag).find("p").text() == "Size")
$(tag).css('visibility', 'hidden');
}
)
This is will work .

Categories