Javascript access TR from TD - javascript

I have a table row, and within that, I have a td (whatever it stands for). I would like to change the class attribute of the TR my TD is in without using an ID or a name. Like that:
<tr>
<td onclick="[TR].setAttribute('class', 'newName')">My TD</td>
</tr>
How do I do it?

td stands for table data..
now .. in your case you need the parentNode property of the td ..
<tr>
<td onclick="this.parentNode.setAttribute('class', 'newName')">My TD</td>
</tr>
or as bobince suggested in his comment
<td onclick="this.parentNode.className= 'newName'">My TD</td>

In jquery, it would be really simple if you have the reference to your td:
$(this).closest('tr');
If you really don't want to take a dependency on jQuery, then you could just do a loop getting the parentNode and checking it's type as a more general purpose solution. In this case you could just get the parentNode since tr is always a direct parent of td. You can do something like this (note this was not tested):
var parent = myTd.parentNode;
while(true) {
if(parent == null) {
return;
}
if(parent.nodeName === "TR") {
return parent;
}
parent = parent.parentNode;
}

If you have the dom element in javascript, you can use .parentNode() which will give you the parent node, which should be the table row. Then you can set .className

If you can use jQuery it could be something like this
$("yourtdselector").closest("tr").attr("class","classname");
For your code
<tr>
<td onclick="changeClass(this,'classname')">My TD</td>
</tr>
function changeClass(elem, class)
{
elem.parentNode.className = class;
}

jQuery is probably the easiest way of doing this, you can use selectors such as:
$('table.mytable tr').addClass('red');
To add a class of 'red' to all tr's in table.mytable. That's just the tip of the iceberg - check it out it should do what you need.

Without any extra framework:
document.getElementById("theTableName").rows[1].cells[1].className = "someclassname";

Related

Javascript jQuery . Add class when the same data-date

I have two tables
<table>
<tr>
<td class="myclass" data-date="2015-07-09"> Some text </td>
</tr>
</table>
<table>
<tr>
<td data-date="2015-07-09"> Text </td>
</tr>
</table>
What I want to do is:
Firstly take the class 'myclass' and add to it one new class 'newclass' . I can easily do it by $('.myclass').addClass('newclass');
Secondly I want to search the DOM if there is a < td > which has the same data-date with the .myclass < td > and add also to the newly found < td > the .newclass
Thank you in advance
You can use:
$('td[data-date='+$('.myclass').data('date')+']').addClass('newclass');
This will satisfy the both condition you are looking for. i.e. adding class to both the td elements.
$('.myclass').data('date') will get the date for myclass element. and attribute value selector to target all the td elments that have same data as that of myclass including myclass itself.
You could simply do:
$('.myclass').each(function () {
$('td[data-date="' + $(this).attr('data-date') + '"]').addClass('newclass');
}):
This will add the new class to each element with the same data-date, including the original one with myclass
Also, this would work fine even if you have multiple rows with a myclass - assuming your question was made more basic than your actual need.
Try this
$("td[data-date='2015-07-09']").addClass('myClass');
You can make it more simple if you give an id to your tables.
Like first-table-name and second-table-name.
In this case you will be able to do this with this code:
$("#first-table-name .myclass").each(function() {
$(this).addClass("newClass");
$("#second-table-name td[data-date='" + $(this).data('date') + "']").addClass("newClass");
});

How to get Upper HTML Tag with Jquery

I trying to a class to my html page with jquery, here is my code.
<tbody>
<tr>
<td class="itmId">1</td>
<td class="entryNAmee">David</td>
</tr>
<tr>
<td class="itmId">2</td>
<td class="entryNamee">Alan</td>
</tr>
</tbody>
I am changing the td to input text with jquery on clicking in the every td except 1st column. that is working fine and when the above event perform the tr become like below.
<tr>
<td class="itmId">1</td>
<td class="entryNAmee nowText">
<input type="text" value="Alan">
</td>
</tr>
After making corrections an event working in blur. code is below.
js.
$(document).on('blur','table tr td input',function()
{
var fieldNewValue = $(this).val();
var fieldNewId = $(this).closest('td.itmId').addClass("kkkkkkkkk");
//console.log(fieldNewId);
alert(fieldNewId);
/*$.ajax({
typr:"post",
url:"updateEntry",
dataType:'json',
data:{newValue:fieldNewValue},
success:function(data)
{
console.log("updated succesfully");
}
});
*/
$(this).parents('td').text(fieldNewValue).removeClass('nowText');
$(this).remove();
});
I Want to add a class to the upper td of the the clicked td.
I tried the closest and parents jquery api's, But didnt work,
Anyone can please support me to how to catch the td ?
Also what are the different between closest and parents in jquery.
Thanks
Change:
var fieldNewId = $(this).closest('td.itmId').addClass("kkkkkkkkk");
to:
var fieldNewId = $(this).closest('tr').find('td.itmId').addClass("kkkkkkkkk");
You can read the docs to see the differences between .closest() and .parents(), however in your code you weren't traversing far enough up the DOM. $(this).closest('td.itmId') was looking for a td that didn't exist where you expected it to since it's a sibling of the parent cell that you were in.
You could also use (this).closest('td').prev() instead of (this).closest('tr').find('td.itmId')
There is also .prev in jQuery which returns the "upper" or better previous element in current context. It works just like this:
$(this).prev().addClass('kkkkkkkkk')

Jquery :first selector give second element instead of first

I want select first row from any cell so I just wrote javascript like.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody tr:first");
alert($(firsttd).text());
And my table is below
<table id="idTable_1" border="1px" width="97%" class="tblDragTable" data-numberofrows="2" data-numberofcolumns="2">
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
</table>
when I use find() it giving me correct result
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody").find("tr:first");
But I just want to know why the above code return second tr instead of first tr
HERE IS MY JSBIN http://jsbin.com/lisozuvade/1/watch?html,js,output
The reason why it fails is because calling parents with a filter of table tbody tr will only match the immediate parent TR. The other TR falls outside of the ancestors so :first will match the only TR it finds.
If you try this you will see what is going on:
alert($(curcontrol).parents('table tbody tr')[0].outerHTML);
returns this:
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
then try this:
alert($(curcontrol).parents('table tbody')[0].outerHTML);
which returns this:
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j28g27m1/
So your first example only looks at the ancestors (one TR) and returns the first match. The second example looks further back up the tree, then finds all TRs in the tbody then chooses the first one.
A preferred, slightly faster, way would be to use closest() and find()
e.g.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr:first");
or faster yet (as selectors are evaluated right-to-left):
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr").first();
e.g. http://jsfiddle.net/TrueBlueAussie/j28g27m1/1/
You're asking for parents of #cellno_111, only that tr is.
Also keep in mind that :first is like .first() as it filters to the first element in the set of matched elements, it has nothing to do with being the first child of something. If you want multiple elements, which are first children you should use :first-child.
.parents(table tbody tr:first): query the parents of the element for a tr which is inside of table and tbody, then pick the first
.parents("table tbody").find("tr:first"): query the parents of the elements for a tbody which is inside a table, then find all trs inside of it, then pick the first of them
PS: I suggest using closest instead of parents as the go-to DOM navigation method for ancestors; most of the times it's way more practical and easier to understand.
Actually, you need to understand what each selector is doing. Try with several console.log, you'll see:
$(curcontrol).parents();
This return a set of elements. In this set, there is only 1 tr, the parent of your curcontrol td tag.
You can indeed filter this specific set by adding a extra filter :
$(curcontrol).parents("table tbody tr:first");
But as I just explained, the original set only contains a single TR, so the first one returned is actually the only one returned.
Your find() approach is different, you specify a specific (parent) element and with the find() you search trough children, which explains in this case the correct behaviour.
If I'm not mistaken, the parent hierarchy of cellno_111 is:
trno_11 -> tbody -> table
In your first example, the first tr parent cellno_111 finds is trno_11 and not trno_10. It does not have a trno_10 parent.
The reason it does work with find(), is because you select the tbody and then search for the first tr child the tbody has.

Add event listener to DOM elements based on class

I have a table, where each tr and td have only classes, I have a problem with selection of td element having the class I need
HTML:
<table>
<tr class="data">
<td class="cell">1</td>
<td class="cell2"></td>
</tr>
<tr class="data">
<td class="cell">2</td>
<td class="cell2"></td>
</tr>
</table>
When mouseover td with class="cell" I have to get text between td on which my mouse and do something with this. This should be done with pure JavaScript, without frameworks. I tried:
var cell = document.querySelector('.cell');
function callback(){ //do something }
cell.addEventListener('mouseover',callback(),false);
It doesn't work, or maybe I did mistakes?
The following will only select the first element with class='cell'.
document.querySelector('.cell');
For adding event listener to all such elements, use querySelectorAll(),
which will return a NodeList (a kind of array of inactive DOM elements) having class='cell'. You need to iterate over it or access specific element using it's index.
For example:
var cells = document.querySelectorAll('.cell');
cells.forEach(cell => cell.addEventListener('mouseover', callback, false));
Check this fiddle
I would rather use event delegation for this.
document.getElementById('your-table').addEventListener('mouseover', function (e) {
var t = e.target;
if (t.classList.contains('cell')) {
console.log(t.textContent);
}
});
However "It doesen't work, or maybe I did mistakes?"
querySelector returns a single element.
cell.addEventListener('mouseover',callback(), here callback() calls the callback function right away and that's not what you want. You want to pass the function reference so remove the ().
Note that even if you use querySelectorAll which returns a node list, it doesn't implement the Composite pattern so you cannot treat a list as a single element like you would do with a jQuery object.
Most modern js environments now support for...of iteration, so you can now do this like:
for (var cell of document.querySelectorAll('.cell')) {
cell.addEventListener('mouseover',callback,false);
}
This might even work in a single line:
document.querySelectorAll('.cell').map(cell=>cell.addEventListener('mouseover', callback, false));

How to get inner tr tag using JQuery?

I am trying to grab documentnumber attribute from the tr tags inside tbody, and save it in an array.
Below is the html , I am working on
<tbody class="line-item-grid-body">
<tr data-group-sequence-number-field-index="" data-sequence-number-field-index="1" documentnumber="80" documentid="4133604" parent="80" class="line-item parent-line-item line-item-show reorderable-row droppable-element">
<td>
<table>
<tbody>
<tr></tr>
</tbody>
</table>
</td>
</tr>
<tr data-group-sequence-number-field-index="" data-sequence-number-field-index="1" documentnumber="80" documentid="4133604" parent="80" class="line-item parent-line-item line-item-show reorderable-row droppable-element">
</tr>
</tbody>
and this is what I did, which is not working. If I don't specify particular class then system also grabs inner tr tags, which I don't want
var docs = jQuery("#line-item-grid").find('tbody').find("tr[class='line-item parent-line-item line-item-show reorderable-row droppable-element']");
for (i=1;i<=docs.length;i++)
{
var tempValue = jQuery(docs[i]).attr('documentnumber');
alert(tempValue);
}
Any ideas?
There's several ways you could go about this. I would do the following....
var docs = $('.line-item-grid-body>tr');
Docpage: Child selector
Another option:
var docs = $('.line-item-grid-body').children('tr');
Bookmark and frequent this page ... Selectors - jQuery API
try this as your selector
$('tbody > tr','#line-item-grid');
Hmm i didn't test this (so check for typos), but off top of my head, i'd try something like this:
jQuery(".line-item-grid tbody > tr").each(function() {
alert($(this).attr('documentnumber');
});
You can define selectors one after another, pretty much same as in CSS.
Also check child selector (http://api.jquery.com/child-selector/) for selecting direct child elements.
Hope it helps

Categories