Traversing the DOM indepth - javascript

Let's say I have this TR tag
<tr>
<td>1</td>
<td><a class="links" href="http://www.linkedin.com/in/jannuelanarna">Jannuel Christian Anarna</a></td>
<td>Calabarzon, Philippines</td>
<td>Market Research</td>
<td>BDA Partnership</td>
<td>Inside Sales Representative</td>
<td>Invite</td>
<td><input type="checkbox" /></td>
</tr>
Now I've targeted the a.links with :
var memberDiv = document.getElementByClassName('links');
Now in my code, i have a loop that evaluates if the href value has a match on an array. And it will return an array matching the values. Now my question is, how could I target the <td> with an a href, and remove the anchor tag?.

After reading, I think I understand. You want to remove the anchors within the TD elements that have been found as a match and convert them to regular text, right?
jQuery code to unwrap the anchors would look like this.
$('tr td a[href="matched-link.html"]').contents().unwrap();
Here's a fiddle showing a test of what I think your question needs: http://jsfiddle.net/EcKKt/
Edit:
For fun, I also created a pure JS example of the same thing here: http://jsfiddle.net/xhR85/
The gist is this:
matches.forEach(function(match, i) {
elements = document.querySelectorAll('tr td a[href="' + match + '"]');
Array.prototype.forEach.call(elements, function(element, ii) {
element.parentNode.innerHTML = element.innerHTML;
});
});

Related

Get value of td table using hierarchy css (without id/classes) with javascript

I'm trying get the value of td value usgin hierarchy css with javascript.
This is my code:
This code returns the value of first td when I click in element, but my alert is undefined.
How I can solve it?
var ee = $(".table tr td:nth-child(1)").attr('value');
$(".table").on('click', function (e) {
e.preventDefault();
alert(ee);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
<tr>
<td>one</td>
<td>two</td>
</tr>
</table>
<td> do not have values, that's why:
var ee = $(".table tr td:nth-child(1)").text();
$(".table").on('click', function (e) {
e.preventDefault();
alert(ee);
});
Your click event is fine. You're just grabbing an undefined item, hence why the alert is acting how it is. You need to grab <td>--this--</td>
Helpful Advice:
This isn't going to give you the text of the 1st <td>, since that's not how nth child works with this. If you want that, try this as a selector:
var ee = $(".table tr td:eq(0)").text();
0 would be the first, 1 is second, 2 is third, etc.
You can also drop the e.preventDefault() and e in the function heading. A table has no default action unlike a form or button.
use
var ee = $(".table tr td:nth-child(1)").html();
instead of
var ee = $(".table tr td:nth-child(1)").attr('value');
First one would refer to a value property on the tag, like an input one. eg : <input type="radio" name="field" value="1" >

Is there simple way to get array from td elements on page? (node.js/cheerio/jQuery)

I am using node.js/cheerio (the same as jQuery syntax) to parse the page.
And when I am using:
$ = cheerio.load(body);
console.log($('.td-title a').text());
I have in my console very long string from words "mainaboutcontactusprofile" etc. How can I make an array of td text?
None of the answers provided worked for me, but this did.
let arr = $('.td-title a').toArray().map((x) => { return $(x).text()});
Credit: Github
jQuery's map()
console.log($("td").map(function(){ return this.textContent}).get());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
</table>
I suggest using jQuery's $.map() function for this. It creates an array based on a matched set of elements:
var textArray = $('.td-title a').map( function(index, domElement) {
return domElement.innerText; //each element input gets turned into text output
});
console.log( textArray );
See http://api.jquery.com/map/ for more details
in javascript
simply document.getElementsByTagName("td") return an array of all td.
Using jQuery you should use something like $('#table1 td')

select the class of td

I want to select the class of the td that is clicked inside my table and then pass it to a function.
<table>
<tr>
<td class = "Vespalx">Vespa lx</td>
</tr>
</table
So in jQuery I tried to select it whit:
$type = $(this).closest("table").find("div");
then I want to perform an action on $type:
$type.click(function(){
$("body").hide();
}):
But now nothing happens!
Did I make a fault with selecting the div?
Is this helping ?
$('td').click(function(){
$(this).attr('class');
// or
$this.classList;
});
You are searching for a div. There isn't any div in your sample code.
I adapted your piece of javascript to find the td.
$type = $(this).closest("table").find("td");
alternatively you could use the css class selector (Vespalx) also.
You need to clarify what is $(this) in your code. However this is a solution:
$type = $("body").find("table").find("td");
$type.click(function(){
$("body").hide();
});
I replaced $(this) with $("body") and I used find method to get the table instead of closest that doesn't work for me. Then I fix the error of second find. In your second find you search for a div and not for a td. At the end of your code I see : and this is wrong. You must use ; and not :
Tnx for all the answers!!!
Know I see that my question was a vague.
But what I wanted was select the class of the td that is clicked and then do something with this class.
See my code:
function scooter (klas) {
var clas = $(klas);
clas.addClass("allscootervis");
//$(".allscooter").css("display", "block");
//$scooter = $("div > this", ".ScooterContent");
$(".introduction").replaceWith("");
}
$("td").click(function(){
$typeun = $(this).attr('class');
//$type = '$(".' + $typeun + '")';
$type = '.' + $typeun;
scooter($type);
});

jQuery change all tr classes after specified one

I have a data table with alternating row background colors. I have an AJAX script to delete a row. I can't come up with a way to change the class of all the rows beneath the one that was deleted so that it alternates correctly again.
For example, considering the following:
`<tr id="1" class="row1">
<td>blah</td>
</tr>
<tr id="2" class="row2">
<td>blah</td>
</tr>
<tr id="3" class="row1">
<td>blah</td>
</tr>
<tr id="4" class="row2">
<td>blah</td>
</tr>`
Now, using my AJAX script, I remove id2, then id3 will move underneath id1 and they will have the same row color. I managed to make my script change the next tr class, but that doesn't really help because then it's just the same color as the one after that. I can't figure out how to iterate through all of the next tr's, and change their class accordingly.
What I have so far:
$('#news_' + id).fadeOut('slow');
var currtr = $('#news_' + id).attr('class');
var nexttr = $('#news_' + id).closest('tr').next('tr').attr('id');
$('#' + nexttr).removeClass($('#' + nexttr).attr('class'));
$('#' + nexttr).addClass(currtr);
You could just iterate over the visible<tr> elements, and remove the class from the even ones, and apply to the odd ones.
Something like this:
Example: http://jsfiddle.net/2CZdT/
$('tr:odd').addClass('odd');
$('td').click(function() {
$(this).parent().fadeOut(function() {
$(this).siblings('tr:visible').filter(':even').removeClass('odd')
.end().filter(':odd').addClass('odd');
});
});​
I have the click event on the <td>, so when one is clicked, it traverses up to the parent <tr> element, fades it out, the in the callback, it grabs all visible sibling <tr> elements, filters the even ones, removes the .odd class, then goes back and filters the odd ones, and adds the .odd class.
Note that this presumes there's a default class applied in your CSS, then you override the odd ones (or even ones) with the alternating class.
Easiest way is to go over the whole table again, e.g. add this after the fadeOut:
$('#id_of_your_table tr:even').addClass('even');
Edit: on second thought, that won't work since the row you faded still exists, but just isn't visible. You need to remove it from the DOM, or skip it when re-applying the zebra-effect. Example:
$('#news_' + id)
.fadeOut('slow')
.remove()
.closest('table')
.find('tr:even').addClass('even');
Or:
$('#news_' + id)
.fadeOut('slow')
.addClass('skip')
.closest('table')
.find('tr:not(.skip):even').addClass('even');
You can also target the table directly as in the first example, but you might as well move up from the faded row to the table its in.
You could use the next siblings selector to get all the rows following the one you are going to delete. Delete the desired row. Then, you should already have the following siblings, so just .each() them and change their class.
E.g.
var followingRows = $("#id2 ~ tr");
$("#id2").remove();
followingRows.each(function() {
if (this.is('.even')
this.removeClass('even').addClass('odd');
else
this.removeClass('odd').addClass('even');
});
Something close to that...
Let CSS do the work for you.
table tr:nth-child(2n+1) {
background-color: #eef;
}
no JavaScript required! =)
I would do something like this:
$('news_' + id).fadeOut('slow', function() {
$(this).remove();
});
var i = 1;
$('tr').removeClass().each(function() {
if (i == 1) {
$(this).addClass('row' + i);
i++;
} else {
$(this).addClass('row' + i);
i--;
}
});

jquery to find all exact td matches

$('#servertable td:eq(' + server + ')')
this finds only 1 (first I think) match, how to find all matches.
btw. td:contains will not work for me.
eq expects a numerical index to only return a single row. If you want to match a td by its contents, you have to use the :contains selector. Saying "it doesn't work" and throwing it away is not the right approach to the problem, as the selector is (most likely) not at fault (Do note its case sensitive, which might be it...)
Anyhow, if you have a table like this:
<table>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
<tr>
<td>World</td>
<td>Hello</td>
</tr>
<tr>
<td>Hello</td>
<td>Hello</td>
</tr>
</table>
This jQuery code:
$(function() {
$("td:contains('Hello')").css('color','red');
});
Will turn all cells with "Hello" to red. Demo.
If you need a case insensitive match, you could do this, using the filter function:
$(function() {
var search = 'HELLO'.toLowerCase();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(search) != -1;
}).css('color','red');
});
If you need to match the exact contents of the cell, you could use something similar to the above:
$(function() {
var search = 'HELLO'.toLowerCase();
$("td").filter(function() {
return $(this).text().toLowerCase() == search;
}).css('color','red');
});
The above is case insensitive (by turning both the search and the contents to lower case when comparing) otherwise you can just remove those if you want case sensitivity. Demo.
I could be wrong, but the :eq positional selector takes an integer n an finds the nth matching element.
So if you said td:eq(1) -- you'd get the 2nd TD element in the table (second because the first index is zero/0).
My guess is that you don't want to use the :contains selector because you're looking for an exact string match and don't want partial matches.
I'm not aware that jquery has a built in selector that will meet your needs (if so, please correct me). You could add one as an extension or use another method, such as an attribute selector to do the search for you.
If you are able to control the generated HTML, you could add an ID attribute to each TD like so:
<table id="servertable" border="1">
<thead>
<tr><th>Server</th><th>Memory</th></tr>
</thead>
<tbody>
<tr><td id="server_mars">Mars</td><td>4 GB</td></tr>
<tr><td id="server_venus">Venus</td><td>1 GB</td></tr>
<tr><td id="server_jupiter">Jupiter</td><td>2 GB</td></tr>
<tr><td id="server_uranus">Uranus</td><td>8 GB</td></tr>
<tr><td id="server_mars_2010">Mars_2010</td><td>4 GB</td></tr>
</tbody>
</table>
<form>
<label for="server">Find:</label><input type="text" id="server" />
<button id="find">Find</button>
</form>
The following attribute selector would locate the correct TD in the table:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#find").click(function() {
var server = $("#server").val();
$("#servertable td").css("background-color", ""); // reset
$("#servertable td[id='server_" + server.toLowerCase() + "']").css("background-color", "#FFFF00");
return false;
});
});
</script>
If you instead want to target the entire row that has the TD that you're looking for, you can add additional selectors:
$("#servertable tbody tr").css("background-color", "");
$("#servertable tbody tr:has(td[id='server_" + server.toLowerCase() + "'])").css("background-color", "#FFFF00");
The tbody tag isn't completely necessary, it just helps to distinguish between rows in the table body and rows in the table header.
Try :containsExact
http://wowmotty.blogspot.com/2010/05/jquery-selectors-adding-contains-exact.html
$.extend( $.expr[":"], {
containsExact: $.expr.createPseudo ?
$.expr.createPseudo(function(text) {
return function(elem) {
return $.trim(elem.innerHTML.toLowerCase()) === text.toLowerCase();
};
}) :
// support: jQuery <1.8
function(elem, i, match) {
return $.trim(elem.innerHTML.toLowerCase()) === match[3].toLowerCase();
},
containsExactCase: $.expr.createPseudo ?
$.expr.createPseudo(function(text) {
return function(elem) {
return $.trim(elem.innerHTML) === text;
};
}) :
// support: jQuery <1.8
function(elem, i, match) {
return $.trim(elem.innerHTML) === match[3];
},
containsRegex: $.expr.createPseudo ?
$.expr.createPseudo(function(text) {
var reg = /^\/((?:\\\/|[^\/]) )\/([mig]{0,3})$/.exec(text);
return function(elem) {
return RegExp(reg[1], reg[2]).test($.trim(elem.innerHTML));
};
}) :
// support: jQuery <1.8
function(elem, i, match) {
var reg = /^\/((?:\\\/|[^\/]) )\/([mig]{0,3})$/.exec(match[3]);
return RegExp(reg[1], reg[2]).test($.trim(elem.innerHTML));
}
});
$('#servertable td')
will find all td elements, but it's not entirely clear what you expect.
I too encountered this very same problem as the original author. As Paulo the original question poser had. Which selector can I use to match elements based equality check on element contents. At least I presume that's what he did (as did I) try to achieve and that would also explain why he (as well as I) can't use contains for the obvious reasons ra170 pointed out in his comment. Anyhow if someone happens to stumble here looking for the answer to that question here's the short answer to it:
jQuery has no such matcher by default. The solution is to define your own matcher. To tackle the problem at hand see this excellent blog post by Motte.

Categories

Resources