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/
Related
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()});
});
I have a very simple table
<table>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
</table>
when i append another row to the above table with text 5 in td jquery each() doesn't loop through newly added row it returns only predefined elements not the elements dynamically added
$("table > tbody").append("<td>5</td>");
$("table tr td").each(function(){
alert($(this).text());
});
Please see JS FIDDLE LINK HERE
In tbody you cannot append td directly wrap them in tr.
Live Demo
$("table > tbody").append("<tr><td>5</td></tr>");
$("table tr td").each(function(){
alert($(this).text());
});
Your reasoning is incorrect. The reason it doesn't find the element is because your selector doesn't match the nesting of elements that you're appending.
Wrap the td elements in a tr element.
You need to do this:
$("table > tbody").append("<tr><td>5</td></tr>");
$("table tr td").each(function(){
alert($(this).text());
});
The reason is simple you, your original code will produce the new row as <tbody><td>5</td></tbody> without the tr tag that you were looking for in the each function.
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');
Say I have multiple tables (no IDs or names) on a page at various levels within embedded divs. What would my selector be (if it is possible) to select all tables regardless of where it resides on a page and iterate or filter the tables based on the content of the first cell in the first row?
You can simply use $('table') as your selector.
Then you can use the existing filters such as ":contains" or ":has", or the .filter() function if you need more finegrained control over in filtering your results. For example,
$('table:has(td > span)')
or
$('table').filter(function(index){
return $(this).html() == "<tr><td>something</td></tr>";
});
Try...
$("table").each(function(){
var curTable = $(this);
var cell = $(this).find("tr:first td:first");
if ($(cell).text() == "some text"){
}
});
alternatively you could all check the html of the first cell in the if clause by $(cell).html()
To select all tables couldn't be simpler:
$("table")
Adding a filter
$("table:has(td:first:contains('mytext'))")
This will select all the tables:
$("table")
This will select the first TD cell of the first row of each table:
$("table tr:first td:first")
You can get every table by just using jQuery('table'). Whether the tables are in various levels or embedded within divs or whatever doesn't change.
To do additional filtering:
jQuery('table').filter( function() { ... } );
The passed in function will map the table element to this, and you would need to return true to keep it in your collection, or false to discard it.
$('table').each(function(){
$(this).find('tr :first')...
});
If you are wanting to look at the first cell in the first row of each table you can use:
$("table tr:first td:first").each(function() {
var html = this.innerHTML;
/* Iterative logic here */
});
You should try something like $('table tr:first td:first:containts("whatever")') to grab the first cell of the first row with specific content.