1

I am currently working on a project wherein values less than or equal to 30% will be colored red in the table. I have written the code below that will check every cell in the table and verify its value and from there execute the condition and highlight it with red if true but somehow it is not doing what I expect. Can you help me understand why it only highlights 0%.

<script>
var td = document.getElementsByTagName("td");
var i = 0, tds = td.length;
for (i; i < tds; i++) {  
    if (parseFloat(td[i].innerHTML) >= 0.00 && parseFloat(td[i].innerHTML) <= 0.30) {
        td[i].setAttribute("style", "background:red;");
    }
}
</script>

I have attached a screenshot to give you a better idea of what is happening. From the example below, it should also color 12.50% and 25.00% red.

enter image description here

Your response is greatly appreciated.

Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
Emc_tgn15
  • 161
  • 1
  • 1
  • 11
  • Please include also the html. What's in the `td`s ? – user2314737 Sep 16 '21 at 08:50
  • Does this answer your question? [strange output in comparison of float with float literal](https://stackoverflow.com/questions/1839422/strange-output-in-comparison-of-float-with-float-literal) `0.1 + 0.2 === 0.3 // false` and it’s not a JavaScript fault, it’s your processor doing this – Krzysztof Krzeszewski Sep 16 '21 at 08:51
  • Why `.setAttribute("style", ...)`? `td.style.backgroundColor = "red"` (or even better use a class and toggle that) – Andreas Sep 16 '21 at 08:53
  • @KrzysztofKrzeszewski, thanks let me check that out – Emc_tgn15 Sep 16 '21 at 08:56
  • @user2314737, it is an embedded code and I can give you a snippet of the html using inspect. – Emc_tgn15 Sep 16 '21 at 08:58
  • 2
    It's not highlighting 30% because you didn't ask it to. You' ve only asked it to highlight values between 0 and 0.3, with the percent sign terminating the float value to process. Change (the typo) of '0.3' to '30' - but that will highlight 1,3350% as well - more code needed :-) – traktor Sep 16 '21 at 08:58
  • @traktor yes that did that trick and you are correct it highlighted the 1,335 as well trying to figure out now how not to include that. – Emc_tgn15 Sep 16 '21 at 09:02

3 Answers3

1

The main issue is what traktor commented: where you put 0.30 instead of 30. However, here's another way you could write that code:

let aryTD = [...document.getElementsByTagName("td")];
const rxCommas = /,/g; // Regular Expression for locating commas
aryTD.forEach((td)=>
{
  let content = td.textContent.replace(rxCommas,""); // remove commas
  let float = parseFloat(content);
  if (float >= 0 && float <= 30)
  {
    td.style.backgroundColor = "red";
  }
});
<table>
<tr><td>1,335.00%</td></tr>
<tr><td>0.00%</td></tr>
<tr><td>0.00%</td></tr>
<tr><td>0.00%</td></tr>
<tr><td>12.50%</td></tr>
<tr><td>25.00%</td></tr>
<tr><td>37.50%</td></tr>
<tr><td>37.50%</td></tr>
<tr><td>37.50%</td></tr>
<tr><td>50.50%</td></tr>
<tr><td>60.00%</td></tr>
</table>
Lonnie Best
  • 9,936
  • 10
  • 57
  • 97
  • 1
    Hi, @Lonnie thank you for taking the time. I tried using your code however in my case 1335.00% is still being highlighted as red because the non-percentage value of 1335% is 13.35 which is below 30. – Emc_tgn15 Sep 16 '21 at 10:02
  • @Emc_tgn15 : Ah, I see. I didn't encounter that because I didn't originally put that comma (it has) into that value of my table. I've added that now, and I've also modified the code to remove all commas before `parseFloat` happens. That should solve your issue. – Lonnie Best Sep 16 '21 at 11:25
  • 1
    Thank you very much. I learned something new today :) I hope it's not too much but can I limit getElementsByTagName to execute only on one column? – Emc_tgn15 Sep 16 '21 at 13:58
  • 1
    Nevermind @Lonnie I have figured it out thanks a lot for your help :) – Emc_tgn15 Sep 16 '21 at 15:20
0

Try This code

var td = document.getElementsByTagName("td");
var i = 0, tds = td.length;
for (i; i < tds; i++) {  
    if (parseFloat(td[i].innerHTML) >= 0.00 && parseFloat(td[i].innerHTML) <= 30) {
        td[i].setAttribute("style", "background:red;");
    }
}
</script>
Jay Patel
  • 1,098
  • 7
  • 22
  • [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) -> _"Any answer that gets the asker going in the right direction is helpful, but do try to mention any limitations, assumptions or simplifications in your answer. Brevity is acceptable, **but fuller explanations are better**."_ – Andreas Sep 16 '21 at 09:00
  • Thanks, @Jay same with traktor's reply above this highlights the values 12.50% and 25.00% however it also includes 1,3350%, I am now checking why it also includes that value. – Emc_tgn15 Sep 16 '21 at 09:07
  • [`parseFloat` is not locale aware.](https://stackoverflow.com/questions/7571553/javascript-parse-float-is-ignoring-the-decimals-after-my-comma). It stops at the 1. @Emc_tgn15 – Andy Sep 16 '21 at 09:20
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 16 '21 at 09:21
0

If the decimal separator always remains a period ('.') and a comma always indicates a number has thousands, you could either

  1. Replace commas with the null string before parsing values as floats, or

  2. Let commas indicate a number is greater than 999.

For an example of the second technique without changing the code a lot:

var td = document.getElementsByTagName("td");
var i = 0, tds = td.length;
for (i; i < tds; i++) {
    var value = td[i].textContent;
    if( value.indexOf(',') < 0) {
       value = parseFloat(value);
       if( value >= 0 && value <= 30) {
          td[i].style.backgroundColor = "red";
       }
    }
}

To limit the td elements processed to a column in the table you can use

to select specific column cells which are the children of rows in a table

Note nth-col is still experimental.

Here's a quick example to get second column cells:

let columnCells = document.querySelectorAll("table tr td:nth-child(2)");
for( var i=0; i<columnCells.length; ++i) {
   console.log( columnCells[i].textContent);
}
<table>
 <tr><td>r1c1</td><td>r1c2</td></tr>
 <tr><td>r2c1</td><td>r2c2</td></tr>
 <tr><td>r2c1</td><td>r3c2</td></tr>
<table>
traktor
  • 17,588
  • 4
  • 32
  • 53
  • thank you very much this is what I was looking for. I learned something new today :) I hope it's not too much but can I limit getElementsByTagName to execute only on one column? – Emc_tgn15 Sep 16 '21 at 13:58
  • all good :) since this is the only column with a percentage I used the same approach you did for comma but this time it will only check the column that has % if ( value.indexOf('%') > 0) – Emc_tgn15 Sep 16 '21 at 15:19
  • 1
    See the updated answer for details of getting a node list limited to cells in a column. – traktor Sep 16 '21 at 15:37