Hi guys I have this question
I have this structure:
<table>
<tbody>
<tr>
<td id="id1"><td>
<td><td>
<td><td>
<td><td>
</tr>
...
</tbody>
</table>
I have the td id and I want to find the table element. Then I want to find, change and show/hide the 4-th tr, but I can't.
I tried $("td#id1") and it finds the td but how can I use it to get the table element and then the 4-th row. They have no IDs.
Another problem I must not change the structure in any way, no new IDs can be added.
You can use closest() along with find() and :eq() selector:
$("td#id1").closest('table').find('tr:eq(3)').show(); // or hide() here
Related
I'm trying to hide a row in a table if it does not contain a search value.
This works:
<table class="mytable">
<tr>
<td>1001</td>
<td>apples</td>
</tr>
<tr>
<td>1002</td>
<td>bananas</td>
</tr>
</table>
<button id="mybutton">Button</button>
<button id="mybutton2">Button2</button>
This will work by hiding all rows, then showing the ones we want:
$('#mybutton').click(function(){
$('.mytable td').parent().hide();
$('.mytable td:contains("apples")').parent().show();
});
But I've seen there's a more elegant (and probably efficient) solution using :not selector, but I can't get it working:
$('#mybutton2').click(function(){
$('.mytable td:not(:contains("apples"))').parent().hide();
});
How can I get this working using the :not selector, so that if a row does not contain apples, it will be hidden, leaving all the rows that contain apples.
JS Fiddle: https://jsfiddle.net/ryy3tvob/
Because first td not contains apple in any row and it will select all first td so it will hide it's parent. So you need to use :contains() for tr
The matching text can appear directly within the selected element, in any of that element's descendants, or a combination thereof. As with attribute value selectors, text inside the parentheses of :contains() can be written as a bare word or surrounded by quotation marks. The text must have matching case to be selected. ( Taken from https://api.jquery.com/contains-selector/ )
$('#mybutton2').click(function() {
$('.mytable tr:not(:contains("apples"))').hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="mytable">
<tr>
<td>1001</td>
<td>apples</td>
</tr>
<tr>
<td>1002</td>
<td>bananas</td>
</tr>
</table>
<button id="mybutton">Button</button>
<button id="mybutton2">Button2</button>
I have html table like this:
<table cellpadding="2" cellspacing="1" width="700">
<tbody>
<tr>
<td class="dark" colspan="2">
Customer Details
</td>
</tr>
<tr>
<td>
Customer Contact Name
</td>
<td>
<input name="tbname" type="text" id="tbname" class="widetb">
</td>
</tr>
</tbody>
</table>
I want to add Some text at the start of the table so it's the first td in the table, how can I do this using jquery? I really don't have clue where to start.
I have to do it this way as I don't have access to change this via the html.
Here is a one liner :
$('td.dark').text('Enter your text here!'); // the class is present in your HTML
This will search for the td with class dark which represents the first td and it will insert the text.
In case you have multiple tables:
$('td.dark').eq(0).text('Enter your text here!');
// here 0 represents the position of the table minus 1 , you want to change the text
As example, so:
$('td', 'table').first().text('hello!');
You could try a google search next time.
The jquery method find finds the set of elements in a parent matching a selector, and eq selects a certain element from the set (with element 1 being referenced by 0 as in arrays). Therefore, you can use the following if you only have one table in your entire document:
$("table") // select all tables
.eq(0) // select the one you want (the only one)
.find("td") // select all td's
.eq(0) // select the first one (the one you want)
.html("insert new content here"); // set the td's inner html
If you have multiple tables, it's tricky. You will need the index of your table relative to other tables. For example, if you have
<table>...</table>
...
<table>...</table>
...
<table>table you are targeting</table>
.......
Then the index of your table would be 2 because it is the third table in the document, and indices start at 0. If you have an index, you can use
var table_index=// set this to the index
$("table") // select all tables
.eq(table_index) // select the one you want (with the index)
.find("td") // select all td's
.eq(0) // select the first one (the one you want)
.html("insert new content here"); // set the td's inner html
It helps if you give your table an id, then you can do something similar to:
$('#id >tbody').prepend('<tr><td>A shiny new row<td></tr>');
Give ID to that First td as your code looks like
<table cellpadding="2" cellspacing="1" width="700">
<tbody>
<tr>
<td id="firsttd" class="dark" colspan="2">
Customer Details
</td>
</tr>
<tr>
<td>
Customer Contact Name
</td>
<td>
<input name="tbname" type="text" id="tbname" class="widetb">
</td>
</tr>
</tbody>
</table>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$('#firsttd').text("Your title here");
</script>
If you can't access the HTML at all and if you have multiple tables then this will work:
var newTR = $( "<tr id='newRow'/>" );
var newTRcontent = "<td colspan=1>Your New Text Here</td>";
$("table:nth-of-type(2) tbody tr").first().before(newTR);
$("#newRow").html(newTRcontent);
I made an example fiddle here
Basically it about using the proper JQuery selector so $(table:nth-of-type(2) will select the second table. Then you can use the code I have above or maybe even better yet here is a one-liner:
$("table:nth-of-type(2) tbody tr").first().before("<tr><td>Your New Text Here</td></tr>");
I have a table like:
<table id="table">
<tbody>
<tr></tr>
<tr>
<td>
<table>
<tbody>
<tr></tr>
</tbod>
</table>
</td>
</tr>
</tbody>
</table>
I'm using jQuery and there exists a stored selector to get the most outer table:
var x = $('#table')
Starting from that If want to get all first level <tr>-elements.
If I use one of those:
x.find('tbody > tr');
x.children('tbody').children();
… the first one will naturally select all nested <tr>-elements as well. The latter seems over-complicated and involves multiple queries.
Is there a way to make this faster/more efficient?
First thing, x.find('tbody > tr') would find all <tr>s. You would need to do x.find('> tbody > tr'), assuming x is x from your example.
I ran a test and this with both and this was my finding.
.children(): 3.013ms
>: 0.626ms
so the > method is faster than the .children() method. The function calls add up... barely.
Here's my JavaScript for the testing.
var $table = $('#table'), $usingChildren, $usingAngleBracket;
console.time('.children()');
$usingChildren = $table.children('tbody').children('tr');
console.timeEnd('.children()');
console.time('>');
$usingAngleBracket = $table.find('> tbody > tr');
console.timeEnd('>');
console.log( $usingChildren, $usingAngleBracket );
the fastest way to get direct children of a parent is .children, so what you can do is:
$('tbody').children('tr')
.find() will search child of child too, so you may not want to use that.
Use can use jQuery's .first() method to find the first <tr> element,
$('#mytable tr').first()
Although, as you wish to find the first <tr> that has nested child elements, you can filter it with .has(). For example: http://jsfiddle.net/cwL4q/3/
$("#mytable tr").has('tbody').first().css("background-color", "red" );
Although, I would strongly suggest simply labelling the 'nested' <tr>'s with a class, then you can simply access them much quicker as you know.
$('.nestedrow');
For the HTML below:
<table id="table">
<tbody>
<tr></tr>
<tr class="nestedrow">
<td>
<table>
<tbody>
<tr></tr>
</tbod>
</table>
</td>
</tr>
</tbody>
</table>
I want to change the "Yes! Pick me" into "Picked" with Jquery in the following HTML structure, I used $('#myDiv>table>tr>td>table>tr').eq(1).text("Picked"); But it was not working. Could someone shed some light on this please? Thanks!
FYI, the first td of the the first table itself contains another table...
<div id="myDiv">
<table>
<tr>
<td>
<table>
<tr>
<td>Yes! Pick me!</td>
<td>Not me..</td>
</tr>
<tr>
<td>Not me..</td>
</tr>
</table>
</td>
<td>Not me..</td>
</tr>
<tr>
<td>Not me..</td>
</tr>
</table>
</div>
The section $('#myDiv>table>tr>td>table>tr>td').eq(1).text("Picked"); does the trick, I forgot the last td part. Thanks to Rocket and everyone's help.
Try this:
$("#myDiv table table td:first").text("Picked")
$('#myDiv').find('table table td').eq(0).text(...);
Start your selection at the #myDiv element ($('#myDiv')), then find all the TD element that are inside a table that is inside another table (.find('table table td')), then only alter the first one (.eq(0)).
Documentation:
.find(): http://api.jquery.com/find
.eq(): http://api.jquery.com/eq
The main problem is that you want .eq(0) not .eq(1) as .eq() is 0-based, and you are not selecting the td, only the tr.
Other than that using > direct descendant selectors makes your selection not very robust at all.
Try $('#myDiv table table td').eq(0).text('Picked');
You can try:
$("td:contains('Yes! Pick me!')").text("Picked");
You can use the :contains(text) selector
$('#myDiv td table td:contains(Yes! Pick me!)').text('Picked');
Be careful with nested tables however because if you were to use just
$('#myDiv td:contains(Yes! Pick me!)').text('Picked');
You would get both the cell your after plus the cell it is nested within.
Your child selector query won't work because HTML5 requires the parser to insert <tbody> elements inside your <table> elements, since you've forgotten to put them in yourself. Perhaps you should consider validating your HTML?
So what I'm trying to do is get the last row of an HTML table. If this row then has a certain class I will ignore this row and select the previous one. This would then be cycled through from the end of the table until a row was found without this certain class.
I figured it's probably involving a for loop, a check for the row class and then JQuery's row.prev method, but still not quite sure how to approach this.
Thanks in advance!
To get the last table row that doesn't have a certain class, say targetClass, you can do this:
$("tr:not(.targetClass):last");
I'm not sure what you want to do with this table row, but if you were to add targetClass to the last row that didn't have it, it would look like this
$("tr:not(.targetClass):last").addClass("targetClass");
Check out this fiddle to see it in action
This example shows you how to get the last of each table on the current page: http://jsfiddle.net/JBnzK/
$('table').find('tr:last').each(function(){
if ($(this).hasClass('stupid')) {
$(this).css('color', 'red');
} else {
$(this).css('color', 'green');
}
});
Assuming you've got the following HTML:
<table id="mytable">
<tbody>
<tr>
<td>1</td>
</tr>
<tr id="YouFoundMe">
<td>1</td>
</tr>
<tr class="certainclass">
<td>1</td>
</tr>
<tr class="certainclass">
<td>1</td>
</tr>
<tr class="certainclass">
<td>1</td>
</tr>
</tbody>
</table>
You can do this:
var elWithoutClass = $('#mytable tr:not(.certainclass):last');
if (elWithoutClass.length) {
alert(elWithoutClass.get(0).id);
// alerts "YouFoundMe"
}
:not(.certainclass) will eliminate <tr> without class 'certainclass'
:last will get you the last one
I invite you to check the Selectors documentation page of jquery to learn more about them.