HTML Dynamic Cell colour change dependent on table cell value

<NEW!>I have managed to make some progress and need help with only 1 issue!
This part solved and displays updated text in column/row "State" every 500 ms.

Can someone help me please.
I would like to change the colour & cell background depending on the text in state column.

Ie Relay 1 has 2 states on/off.
When its ON I would like to change cell "State" background to red and text colour to white.
When its OFF I would like to change cell "State" background to green and text colour to black.

The page is loaded to SD and called by program and all works but don't know where to begin with HTML

Any help much appreciated.

image

<!DOCTYPE html>
<html>
<head>
<script>

function GetArduinoInputs()
        {
            nocache = "&nocache=" + Math.random() * 1000000;
            var request = new XMLHttpRequest();
            request.onreadystatechange = function()
            {
                if (this.readyState == 4) {
                    if (this.status == 200) {
                        if (this.responseXML != null) {
						
							document.getElementById("val0").innerHTML =
                                this.responseXML.getElementsByTagName('analog')[0].childNodes[0].nodeValue;										
							document.getElementById("val1").innerHTML =
                                this.responseXML.getElementsByTagName('analog')[1].childNodes[0].nodeValue;
                                
							document.getElementById("val2").innerHTML =
                                this.responseXML.getElementsByTagName('analog')[2].childNodes[0].nodeValue;
                                
							document.getElementById("val3").innerHTML =
                                this.responseXML.getElementsByTagName('analog')[3].childNodes[0].nodeValue;
                        }
                    }
                }
            }
            request.open("GET", "ajax_inputs" + nocache, true);
            request.send(null);
            setTimeout('GetArduinoInputs()', 400);
        }

</script>
<style type="text/css">
  
.cust2 {
  font-family: Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  width: 500px;}
.cust2 td, .cust2 th {
  border: 1px solid #ddd;
  padding: 5px;}
.cust2 tr:nth-child(even){background-color: #f2f2f2;}
.cust2 th {
  padding-top: 9px;
  padding-bottom: 9px;
  text-align: left;
  background-color: LightSalmon;
  color: white;}
	
</style>
</head>

<body onload="GetArduinoInputs()">
    	
	<table class="cust2">
	<br />
    <th>Relays Alarm Errors</th>
    <th>State</th>
  	<tr><td>Relay 1</td>
    <td><b><span id="val0">...</b></span>
	</td></tr>
	<tr><td>Relay 2</td>
    <td><b><span id="val1">...</b></span>
	</td></tr>
	<tr><td>Alarm</td>
    <td><b><span id="val2">...</b></span>
	</td></tr>
	<tr><td>Error</td>
    <td><b><span id="val3">...</b></span>
	</td></tr>
	</table>
	
</script>
</body>
</html>

What all components you are using and secondly share us the circuit diagram

1 Like

The Electronic components work 100%

I've managed to find this

But I cannot get it to work in column "state"
It works in the Signal column if I define the "Error" signal and choose MediumSeaGreen.
next is looking for error 1 in Green and it doesn't find it!

I will upload the circuit diagram and whole code once I get time to.
This issue is simply a HTML one.

This is what I changed.

<table id="c2-info"; class="cust2";>
      <br />
      <th>Relays Alarm Errors</th>
      <th>State</th>
      <tbody>
  	<tr><td>Relay 1</td>
        <td><b><span id="val0">...</b></span>
	</td></tr>
	<tr><td>Relay 2</td>
        <td><b><span id="val1">...</b></span>
	</td></tr>
	<tr><td>Alarm</td>
        <td><b><span id="val2">...</b></span>
	</td></tr>
	<tr><td>Error</td>
        <td><b><span id="val3">...</b></span>
	</td></tr></tbody>
</table>
<script>
		var t = document.getElementById('c2-info');
			if(t) {
					Array.from(t.rows).forEach((td, rowIdx) => {
					Array.from(td.cells).forEach((cell, cellIdx) => {
					if (cell.innerText == '') {
						cell.style.backgroundColor = 'Tomato';
					}else if (cell.innerText == 'CLOSED') {
						cell.style.backgroundColor = 'Tomato';
					}else if (cell.innerText == 'ALARM') {
						cell.style.backgroundColor = 'Red';
					}else if (cell.innerText == 'Error') {
						cell.style.backgroundColor = 'MediumSeaGreen';
					}else if (cell.innerText == 'Error 1') {
						cell.style.backgroundColor = 'Green';
					}
				});
			});
		}
</script

What's wrong, Why doesn't work?

So it works perfect this part of the table:-

<tr><td>Error</td>

But won't work in the next

<td><b><span id="val3">...</b></span></td></tr>

What am I doing wrong?
Please help me.

You have this two tines; the furst obe should be <script>. The skash indigates the end if a HTML tag.

Not saying that it will solve the problem but it is something that stoid out.

Sorry that's a typo!
Will correct in forum.
Doesn't solve the issue though.
Thanks

If I add this line to code :- document.getElementById("val0").innerHTML = "Error 1";
it does turn the cell Green but obviously it stays Green !
It's as if the value in

<td><b><span id="val3">...</b></span> 

is somehow different to "Error 1" , LightBlue for "..." also works.
I just don't get it!

<script>
	
	var t = document.getElementById('info');
    	document.getElementById("val3").innerHTML = "Error 1";
		if(t) {
			Array.from(t.rows).forEach((td, rowIdx) => {
				Array.from(td.cells).forEach((cell, cellIdx) => {
					
					if (cell.innerText == 'Relay 1') {cell.style.backgroundColor = 'Red';}
                    else if (cell.innerText == "Error") {cell.style.backgroundColor = 'MediumSeaGreen';}
                    else if (cell.innerText == "Error 1") {cell.style.backgroundColor = 'Green';}
                    else if (cell.innerText == '...') {cell.style.backgroundColor = 'LightBlue';}
                    
				});
			});
		}

</script>

image

consider

<table border=1 cellspacing=0 id="c2-info"; class="cust2" > 
 <tr> <th>  Relays Alarm Errors </th> 
      <th>  State </th> </tr> 

 <tr> <td> Relay 1 </td> 
      <td style="background-color:chartreuse"> On </td> </tr>

 <tr> <td> Relay 2 </td> 
      <td style="background-color:yellow"> Off </td> </tr>

 <tr> <td> Alarm </td> 
      <td style="background-color:red"> Alert </td> </tr>

 <tr> <td> Error </td> 
      <td style="background-color:chartreuse"> None </td> </tr>
 </table> 

table

So how will that work?
data in "State" column/row is active and updated every 500 ms.
I need the cell column/row colours to change dependent on the value of the data displayed in the "state" column/row.
Please see code above.
Thanks for you suggestion though.

i presumed your code was already providing content for the data column. i assumed you would also specify the color filed

look this over.

could use less memory by individually formatting each row, which would then need to include content for the 1st column

char tbl [] = {
"<table border=1 cellspacing=0 id=\"c2-info\"; class=\"cust2\" > "
" <tr> <th>  Relays Alarm Errors </th> <th>  State </th> </tr> "
" <tr> <td> Relay 1 </td> <td style=\"background-color:%s\"> %s </td> </tr>"
" <tr> <td> Relay 2 </td> <td style=\"background-color:%s\"> %s </td> </tr>"
" <tr> <td> Alarm   </td> <td style=\"background-color:%s\"> %s </td> </tr>"
" <tr> <td> Error  </td> <td style=\"background-color:%s\"> %s </td> </tr>"
"</table>"
};  

char buf [600];

void
loop (void)
{
}

void
setup (void)
{
    Serial.begin (9600);

    Serial.println (tbl);

    sprintf (buf, tbl,
        "red", "On", "yellow", "Off", "red", "Alert", "chartreuse", "None");
    Serial.println (buf);
}

Yes, content from Arduino code is provided here:-
It prints "No Errors" or "Error 1" the column when state changes but the cell colour doesn't change.

            document.getElementById("val3").innerHTML =
            this.responseXML.getElementsByTagName('analog')[3].childNodes[0].nodeValue;

Its displayed here:-

<td><b><span id="val3">...</b></span>

and post processed here:-

<script>
     var t = document.getElementById('info');
    	document.getElementById("val3").innerHTML = "Error 1";
		if(t) {
			Array.from(t.rows).forEach((td, rowIdx) => {
				Array.from(td.cells).forEach((cell, cellIdx) => {
					
					if (cell.innerText == 'Relay 1') {cell.style.backgroundColor = 'Red';}
                    else if (cell.innerText == "Error") {cell.style.backgroundColor = 'MediumSeaGreen';}
                    else if (cell.innerText == "Error 1") {cell.style.backgroundColor = 'Green';}
                    else if (cell.innerText == '...') {cell.style.backgroundColor = 'LightBlue';}
                    
				});
			});
		}

</script>

If you "print" t or document.getElementById('info') is it non-zero?

presumably the color of the field depends on the content ???

It does!
Please take time to read the whole post!
Thanks.

so you have your answer

https://stackoverflow.com/questions/8722680/changing-style-elements-based-on-cell-contents

It will pick out all

<tr><td>Error</td>

in this part and behave as expected.
but ignores these :-

<td><b><span id="val3">...</b></span> </td></tr>

Why? what am I missing?
BTW it also picks out the <...> but not the id="val3"!

What Am I doing wrong???

The code there is very similar but doesn't fix my issue.

Hello @bms_007 - I've been away from table-making js and css for twenty years, but my guess on this issue is; trying to change the background of a pre-defined cell (or row) might better be solved by pre-defining a "bgred" cell/row and "bggrn" cell/row, then IF a state change becomes 0, use the "bgred" cell/row ELSE use "bggrn" cell/row. I think your code is coloring the cell as you intend, but it then gets overlayed by a higher priority.

Thanks @XFPD could you please elaborate a little, This is my first venture into HXML/XML/CSS and I am no expert. I've spent several days on this issue and find the language counter intuitive.
A example would help tremendously.
Thanks in advance.