how wud u get the next row in the following example? (i am trying to print the next three row/column values of the rowId provided)
function printRowData(rowId)
{
var row=document.getElementById(rowId);
for(i=0; i<3 ; i++)
{
var column=row.getElementsByTagName("td");
alert(column[0].innerText);
//now i want to move to the next row...something like row=row.next()?????
}
}
If you just want the next row, and not subsequent rows, you can do this:
var next = row.parentNode.rows[ row.rowIndex + 1 ];
So your code could look like this:
function printRowData(rowId) {
var row=document.getElementById(rowId);
var idx = row.rowIndex;
for(i=0; i<4 ; i++) {
if( row ) {
alert(row.cells[0].innerText);
var row = row.parentNode.rows[ ++idx ];
}
}
}
From the current row, it gets the .parentNode, then from that, it accesses the rows collection, and increments the .rowIndex property of the original row to select the next.
This takes care of white space issues.
Notice also that instead of getElementsByTagName, I replaced it with row.cells, which is a collection of the cells in the row.
EDIT: Forgot to include the rows property after parentNode. It was included in the description though. Fixed.
To get around the problems with whitespace you can now use
row = row.nextElementSibling
Just make sure to check for null when you get to the end of the table, or if you have a thead, tbody or tfoot it will be at the end of that particular node.
If you're supporting older browsers you may want to use a shim.
Try using the nextSibling property:
row = row.nextSibling
But note that whitespace in your source HTML may turn into text nodes among the rows. You may have to call nextSibling more than once to skip the text nodes.
Have you considered using jQuery? With jQuery, you don't have to worry about the text nodes:
row = $("#" + rowId);
...
row = row.next();
row = row.nextSibling. You might need to do that in a while loop as you may come across whitespace nodes, so you should check to see if the next node has the correct tagName.
If you can use jQuery, then it's becoming really easy.
row.next();
Use document.getElementById(rowId).nextSibling
Related
I need to get the text that's written inside a td, but it always gives me an undefined.
This is my try of getting the text:
console.log($('USERvalue'+keykey).prop("innerText"));
console.log($('td[id^="USERvalue"]').prop("innerText"));
Both are the same element. on the first one i target a specific one. In the second line i target several, because i just say the id should start with xy.
But both give me an undefined. If I'm correct that means that it finds the element but cant find any text.
This is the element i try to reach and get the text out of it:
for(let key = 0; key < GlobalVarUS2.length; key++){
let temp = $("<tr><td id='USERvalue"+key+"' value='"+GlobalVarUS2[key]["pk_us_id"]+"'>"+GlobalVarUS2[key]["benutzername"]+"</td><td><input type='checkbox' id='CHBUSER"+key+"' style='size: 30px'></input></td></tr>");
temp.appendTo("#table_user");
}
Ultimately I want to compare it to a string and if it is correct, do something. But first i need the text of the element.
I hope someone can help me :)
You are using $('td[id^="USERvalue"]').text() like a single element. But in real case it is returning multiple elements, So if you want text of all td then you have to process them in loop and you have to contain text in single variable which will be appended each time. for example:
var text="";
$.each($('td[id^="USERvalue"]'),function(k,v){
text += $(v).text();
});
console.log(text);
I am using stupidtable (http://joequery.github.io/Stupid-Table-Plugin/) to add sorting to a table. I use a callback to add an appropriate up or down arrow to show which column has been used for the sort and whether it is ascending or descending.
The original event handler used the code:
table.bind('aftertablesort', function (event, data) {
// data.column - the index of the column sorted after a click
// data.direction - the sorting direction (either asc or desc)
var th = $(this).find("th");
th.find(".arrow").remove();
var arrow = data.direction === "asc" ? "↑" : "↓";
th.eq(data.column).append('<span class="arrow">' + arrow +'</span>');
});
This works fine when there is only one row of headers, but if there are multiple rows it doesn't because it finds the first header row not the last.
I'm struggling to find out how to find the bottom row, following another thread I tried:
var th = $(this + ' thead tr:last').find("th");
But this gives a syntax error, I guess because I am not using 'this' properly. Can anyone help?
Thanks,
Steph
you cant combine an object with a string to build a selector.
try this:
var th = $(this).find('thead tr:last').find("th");
this is not a string, but a DOM element.
You could use it as a context selector like this :
var th = $('thead tr:last', this).find("th");
But .find is faster than context, so use this :
var th = $(this).find("thead tr:last th");
if this referes to your table you should use find
var th = $(this).find('thead tr:last')
The following line
$(this + ' thead tr:last')
Will not work, because this is an object and you are mixing with a string, which will result in
$("[object HTMLTableElement] thead tr:last")
You do know that thead is for the header section of a table. So when ask "bottom row" are you sure it's the header you want or the body?
Find the last header row if this is a parent.
var last_header_row = $(this).find("thead").last("tr");
To find the last row in the body if this is a parent.
var last_body_row = $(this).find("tbody").last("tr");
Note, that the this reference is in the context of the callback function for the event. Without knowing what that context is we can't assure that it's a DOM element reference.
If you have a reference from inside the table, where this is a tr or something. Replace the call to find(..) with closest(..)
I'm trying to highlight rows in a table using jQuery, but I'm wondering if it's possible to use a variable for the row I want highlighted. This is the code I have now, which is not working.
var rowNumber = 3 //I want to use a loop, but for testing purposes I have it set to 3
$('tr:eq(rowNumber)').addClass('highlight');
Sure, why not. You may pass a variable in :eq() selector:
$("tr:eq(" + rowNumber + ")").addClass("highlight");
or use eq() method instead:
$("tr").eq(rowNumber).addClass("highlight");
$('tr').eq(rowNumber).addClass('highlight');
Should work for you.
Let me first address isolated access (i.e. not taking into consideration optimisation for loops)
Best solution: Use .eq() (fast, nice and short)
You could try something like
$('tr').eq(rowNumber).addClass('highlight');
Explanation: .eq(index) Reduces the set of matched elements to the one at the specified index.
Source: http://api.jquery.com/eq/
Alternative solution: Use the ":eq(index)" selector (unnecessarily slower, more verbose and convoluted)
$("tr:eq("+rowNumber+")").addClass('highlight');
A third solution: (fast, but more verbose than the proposed solution)
$($('tr').get(rowNumber)).addClass('highlight');
How this one works: $('tr').get(rowNumber) gets the (rowNumber+1)th DOM element matching the query selector and then this is wrapped in jQuery goodness using the surrounding $( ).
More info at: http://api.jquery.com/get/
Feel free to experiment with the accompanying jsFiddle:
http://jsfiddle.net/FuLJE/
If you are particularly performance conscious and are indeed are going to iterate through an array you can do this instead:
var trs = $('tr').get(); //get without arguments return the entire array of matched DOM elements
var rowNumber, len = trs.length;
for(rowNumber = 0; rowNumber < len; rowNumber++) {
var $tr = $(trs[rowNumber]);
//various stuff here
$tr.addClass('highlight');
//more stuff here
}
Of course you could also use .each()
$("tr").each(function (rowNumber, tr) {
var $tr = $(tr);
//various stuff here
$tr.addClass('highlight');
//more stuff here
})
Documentation can be found here: http://api.jquery.com/each/
Just to point out the obvious: $("tr").addClass('highlight') would work if adding the highlight class to all tr was all that the OP wanted to do :-)
Links to live examples # jsfiddle & jsbin.
So this function:
function symbolize(e){
var elements = e.childNodes; // text nodes are necessary!
console.log(elements);
for(var i=0; i < elements.length; i++){
t = elements[i];
var range = document.createRange(), offset = 0, length = t.nodeValue.length;
while(offset < length){
range.setStart(t, offset); range.setEnd(t, offset + 1);
range.surroundContents(document.createElement('symbol'));
offset++;
}
}
}
..should iterate over every letter and wrap it in a <symbol/> element. But it doesn't seem to be working.
So I added the console.log(); right after the *.childNodes have been fetched, but as you'll see in the example site above, the log contains 2 unexpected elements in front(!) of the array. And yeah, because of this, I have a feeling that surroundContents(); make the changes live(!). couldn't find any reference on this though
One of the elements is an empty Text node, the other is my <symbol/>. But yeah, this is totally unexpected result and messes up the rest of the function.
What could be wrong with it?
Thanks in advance!
Update
Oh, looks like the elements are added on Chrome, Firefox doesn't add the elements, but still halts the function.
Element.childNodes is indeed a live list , it could not be otherwise (that would mean an incorrect list of nodes). The easiest solution is to freeze (make a copy of) it before you mess with it (by surrounding existing ranges).
var elements = Array.prototype.slice.call(e.childNodes, 0);
https://developer.mozilla.org/en/childNodes it's of type NodeList
https://developer.mozilla.org/En/DOM/NodeList those are live lists
How can I get the second child node of a tr, which has 3 td in it?
I have a code
rows=document.getElementById('mytr');
rows.firstChild.innerHTML='ddsds';
rows.lastChild.innerHTML='dd';
Now I would like to change the content in the middile also. how can I do that?
rows.secondChild.innerHTML='ddsds';
will not work.
Although I'd recommend using something like jQuery for this kind of manipulation, this is what you want:
var rows = document.getElementById('mytr');
var cells = table.getElementsByTagName('td');
cells[0].innerHTML = 'ddsds';
cells[1].innerHTML = 'ddsds';
cells[2].innerHTML = 'dd';
Access the childNodes or cells as array
rows.childNodes[1].innerHTML would do the second cell, as would
rows.cells[1].innerHTML
you can also use nextSibling,
rows.firstChild.nextSibling.innerHTML='ddsds';
and be careful while accessing child, these can return a text node if there are some white spaces. always try to validate if the child is not a text node using
rows.firstChild.nodeType == 1 // this will check if the node is not a text node
You can use .childNodes to find childnode by it's index.
rows.childNodes[1].innerHTML = 'foo'; // set foo to second child
if (rows.childNodes.length > 0)
rows.childNodes[1].innerHTML = "ddsds";