the use of addClass/removeClass of a table td with ajax - javascript

The following code outputs a table with values, and according to the value, it gets a layout. I use jQuery (Ajax) to update the information every 10 seconds.
php script that generates the wanted variables and stores (echoes) them into a json array (example.php)
$variable1 = 20;
if ($variable1 > 0) {
$td_variable1class="positive";
} else {
$td_variable1class="negative";
}
$array['variable1'] = $variable1;
$array['td_variable1'] = $td_variable1;
echo json_encode($array);
html table where the variable is retrieved from the json generated by the example.php:
<table>
<tr>
<td class='variable1class'>
<div id='variable1'></div>
</td>
</tr>
</table>
javascript:
<script type="text/javascript">
$(function() {
refresh();
});
function refresh() {
$.getJSON('example.php', function(data) {
$('div#variable1').html(data.variable1);
$('td.td_variable1').addClass(data.td_variable1);
});
setTimeout("refresh()",10000);
}
The problem is the "addClass" adds a class to the existing class, resulting in an output like this:
before the refresh:
<td class="td_variable1 positive">
after (assuming the variable changed from positive to negative):
<td class="td_variable1 positive negative">
I tried to avoid this by using removeclass:
$('td.td_variable1').removeClass().addClass(data.td_variable1);
But then the actual class name of the td is removed and my output looks like this:
<td class="negative">
and it should look like this:
<td class="td_variable1 negative">
Thanks for your help in advance!

Assuming you only have those 2 options, remove both (and only those two) then add the new one:
$('td.td_variable1').removeClass("positive negative").addClass(data.td_variable1);

.removeClass() removes all classes when not given any parameter. Use .removeClass("negative") instead.

Related

How to obtain text of a <td> element from another <td> element with jquery

I am trying to use a button inside a table division to set a variable as the same value as another division in the same row, but whenever I run my code (below), it returns the value of all the table divisions concatenated together. I am unsure why this was happening, so I replaced '.children()' with 'childnodes[0]' to try and get only the first name, but this just doesn't work and I don't why.
My html looks like this:
<table>
<tr>
<td>John</td>
<td>Doe</td>
<td><button>Get First Name</button></td>
</tr>
</table>
And my Javascript is this:
$(document).ready(function(){
$("button").click(function(){
var first = $(this).closest("tr").childNodes[0].text();
alert(first)
})
});
set a variable as the same value as another division in the same row
there are lots of possibilities for this, here are some (with the most useful first (opinion based))
$("button").click(function() {
var first = $(this).closest("tr").find("td:first").text();
var first = $(this).closest("tr").find("td").first().text();
var first = $(this).closest("tr").find("td").eq(0).text();
var first = $(this).closest("tr").children().first().text();
var first = $(this).closest("tr").children().eq(0).text();
var first = $(this).closest("td").siblings().first().text();
});
it returns the value of all the table cells concatenated together
https://api.jquery.com/text
Get the combined text contents of each element in the set of matched elements, including their descendants, or set the text contents of the matched elements.
because you're passing the "tr" to text() it gets the text of all the cells (tds) and their content etc and combines them as one, so you need to limit to the first as you've attempted.
however .childNodes[0] can only be applied to a DOM element/node, while $(this).closest("tr") gives you a jquery object/collection, which doesn't have .childNodes property.
So the jquery equivalent would be to use .children().eq(0).
You could use class identifiers to get information you need as well.
<table>
<tr>
<td><span class="first-name">John</span></td>
<td><span class="last-name">Doe</span></td>
<td>
<button class="btn-get-data" data-class="first-name">Get First Name</button>
<button class="btn-get-data" data-class="last-name">Get Last Name</button>
</td>
</tr>
</table>
$(document).ready(function() {
$(".btn-get-data").click(function() {
$btn = $(this);
$tr = $btn.closest('tr');
var first = $tr.find('.' + $btn.attr('data-class')).html();
alert(first);
})
});
If you make the button click generic like so, you can add additional buttons on the page and use that to get the class within that row.
Here is a working fiddle example: https://jsfiddle.net/b1r0nucq/
you could find the :first child and get his html(), as below:
$(document).ready(function() {
$("button").click(function() {
var first = $(this).closest("tr").children(":first").html();
alert(first)
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>John</td>
<td>Doe</td>
<td><button>Get First Name</button></td>
</tr>
</table>

Basic Jquery - If Text exists in a TD then Make a DIV Visible

I'm trying to make a Div on the page Appear if a word exists later on the page? , what i'd actually like it to do is display if any words in a list of 10 appear on the page? The only place I want to look for them is inside of that TD class "sku nobr" after that span class "td-title"
I'm a total rookie at this, I got it to work for a H1 value with this code but I don't know how to do it with the 4523 where it is now??
THANKS!!!!!
<script type="text/javascript">
$(document).ready(function(){
if ($(".sku nobr:contains('4523')").length) {
$("#thingtohide").removeAttr("style").none();
}
});
</script>
<div id="thingtohide" style="display: none;">COOL TEXT TO DISPLAY</div>
<tr class="cart-item-row">
<td class="sku nobr">
<span class="td-title">SKU:</span>
4523
</td>
</tr>
First, your HTML is not valid. You're missing the <table></table> tags.
<div id="thingtohide" style="display: none;">COOL TEXT TO DISPLAY</div>
<table>
<tbody>
<tr class="cart-item-row">
<td class="sku nobr">
<span class="td-title">SKU:</span>4523
</td>
</tr>
</tbody>
</table>
Second, your selector is wrong. Replace .sku nobr:contains('4523') with .sku:contains('4523')
$(document).ready(function(){
if ($(".sku:contains('4523')").length) {
$("#thingtohide").show();
}
});
Edit If you are looking for any number (which can include commas), you have to be more creative. You can use the filter method. Here's another demo.
$(document).ready(function(){
// find TD with class 'sku' containing numbers
var $sku = $("td.sku").filter(function () {
// assuming the number is 4523,8563,9997,7757
// text = $.trim($(this).text()); => SKU:4523,8563,9997,7757
// text = text.replace(/SKU:|,/g, ''); => 4523856399977757
var text = $.trim($(this).text().replace(/SKU:|,/g, ''));
// check that it is a number
return text && !isNaN(text);
});
// check if there are any matches
if ($sku.length) {
$("#thingtohide").show();
}
});
It looks like you've got a minor typo.
$(".sku nobr:contains('4523')")
Change to:
$(".sku.nobr:contains('4523')")
Multiple classes need to be separated by a ., not a space.
for checking if a cel contains multiple pieces of text I did this:
<script>
$(document).ready(function(){
if ($(".sku:contains('4523'),.sku:contains('5678')").length) {
$("#thingtohide").show();
}
});
</script>

Getting the value of TD in a foreach loop

I have this code which show me the list of my item
<tbody class="table-color2">
<c:forEach var="defect" items="${defectList}">
<tr>
<td id="defectId"><a onclick="getDefectId()">${defect.id}</a></td>
<td>${defect.createdDate}</td>
<td>${defect.reportedBy.firstName}</td>
<td>${defect.title}</td>
<td>${defect.bugtype.description}</td>
<td>${defect.status.description}</td>
<td>${defect.priority.description}</td>
</tr>
</c:forEach>
</tbody>
what Im trying to do is to get the value of the td id="defectId" when it is clicked, my jquery script for the onclick is this :
function getDefectId(){
var defectId = $(' #defectId ').val();
alert("Defect ID " + defectId);
}
but currently, I'm getting a value of undefined, how do I get the value?
You have several issues. Firstly you're appending the same id in a loop, which will result in duplicates which is invalid. Also, a elements don't have a value to retrieve so you need to use text(). Finally note that using your current method would mean that you need to pass the this reference of the clicked element to the function.
However you can tidy all that up by using classes and hooking up the event in JS. Try this:
<tbody class="table-color2">
<c:forEach var="defect" items="${defectList}">
<tr>
<td class="defect">${defect.id}</td>
<td>${defect.createdDate}</td>
<td>${defect.reportedBy.firstName}</td>
<td>${defect.title}</td>
<td>${defect.bugtype.description}</td>
<td>${defect.status.description}</td>
<td>${defect.priority.description}</td>
</tr>
</c:forEach>
</tbody>
$(function() {
$('.defect a').click(function(e) {
e.preventDefault();
console.log($(this).text());
});
});
Working example
You can do the following(remember that id needs to be unique):
<td class="defectId"><a onclick="getDefectId(${defect.id})">${defect.id}</a></td>
And in you function:
function getDefectId(value){
alert("Defect ID " + value);
}
Try this : use text() instead of val() because you want to know the text inside td and not the value of input element.
EDIT: - Sorry, missed that there are multiple td's. In this case, you must not use same id for all tds. Just make it class and do following changes in function.
function getDefectId(){
var defectId = $('.defectId').text();
alert("Defect ID" + defectId);
}
I would suggest to use jQuery event handler instead of calling javascript function. See below code
HTML: remove onclick call
<td class="defectId">${defect.id}</td>
jQuery : register a click handler and read text
$(function(){
$('.defectId a').click(function(){
var defectId = $(this).text();
alert(defectId);
});
});

Pulling Data from table

I have a table in HTML:
<tr class="inner2-top">
<td class="name1"> Hello </td>
</tr>
How would I get the name1 in a javascript variable function like this?
function grabData() {
var name = // todo
}
You want the data that's inside of the td?
function grabData(className) {
return document.getElementsByClassName(className)[0].innerText;
}
console.log(grabData("name1"));
I suggest using id attributes instead of class attributes if you're going to use this method, though. ids are unique whereas classes are not, which will explain why you get unexpected results if you have more than one element with the class "name1" etc.
var name = $(".name1").text();
Try the above
you can get that text using class selector
var getName=$('.name1').html();
alert(getName);
DEMO

Getting the cell of a <tr> that has particular className

What i'm trying to do is to get the cell of this where the classname is "revision_id".
<tr>
<td class="supplierOrderId">10790</td>
<td class="revision_id">#7</td>
<td class="supplier">DGI Developpement </td>
<td class="quantity">80</td>
<td class="stock">0</td>
<td class="purchase_price">10.00</td>
<td class="comments"> </td>
</tr>
I managed to do it this way :
revision = this.parentNode.parentNode;
revisionId = revision.cells[1].innerHTML.replace( /[^\d.]/g, '' );
(cause I wanna get the int of the string)
iRevisionId = parseInt(revisionId);
Is there a more proper way to do it, with the given className ?
Because in the case where someone adds a cell before mine in the future, my code is going to be "deprecated".
Hope i've given all the details,
Thanks by advance.
// More Details //
The problem with most answers is that they work only if I have 1 <tr>. Once I get multiple, it gets every revisionID like this :
console.log(result) -> #1#2#3#4
(if I have 4 <tr> for exemple)
So this is why I am getting the GOOD one like this :
revision = this.parentNode.parentNode; // outputs the good <tr>
but after that, I can't get the with the given className.
if this is tr
var data = $(this).children(".revision_id").text()
Using the text() method, you can get the text inside your td element.
After that just parse it like you did with parseInt()
$(function() {
var quantity = $('tr td.quantity').text();
console.log(parseInt(quantity));
});
you can do via jquery like this:
var value= parseInt($(".vision_id").text().match(/[0-9]+/g)[0]);
FIDDLE EXAMPLE
Depends on whether you can use jQuery or not.
Pure JavaScript
With pure JS, provided you're using a modern browser, you can use the getElementsByClassName function. For the purpose of this demonstration, I've assumed you have an ID on your table you can use.
var myClassName = 'revision_id';
var table = document.getElementById('mytable');
// the desired TD
var td = table.getElementsByClassName( myClassName ) );
See Mozilla's docs on getElementsByClassName.
Also, this answer works with backwards compatibility.
jQuery
Of course, this becomes easier with jQuery:
var $td = $('#mytable td.revision_id');
Demo here: http://jsfiddle.net/uJB2y/1/
Well if you want it with jquery then you can use .filter() method:
var text = $('td').filter(function () {
return this.className === 'revision_id';
}).text().slice(1);
text = +text; // conversion for int
alert(text);
Demo

Categories