I don't know the terminology but hoping this explanation makes sense. I have a JavaScript code that I want to repeat 10 times, each time with an increasing number to target each td in a table (first td then the second then the third and so on)
The goal of this JavaScript is to match the TD width of the thead to the one in the tbody (this is because I have them separated via css with position:absolute).
Right now I managed to match the width of a single TD with this:
var cell4 = $('#divResults tbody > td:nth-child(4)');
$('#divResults thead > tr > td:nth-child(4)').css({ width: cell4.width()});
The easiest, but not practical, way to accomplish setting the remaining TDs is to duplicate the JS but replacing the numbers 9 more times.
I know there is a way to create a loop and target each TD without manual duplication of the code but can't seem to find an answer online.
I appreciate the help
Instead of selecting a specific element, select all elements and loop over them.
$('#divResults tbody > td').each(function( index ) {
// Do some repeating code
});
Link for more details
https://api.jquery.com/each/
In vanilla JS you would use a for loop to achieve this. Using jQuery you can just grab a collection of <td>s and loop over them using .each
// Get the first tr's collection of td elements
var bodyTds = $('#divResults tbody tr:first-child td');
// Loop over the head td's (should be th's really)
$('#divResults thead tr td').each(function(index) {
// Apply the width of the body td to the head td
$(this).css({ width: bodyTds.eq(index).width()});
});
Related
I am trying to use after() to place more DOM data (a <table>) after a $('tr'); I am noticing that the width of the new element changes the width of the tr's first td element. What can I do to prevent that?
$('#table tr').click(function(){
$(this).after(table);
$('#data').slideDown("slow");
});
http://jsfiddle.net/HZLLb/1/
As the comments stated, you can't have a table element in that position, and you should not repeat id's. You CAN, however, have multiple tbody elements, as well as multiple elements with the same class, which is likely the solution you are going for:
var table = '<tbody class="data" style="display:none;"><tr><td>Test</td><td>Test</td> <td>Test</td></tr></tbody>';
$('#table').on('click', 'tr', function(){
$(this).closest('tbody').after(table);
$('.data').last().slideDown("slow");
});
http://jsfiddle.net/HZLLb/3/
I'm having problems with html DOM.
How do I get the value from this path:
html body div table tbody tr td table tbody tr td table tbody tr td table tbody tr td form table tbody tr td
I can only find stuff like getElementbyID/tag/name/class etc.
How do I get the absolute DOM 'path' of the td element (let's say the 3rd cell of the second row in that table)?
I've been looking everywhere but cannot find a simple answer without ID/Class etc involved.
You could use querySelector(), but it doesn't have great support...
var elem = document.querySelector('html body div table tbody tr td table tbody tr td table tbody tr td table tbody tr td form table tbody tr td');
Otherwise just use a library that allows you to use CSS selectors, such as jQuery.
var $elem = $('html body div table tbody tr td table tbody tr td table tbody tr td table tbody tr td form table tbody tr td');
By the way, selecting like this is horrible for performance. Absolutely terrible. Have a read up on CSS selectors to learn why.
First, consider whether you do really need full paths. Referring to IDs or classes is more robust as they have less moving parts.
If full paths are what you need, you may wish to use XPath, as it's specifically designed for finding elements by path.
Here's a simple cross browser XPath library - there are many others.
Looks like you may want something like this:
For the following sample HTML,
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="findit.js"></script>
</head>
<body>
<div id="header">
<h1>Welcome to my ASP.net site!</h1>
</div>
<div id="h440292">
<table>
<!-- tbody omitted, but some (all?) browsers add it -->
<tr>
<td>junk</td>
<td>junk</td>
<td>junk</td>
</tr>
<tr>
<td>junk</td>
<td>junk</td>
<td>pick me!</td>
</tr>
</table>
</div>
</body>
</html>
this jQuery code will find the cell that says "pick me!"
$(function () {
var $resultCell = $("body")
.children("div").eq(1)
.children("table")
// Note I have to add this even though
// I omitted the tbody in the HTML markup
.children("tbody")
.children("tr").eq(1)
.children("td").eq(2);
alert($resultCell.text());
});
If performance becomes a problem, you may need to resort to doing something similar using the native DOM methods.
I am playing with this idea. I want to be able to find any node on a page (using a headless browser). Trying to build an absolute node path I created a recursive function, works but I am finding it is not completely unique which is annoying. On here for example, each post is templated so selecting text in the third response will reveal the same node path up the HTML tag as the first post
const buildPath = (node) => {
console.log(node);
if(node.tagName !== "HTML") {
path.unshift(node.tagName.toLowerCase())
buildPath(node.parentNode)
}
};
const path = [];
builtPath(<start node>);
document.querySelector(path.join(" "))
but this is where I am stuck now. Some things don't have any specific classes or names or ids to add to that. I may need to capture the innertext or innerhtml and try to match that. Kinda annoying. I suppose you could load like D3 and inject an incremental ID as data but then the site can't change at all, which may be true for this method too but I would think less so.
1) How do I find the row number/index in a HTML table? The generated table doesn't have any id for row.
eg: I have a plain HTML table generated, which has 10 rows,
I am adding rows dynamically to this table.(in between existing rows)
Since I am adding new row, the existing row index will change. Now I need to to find the index of each row before adding the new row.
"1) How do i find the row number/index in a HTML table? The generated table dosen't have any id for row."
If you mean that you already have a row, and you need its index, don't use jQuery to get it. Table rows maintain their own index via the rowIndex property.
$('table tr').click(function() {
alert( this.rowIndex ); // alert the index number of the clicked row.
});
Demo: http://jsfiddle.net/LsSXy/
To get the index of any element within a selector use index().
In your case it would be:
var rowIndex = $("#myTable TR").index();
In addition, you can use eq() to select a specific element in a group:
var thirdRow = $("#myTable TR").eq(2) // zero based .: 2 = 3rd element.
Read more on info
Read more on eq
The jQuery site is really good for finding functions, I always find myself going back to it all the time for reference and refresh. http://docs.jquery.com/
Or you can use css selectors in jquery like so
$('table tr td:first').addClass('first-row');
I typically zebra stripe table rows for odd / even like so and it works well:
$("table tbody tr:visible:even",this).addClass("even");
$("table tbody tr:visible:odd",this).addClass("odd");
However, I have a data table where there are three consecutive rows for 1 set of data. The next three consecutive rows would be for the next set of data. So ideally I'd like to take the first three rows and add a class of even and then the next three rows after that to have a class of odd.
Here's something I whipped up on jsfiddle:
$("tr:nth-child(6n)").addClass("odd")
.prev().addClass("odd")
.prev().addClass("odd");
What this does is select every 6th tr element, set its class to odd, and the same to the previous two tr elements, thus giving you the result of 3 "grouped" rows.
More about the nth-child() selector here, and more about the prev() function here.
You could change the code to this to add an even class to the three rows preceding the ones with the odd classname:
$("tr:nth-child(6n)").addClass("odd")
.prev().addClass("odd")
.prev().addClass("odd")
.prev().addClass("even")
.prev().addClass("even")
.prev().addClass("even");
That looks like this.
Here is a solution that can work with more complex formulas.
http://jsfiddle.net/JRPmw/
You use jQuery's filter instead. You provide as complex an equation as you like and return true for rows you want.
$('tr').filter( function(n) {
var x = (n+1) % 6;
if (x >= 1 && x <= 3) return true;
}).addClass('threes');
Try use :nth-child selector :
$("table tbody tr:visible:nth-child(6n+1)").addClass("even");
$("table tbody tr:visible:nth-child(6n+2)").addClass("even");
$("table tbody tr:visible:nth-child(6n+3)").addClass("even");
$("table tbody tr:visible:nth-child(6n+4)").addClass("odd");
$("table tbody tr:visible:nth-child(6n+5)").addClass("odd");
$("table tbody tr:visible:nth-child(6n+6)").addClass("odd");
http://jsfiddle.net/fliptheweb/5Xnvu/
Let's say I have a table with these rows:
<table>
<tr id="before_dynamic_rows"></tr>
<tr id="after_dynamic_rows"></tr>
</table>
Using jQuery, I insert automatically generated rows (search results) before the after_dynamic_rows row. How can I delete a range of rows, namely - you guess it - the ones between the row with the id before_dynamic_rows and the row after_dynamic_rows? (In order to be able, after having inserted them, to remove them and insert different ones.)
var response = ajax.responseText;
$('#after_dynamic_rows').before(response);
That's how I insert the new rows. Considering the first answer: how can I assign a class to whatever the response text may be?
This answer is based on a literal interpretation of the question with the idea that the only rows which should be removed are those rows that are in between #before_dynamic_rows element and #after_dynamic_rows.
See working version at: http://jsfiddle.net/7wBzd/
var $rows = $("tr");
$("tr:lt("+ $rows.index($("#after_dynamic_rows")) +"):gt("+ $rows.index($("#before_dynamic_rows")) +")").remove();
$("table tr:gt(0)").not("#after_dynamic_rows").remove();
Try it out here.
Note if #after_dynamic_rows is the last row, then you can just do:
$("table tr:gt(0)").not(":last").remove();
or:
$("table tr:gt(0):not(:last)").remove();
...and if there are rows before #before_dynamic_rows, just do:
$("table tr:not(#before_dynamic_rows, #after_dynamic_rows)").remove();
I would assign a class to those added rows to make them easy to select, but you could select all tr children and use the 'not' method to remove the two you want to keep.
$("table tr").not("#before_dynamic_rows").not("#after_dynamic_rows").remove();