Targeting correct row elements - javascript

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.

Related

Looking to get index of first matched element within array

I'm looking to get index position of matched element within repeater and would like to know how I can find.
List of books below
element.all(by.repeater('books'))
within those rows, some rows will have below element
element(by.css('[ng-click="download"]')
and I want to do following
find element of download button (more than 1)
get index position of first download button (so I can do other stuffs later with .get(3) for specific row)
So here what I have tried.
element.all(by.css('some-css')).first().element(by.tagName('tag-within-css')).get(index);
element.all(by.css('some-css')).get(index).element(by.tagName('tag-within-css'));
Finding Sub-Elements - Protractor locators guide
some error such as index not defined or no method of 'get'.
Thanks.
I think you don't need to operate using element positions/indexes inside the repeater. Instead, find download buttons and operate with the current row using context/element specific element searches by chaining element and element.all:
var books = element.all(by.repeater('books'));
var downloadButtons = books.all(by.css('[ng-click="download"]'));
var firstDownloadButton = downloadButtons.first();
// here is how you can, for example, get the next div element to the download button
var nextElement = firstDownloadButton.element(by.xpath('following-sibling::div'));

jQuery: Get First Column Value on Fourth Row (only) of HTML Table

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();

Iterating over table cells

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.

How to get table row above (or before) my current row in jQuery?

Say I have a variable which holds a table row.
How would I get the row right before it using javascript/jquery?
This:
var prevRow = row.previousElementSibling;
or
var prevRow = $( row ).prev()[0];
([0] is used to "unwrap the jQuery object", to get the DOM reference to that row. If you want to perform jQuery methods on that row, you can just leave it inside, like $( row ).prev().addClass( '...' ); and in that case you don't need a new variable.)
Assuming that the two rows are siblings (not contained in separate tbody or thead elements):
$curRow = $(this); // or however you're getting the current `tr`.
$curRow.prev('tr');
Should get you the previous row.
Well you need to do something like so:
$("#cellID").parent().prev()
Your input is not sufficient but if i understand correctly here is the code for your requirement..
If your Variable contains table row id then $('#yourVariableName').prev('tr')[0] will work.
If your Variable contains table row Class then $('.yourVariableName').prev('tr')[0] will work.
If your Variable contains table row index then $(' table tr').eq(varValue).prev('tr')[0] will work.
But please specify what your variable will contain.
Let's say you want to get the input value from the td in the tr above the current one:
$('#id').prev().children('td').children(':text').val();

Find the next textarea using Jquery

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()

Categories