jQuery to select elements based on the text inside them - javascript

How to select a tag having a specific text inside it and nothing else? For example if I have the following:
<table>
<tr>
<td>Assets</td><td>Asset</td>
</tr>
<tr>
<td>Play</td><td>Players</td><td>Plays</td>
</tr>
</table>
Is there any way that I may select the <td>Asset</td> and nothing else. I tried it with contains i.e. $("table tr td:contains(Play)") but it returns all the tds in the second tr (as it should). Whereas I just want <td>Play</td>.
Is there any way to achieve this, like there's a way to select elements based on their attributes. Is there any way to select elements based on the text inside them?

How about that:
var lookup = 'Asset';
$('td:contains('+ lookup +')').filter(function() {
return $(this).text() === lookup;
});
Demo
Try before buy

Try something like this :
$("table tr td").filter(function() {
return $(this).text() === "Play";
})

If it was an input field you can specify something similar, but a little more exact with $('input[name~="Plays"]) so that it would filter out every other word, leaving the value isolated.
Other than that, the only way I know of doing this with a table is with what you had, but also throwing a conditional statement to check the text inside them.
Here is my version of accomplishing this:
http://jsfiddle.net/combizs/LD75y/3/
var play = $('table tr td:contains(Play)');
for (var i = 0, l = play.length; i < l; i++) {
if ($(play[i]).text() === "Play") {
// your script to modify below
$(play[i]).css({"color" : "red"});
}
}

Related

Hide tr (table row) with text content

I'm trying to hide a table row with javascript and css.
I have to admit that I'm still a beginner, so it's likely that I'll ask some stupid questions.
I want to hide a table row that somewhere in a td contains the text 'banana'.
Hopefully someone can help me out, thanks!
I've tried different kinds of code I found on the internet, but can't get anything working. This is what I got so far.
if(document.getElementsByTagName('tr').contains('banana'))
{
document.getElementsByTagName('tr').style.display = 'none';
}
Problem you have is you seem to be thinking in terms of jQuery. JQuery does loops under the hood. Since you are not in jQuery world, you need to do the loops yourself over the collection.
Select the rows
loop over the rows
Read the text
Check if text as match
if it does, hide it
// select all the rows
const rows = document.querySelectorAll('tr');
// loop over the rows
rows.forEach( function (row) {
// get the text of the row
var text = row.textContent; // case insensitive use .toLowerCase()
// see if it is in the string
if (text.includes('banana')) {
// add class to hide the row
row.classList.add('hidden')
}
})
.hidden {
display: none;
}
<table>
<tbody>
<tr>
<td>apple</td><td>$1.00</td>
</tr>
<tr>
<td>pear</td><td>$1.00</td>
</tr>
<tr>
<td>banana</td><td>$1.00</td>
</tr>
<tr>
<td>strawberry</td><td>$1.00</td>
</tr>
</tbody>
<table>
How will this fail? When the text joins between cells there is no whitespace so you can make matches that are not there. Is you search for something that is partial sting in another word that can also be wrong.
Other option you have is instead of looping over the rows, you loop over the cells. And if there is a match in the td, you hide the parent.
Instead of getting tr element you can get all td element and perform the following:
var tdcollection = document.getElementsByTagName('td');
for (var i = 0; i < tdcollection.length; i++) {
if (tdcollection[i].innerText.indexOf("banana") >= 0) {
tdcollection[i].parentElement.style.display = 'none';
}
}
<table>
<tr><td>banana</td><td>test1</td></tr>
<tr><td>grape</td><td>test2</td></tr>
</table>

Append div inside of td and set the value?

I have multiple tables that I need to populate. I use jQuery to loop through table cells. If table cell has data-text attribute I need to append div element. Div element will allow cell to have scroll bar vertical. This way table won't expend if text is too long.
Here is example of my code:
$('#'+tabID+' table tr td').each(function(){
elementID = $(this).prop('id').toUpperCase();
value = $.trim(decodeURIComponent(obj.DATA[elementID]['value']));
if($(this).attr('data-text')) {
$(this).append('<div class="hm_textScroll">'+value+'</div>');
} else {
$(this).text(value).css({'color':'blue','font-weight':'bold'});
}
});
Code above will append div element and set the value but the problem is that if I move to a different table and come back again one more div will append. That creates duplicate. I'm not sure what is the best way to prevent that? Or if there is a better way to work around this. If anyone have suggestions please let me know.
Thanks in advance.
Here you go with a solution
$('#' + tabID + ' table tr').each(function(){
$(this).find('td').each(function(){
elementID = $(this).prop('id').toUpperCase();
value = $.trim(decodeURIComponent(obj.DATA[elementID]['value']));
if(typeof $(this).attr('data-text') != 'undefined') {
if($(this).find('div.hm_textScroll').length > 0){
$(this).find('div.hm_textScroll').text(value);
} else {
$(this).append(`<div class="hm_textScroll">${value}</div>`);
}
} else {
$(this).text(value).css({'color':'blue','font-weight':'bold'});
}
});
});
First loop through each tr then loop through each td.
For check the data-attribute, use typeof $(this).attr('data-text') != 'undefined
In the if statement (true condition) I've used backtick ES6 for appending div container.
Hope this will help you.
If I understand you correctly, you would have to additionally check whether a <div class="hm_textScroll"></div> already exists in the <td>.
One possible solution using vanilla javascript would be this:
const tableElement = document.querySelectorAll('#'+tabID+'table tr td');
tableElement.forEach(td => {
if (td.hasAttribute("data-text")) {
if (!td.querySelector(".hm_textScroll")) {
td.innerHTML='<divclass="hm_textScroll">'+value+'</div>'
}
}
});

Finding a row with a cell with a specific value

I have to mark all rows in a table (and later change the code to delete the rows).
The table structure looks like:
<table class="table table-striped table-condensed" id="buckettable">
<thead>
...cut out
</thead>
<tbody>
<tr class="success">
<td><input class="fld-bucketno" type="checkbox" name="bucket" value="158bf61f-8f66-4dee-9ff6-b9d1f6d4b840" /></td>
<td class="text-right">
<a class="bucketNo" href="/Sim/Staging/1212">1212</a>
</td>
What I am interested in is the value of the anchor in the td - second last line.
I get a json list of id's to delete. First I mark them, then change the code to delete them. That is the idea, at least. Mind me - I know a lot of programming, but Javascript is an unknown land for me ;)
My code so far is:
success: function (resp) {
var table = $('#buckettable').find('tbody')[0];
var length = resp.length;
for (var i = 0; i < length; i++) {
var bucketNo = resp[i];
var rows = table.children.length;
for (var j = 0; j < rows; j++) {
var row = table.children[j];
var bucket = row.find('.bucketNo').text();
if (bucket == bucketNo) {
alert(bucket);
}
}
}
$('#cleanup').modal('hide');
and I fail to filter the rows. I am open to any sensible other approach - hopefully it teaches me a lot.
In the above code I manage to get the row... but then the find('.bucketNo') fails with an aexception that Object # has no method find.... which I find funny because I use that on a form earlier. Pointers to documentation VERY welcome, especially in addition to an answer.
If there is a better way to do that tell me. I was told that search by ID is faster (obviously) but somehow I am not sure - should I set a coded ID (bucket-xxx, xxx being the number) on every row?
There is a much simpler way of doing this.
var targetBucketNo = 1212;
$('#buckettable a.bucketNo')
.filter(function(item) {
return item.text() == targetBuvketNo;
})
.parent()
.remove();
To explain in more detail. The following will get the anchors with the bucketNo class that are inside your #buckettable table.
$('#buckettable a.bucketNo')
Filter will filter the results for ones that have the target bucket number
.filter(function(item) {
return item.text() == targetBuvketNo;
})
Remove will remove the elements
.remove();
You can replace .remove() with .addClass('your-class-name') if you wanted to add a class instead. This would add it to the td element so you should add .parent() before addClass.
You are accessing the native Javascript children, hence find() is not a function. However you can skip around a lot of the native functions you're using by using the jQuery filter method:
var $aTag = $('#buckettable').find('tbody td a.bucketNo').filter(function() {
return $(this).text() == bucketNo
});
alert($aTag.text());
You can also loop all links with the class "bucketNo" and then look if the ID is in your array. After this get the containing TR and delete it or add a class or something:
var resp = [2323,5656]
$('a.bucketNo').each(function() {
if( resp.indexOf( parseInt($(this).text()) ) != -1 )
$(this).closest('tr').addClass('del');
});
http://jsfiddle.net/44cEt/

How do I use regex to do some Javascript string manipulation?

I have a string that begins and ends with the table row tag <tr>...</tr>. There are multiple <td>s inside this, that take the form:
<td class="someClass">TextIWant TextI Do NOtWant</td><td><img src='green.png'></td>
<td class="someClass">TextIWant TextI Do NOtWant</td><td><img src='blue.png'></td>
What I'm looking to do, is look at the color.png, and add a class to the td, and trim some of the text inside the td. The final output should be something like:
<td class="someClass green">TextIWant</td>
<td class="someClass blue">TextIWant</td>
How can I do this with regular expressions?
You probably need to provide a lot more details about what you need to do, but the best course of action would be to use a DOM parser and JavaScript has a very nice one built in (IE8- is not supported).
// Select all odd `td` nodes and iterate over them
Array.prototype.forEach.call(document.querySelectorAll("td:nth-child(odd)"),
function (elem) {
// Get the immediately following sibling (with the img)
var imgTd = elem.nextSibling;
// Get the color from the <img>
elem.className += ' ' + imgTd.querySelector("img").getAttribute("src")
.replace('.png', '');
// Remove the sibling
imgTd.parentNode.removeChild(imgTd);
// Update the initial elements text to remove the undesired text
elem.textContent = elem.textContent.replace("TextI Do NOtWant", "");
});
http://jsfiddle.net/e9vrK/
Id do this with jquery, something like:
var td;
var img;
var color;
$('img').each(function(){
img=$(this);
td = img.closest('td').prev();
color = img.attr('src').split('.')[0]
td.html('the image is '+color+'.png').addClass(color);
});
demo here http://jsfiddle.net/QHkbe/2

JQuery Table Manipulation Inserting rows

What I want to do, in short, is from $(this) being a table row, find the next table row with a class of "example" (not necessarily a sibling).
I.E. use next() to find the next row with a class of "example" which isn't a sibling.
HTML:
<table>
<tr><td>One</td></tr>
<tr class="current"><td>Two</td></tr>
<tr><td>Three</td></tr>
<tr><td>Four</td></tr>
<tr class="target"><td>Five</td></tr>
<tr><td>Six</td></tr>
</table>
JavaScript:
var current = $('.current').next();
while(current.size() && !current.hasClass('target')) {
current = current.next();
}
current.css('color', '#0f0');
OR
$('.current').nextAll('.target').last().css('color', '#0f0');
If you're building those <tr>s from strings, you could do something like that:
var x = '';
for(var i = 0; i < 3; i++) {
x += '<li>Test ' + i + '</li>';
}
$(x).appendTo('#test');
So instead of inserting the table rows one by one, put them together as one string, make a jQuery object from that string and attach that to your table.
This also helps you with performance, since you edit the DOM only once.

Categories

Resources