I have a table with html controls such as a select, etc.. Now when I click on a tag I want to get span value in first td
And I tried this:
$('tr > td a').on('click', function(e) {
alert($(this).parent().find('td').eq(0).find('span').html());
});
table, tr, td, th {
width: 750px;
border: 1px solid black;
border-collapse: collapse;
align: centre
}
select, a {
display: block;
}
<table>
<tr>
<th>Name</th>
<th>Clicks</th>
<th>Clicks2</th>
</tr>
<tr>
<td>
<span id="span1">Hi!</span>
Save
</td>
<td style="block">
Click Me
<select>
<option>1</option>
</select>
</td>
<td>
Click Me
<select>
<option>2</option>
</select>
</td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
Fiddle link
I tried to show popup only when a is clicked but it is poping up every time td is clicked.
So I gave a tag a class Click and tried to achieve the same but couldn't.
How to show popup only when a clicked
Your a is display:block so it maintains the whole space of the td. Give your a display:inline-block. This will let the a take only the space it needs. And then your clickhandler will work.
You can also use the javascript function onclick="functionname()" inside your 'a' tag and write your popup code in that function.
This code
$('tr > td a').on("click"...
adds a click handler to the a, then the this inside is the a, so
$(this).parent()
gives the td
followed by
.find('td')
will try to find a td inside the td, which won't happen
To get the first td use closest which goes up the parents until if find the target, ie:
$(this).closest('tr').find('td:first').find('span').html()
or
$("td:first > span", $(this).closest('tr')).html()
(or .eq(0) if you don't like :first)
You could asign a class to the span in your first column, say myClass, like this:
<table>
<tr>
<th>Name </th>
<th>Clicks</th>
<th>Clicks2</th>
</tr>
<tr>
<td>
<span class="myClass" id = "span1">Hi!</span>
Save
</td>
<td style="block">
Click Me
<select>
<option>1</option>
</select>
</td>
<td>
Click Me
<select>
<option>2</option>
</select>
</td>
</tr>
</table>
,and use jQuery like this:
$('td > a').on('click', function (e) {
alert($(this).parents('tr').find(".myClass").html());
});
See here
Just change you script from this
$(function(){
$('tr > td a').on('click', function(e) {
alert($(this).parent().find('td').eq(0).find('span').html());
});
});
To this
$(function () {
$('tr > td a').on('click', function (e) {
alert($(this).parent().find('span').html());
});
});
Here is a jsFiddle : https://jsfiddle.net/CanvasCode/hdzswrn7/
Related
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>"
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>
I made the following example to describe my problem:
$("tr > td > #arm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", true);
$(this).parent().children("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", false);
$(this).parent().children("#disarm").prop("disabled", true);;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>
<script>
</script>
I have the above table with one row that contains 2 cells and a button in each cell. One of them is disabled so I made a script where when I press the second button it should enable the first one and disable the one which was clicked.
Disabling the button that was clicked work as I expected but I don't know why it doesn't enable the other button.
You're not selecting the right element. Your code is
$(this).parent().children("#disarm")
where $(this) is the #arm element, then parent() is the td cell.
So basically you're searching for a children element (#disarm) of that cell, that's why he can't find it
Try with this instead
$("tr > td > #arm").on("click", function() {
$(this).prop("disabled", true);
$(this).closest("tr").find("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).closest("tr").find("#arm").prop("disabled", false);
$(this).prop("disabled", true);
});
Here it is a WORKING DEMO of your code :)
you need to use prev and next
$("tr > td > #arm").on("click", function() {
$(this).parent().children("#arm").prop("disabled", true);
$(this).parent().next().children("#disarm").prop("disabled", false);
});
$("tr > td > #disarm").on("click", function() {
$(this).parent().prev().children("#arm").prop("disabled", false);
$(this).parent().children("#disarm").prop("disabled", true);;
});
https://jsfiddle.net/hfr33exa/1/
Try to totatlly remove disable attribute from element. As far as I know not all browsers correctly works with disable="false"
you can add a class and then use prop function as below
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<table>
<tr>
<td>
<button id="arm" disabled class="test">Arm</button>
</td>
<td>
<button id="disarm" class="test">Disarm</button>
</td>
</tr>
</table>
<script>
$('.test').click(function(){
$(".test").prop('disabled', function () {
return ! $(this).prop('disabled');
});
});
</script>
</body>
</html>
DEMO
description: I have added a class test to all the buttons and then I used the prop function. So the button on which click event occurs is disabled and rest all are enabled
Here is the solution of your problem. Use removeAttr to remove disabled to the element.
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>
<script>
$("tr > td > #arm").on("click", function() {
$("#arm").prop("disabled", true);
$("#disarm").removeAttr("disabled");
});
$("tr > td > #disarm").on("click", function() {
$("#arm").removeAttr("disabled");
$("#disarm").prop("disabled", true);;
});
</script>
here is a jsfiddle of a working example
There is no reason to select the parent when you click on the button.
$(this).parent().children("#arm").prop("disabled", true);
should just be
$(this).prop("disabled", false);
Now when you are trying to pick the other element you do this.
You pick the parent of the button
You look for the other button inside of that element.
The problem is the button is in a sibling of the parent. But there is no need to select the parents when you have the id. Just select it by its id to start, it will be faster.
$("table tbody").on("click", "button", function() {
var btn = $(this).prop("disabled", true);
var opposite = btn.attr("id") === "disarm" ? "#arm" : "#disarm";
$(opposite).prop("disabled", false);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<td>
<button id="arm" disabled>Arm</button>
</td>
<td>
<button id="disarm">Disarm</button>
</td>
</tr>
</table>
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');
I have a table where I need the first two cells of every row clickable (NOT the entire row). When I click the first or the seccond cell, I want to get the value of the third cell of that same row.
To clarify, when I press a1 I want the alert to show c1, If I press b2 I want it to show c2 and If I press c3 I dont want anything to happen.
As you can see, my alert($(this).parent(':nth-child(3)').text()); doesn't work.. how can I achieve this?
$('td:nth-child(-n+2)').on("click", function(){
alert($(this).parent(':nth-child(3)').text()); //Doesn't work
});
td{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<table>
<tr>
<td>a1</td>
<td>b1</td>
<td>c1</td>
</tr>
<tr>
<td>a2</td>
<td>b2</td>
<td>c2</td>
</tr>
<tr>
<td>a3</td>
<td>b3</td>
<td>c3</td>
</tr>
</table>
you need to use .closest('tr') .. to select parent tr and .find() to select td:nth-child(3)
$('td:nth-child(-n+2)').on("click", function(){
alert($(this).closest('tr').find('td:nth-child(3)').text());
});
Working Demo
Use this
$(this).parent().children(':nth-child(3)').text()
Select the parent and then a child of it.
JsFiddle
You can use
$('td:lt(2)').on("click", function () {
alert($(this).parent().find("td:eq(2)").text()); //Doesn't work
});
Fiddle
lt(2) will get the specified elements whose index is less than 2
eq(2) will select the element whose index is equal to 2
This work for me:
$('table tr').each(function(){
$(this).find('td:lt(2)').on("click", function () {
var text = $(this).parent().find("td:eq(2)").text();
console.log(text);
});
});