So I have this code (from the gracious help from this site!)
window.onload = function inventorytable() {
var tableRows = document.getElementById
("inventorytable").getElementsByTagName("tbody")[0].getElementsByTagName("tr");
Now from here, I want to get all of the TDs, under all of the TRs. I also want to be able to perform operations on the TDs, depending on which TD (i.e. which column) they are in the table.
So for example, if I have
<tr>
<th>Processor Speed</th>
<th>Amount of RAM</th>
<tr>
<td>2.0</td>
<td>3.0</td>
</tr>
<tr>
<td>3.2</td>
<td>4.0</td>
</tr>
I want to be able to select each TD separately, depending on its order within the TR, and then add text to it. There will be a variable number of TRs, at least 20, and possibly more. There are going to be about 10-15 TDs.
The text added would be something like " Ghz" or " GB"
You have to iterate over all tr elements (which is a NodeList [MDN], returned from getElementsByTagName [MDN]):
for(var i = 0, l = tableRows.length; i < l; i++) {
var row = tableRows[i];
//...
}
Inside the loop you can get all tds of one row again with getElementsByTagName or using the .cells [MDN] property. You can then decide to either iterate over them as well or to access the specific cells explicitly, such as cells[1] to access the second cell (second column) in that row.
If the cells contain simple text or you don't have any event handlers bound to their descendants, you can simply use innerHTML [MDN] to change the element's text content.
Otherwise you have to create a new text node and append it to the cell (that might be the best option in any case).
The Mozilla Developer Network is a great source for all kinds of information, including the DOM and JavaScript.
This is how I would do it:
var table = document.getElementById( 'inventorytable' );
[].forEach.call( table.rows, function ( row, i ) {
[].forEach.call( row.cells, function ( cell, j ) {
// this function runs for every cell in the table
cell // references the current cell
row // references the current row (the row the cell is in)
i // the row index (0 = first row, 1 = second row, etc.)
j // the cell index (0 = first cell in row, 1 = second cell in row, etc.)
});
});
Live demo: http://jsfiddle.net/6tXUm/
Note: You need to include ES5 shim since some older browsers (mainly IE8) don't implement the new ES5 features like forEach.
If you want to simplify your life and logic here is an example of what you want: http://jsfiddle.net/Akkuma/2wJ8G/
What I'm doing is first getting the exact table and from there grabbing all td elements. It will automatically run through each one in order of row, as that is their order in the markup. You don't need to first select document.getElementsByTagName('tr'). If you need to filter you can look up the tree or select elements at a higher level first, for instance the thead.
In the second example, I know explicitly there is only one tbody and can access the area, which is of length 1, and chain .getElementsByTagName('td') to get only those td within the tbody (you could have a td in your thead or tfoot)
The third example uses #Rob W 's recommendation of using table dom traversal. At least in my example using it only complicated the code.
The final example combines Rob W's recommendation (ex3) with ex2. This allows you to skip having to write two loops.
Related
Sample code:
<tr><td>first_button</td><td>second_button</td></tr>
<tr><td>first_button</td></tr>
<tr><td>first_button</td><td>second_button</td></tr>
<tr><td>first_button</td></tr>
<tr><td>first_button</td><td>second_button</td></tr>
function someFunc(i) {
// first button appears on every row
first_button[i].style.display="none"; // works
// second button appears randomly
second_button[i].style.display="none"; // doesn't work as intended
}
// someFunc(2) targets the third row's "first_button" but
// the last row's "second_button". I want to target the
// third row's buttons, not the third button of each type.
var i is incremented with every row. I want to target the i-th row's buttons not the i-th button of each type. What is the simplest way to do this?
Target the rows index, not the index of the nodelist containing your 'buttons'. Also put a check in there to make sure the second cell exists there:
var table = document.getElementById('mytable');
function someFunc(i) {
var row = table.getElementsByTagName('tr')[i];
var cells = row.getElementsByTagName('td');
cells[0].style.display="none";
if(typeof(cells[1]) != 'undefined'){
cells[1].style.display="none";
}
}
JSFiddle
You are probably using some document method to get references to your buttons. Maybe document.getElementsByClassName() or document.querySelectorAll(). Those methods are also available on individual elements. So, you can get a reference to the <tr> element and call row.getElementsByClassName() to get just the elements that are descendents of the row.
I want to fill a td element by accessing other td s in the same row. How would I access them using jQuery?
In my situation, I have a table, and column 5 is populated by subtracting col 3 from col 4, and returning the result in col 5. I started to do it with a nested loop, but realized, that if I used the .each() on each col 5 td, it would be achievable if I could identify col 3 and 4 using jQuery.
Here is the fiddle.
The section to identify the elements is here:
$('section.techtable td:nth-child(5)').each(function() {
$(this).append(strinToMonthNumber($(START JQUERY),$(END JQUERY)));
})
I think that I would have to access the parent of $(this), and then the (3rd and 4th) child element?
I am also trying to avoid using span or class attributes on the TH or TD elements.
You can select one element (table cell in your case), and then use jQuery.prev() or jQuery.next() to select previous or next sibling element. In native DOM, you could use previousSibling/nextSibling (or previousElementSibling/nextElementSibling in modern browsers to skip non-element nodes) element properties for same purpose.
Based on your code example, something like this:
$('section.techtable td:nth-child(5)').each(function() {
var cell5 = $(this),
cell4 = cell5.prev(),
cell3 = cell4.prev();
cell5.append(strinToMonthNumber(cell3, cell4)));
})
Try this:
$('section.techtable tr').each(function() {
var $cells = $(this).find("td");
var val = strinToMonthNumber($cells.eq(2).text(),$cells.eq(3).text());
$cells.eq(4).text(val);
});
Note that the cell indexes are of zero-origin, therefore one less than your 3/4/5. If you already took zero-origin into account, then +1 in each case.
I have a table named resultGridTable. I have a jQuery function to be executed on each row of the table. In the function, "this" means a row.
For the fourth row, I need to alert the first column value (of fourth row). I have the following code; but it does not work. How can we make it working?
For the fifth row, I need to alert the number of columns in the row. How can we do it?
In the sixth row's second column, I have two buttons (input type="submit"). I need to alert the second button's text/value. (The second button has a class named "secondButton") How can we do it?
Following is the code::
$('#resultGridTable tr').each(function (i)
{
//"this" means row
//Other operations in the row. Common for all rows
if(i==3)
{
//Specific Operation for fourth row
var columnValue = $(this 'td:nth-child(0)').val();
alert(columnValue);
}
});
READINGS:
jQuery Code: Starting from Parent to Child; not from Child to Parent
How to get value of first column in current row in html table using jQuery
How to get the first row's last column of an Html table using jQuery
Just to be different, you can mix up DOM and jQuery to good effect here since you have fixed offsets into the table:
var t = document.getElementById('resultGridTable');
// jQuery to get the content of row 4, column 1
var val1 = $(t.rows[3].cells[0]).text();
// no jQuery here to get that row length!
var val2 = t.rows[4].cells.length;
// DOM access for the cell, and jQuery to find by class and get the text
var val3 = $('.secondButton', t.rows[5].cells[1]).text();
These should all be substantially faster than using selectors.
Look into jQuery eq:
alert($('#resultGridTable tr:eq(3) > td:eq(0)').text());
alert($('#resultGridTable tr:eq(4) > td').length);
alert($('#resultGridTable tr:eq(5) > td:eq(1) > .secondButton').text());
If you have special values for rows/columns, consider adding a class to it, then you can use selectors rather than "magic" numbers which could change.
Adapted from Accepted Answer.
This is the code if you are using jquery instead of document.getElementById The difference is that you need to insert the array of [0].
var t = $('resultGridTable');
// jQuery to get the content of row 4, column 1
var val1 = $(t[0].rows[3].cells[0]).text();
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');
HTML
<tr id="rowId"><td><textarea class="inputTextarea"></textarea></td><td><textarea class="inputTextarea"></textarea></td></tr>
<tr id="rowId2"><td><textarea class="inputTextarea"></textarea></td><td><textarea class="inputTextarea"></textarea></td></tr>
<tr id="rowId3"><td><textarea class="inputTextarea"></textarea></td><td><textarea class="inputTextarea"></textarea></td></tr>
Provided I know rowId, how do I find the next textarea ON THIS PAGE, starting at any arbitary point. I don't mean ANY input, textarea only. I need to be able to start AT ANY row, and progress on to the next textarea, essentially going down the rows.
EDIT
Based on answers, I used the following code to traverse the textareas row by row:
var curElt = $('#' + startAt); //startAt is the first row id
for(var i=1; i < 10; i++) {
$(curElt).find('textarea').eq(0).val(i);
$(curElt).find('textarea').eq(1).val(i+1);
curElt = $(curElt).next();
}
You can use the next and find methods:
$('#' + current_row_id).next().find('textarea').eq(0);
next will get the next sibling, and then find will find all of the elements within the set that match the passed-in selector(s), then eq(0) will grab the first element in the resulting set returned from find.
$('#rowId2').find('textarea');
That will find both children of the row. If you want the first one, either:
$('#rowId2').find('textarea').eq(0); //jQuery object
$('#rowId2').find('textarea')[0]; //DOM Element
Edit: If you only know one row and want to find the first textarea in the next row:
$('#rowId').next().find('textarea').eq(0);
$textarea = $('#rowId textarea').eq(0);
$nextarea = $textarea.closest('tr').next().find('textarea').eq(0);
Just to clarify, $.fn.next() finds the next sibling in the DOM.
Starting from the textarea, first
you have to find its parent-tr (
$textarea.closest('tr') ).
From there, use next to find the next tr
( .next() )
Finally, find the first
textarea within that tr (
.find('textarea').eq(0) )
Try this:
$("#rowID textarea:first-child").val()