Don't Know How to Change Table's Row Color Depending on Cell Contents; HTML and XML
I am working on a project where I have 5 XML files that I bring into HTML and display the tables on one browser page. I would like for the row of the tables to change depending on what is in the "status" field. There will only be the following inputs in that column - "IS" which is in stock(green), "OS" which is out of stock(red), and "PO" which is Pre-Order(blue).
I only included the first part of the html code along with the first table, but there is a table for each xml file. You can also probably tell how the XML files are structured by looking at the way they are displayed in the tables.
I think what I want to do can be accomplished with JavaScript, but I have no idea how to do it and it's the only thing I have left before I'm done.
Any help would really be appreciated and thanks in advance.
Ummm...I hope you are aware your code *ONLY* works in Internet Explorer.
The whole concept of "data islands" is entirely a Microsoft thing.
So most of us will avoid it, since it is useless in an internet situation; only useable in inTRAnet where you can control what browser people must use.
And I have certainly never used it.
Having said that... Yes, you should be able to do this pretty easily.
Put this in the <head> section of the page:
Code:
<script type="text/javascript">
function fixStatus( )
{
var rows = document.getElementsByTagName("tr");
for ( var r = 0; r < spans.length; ++r )
{
var row = rows[r];
var spans = row.getElementsByTagName("span");
for ( var s = 0; s < spans.length; ++s )
{
var span = spans[s];
if ( span.datafld != null && span.datafld == "status" )
{
var val = span.innerHTML.toUpperCase();
switch ( val )
{
case "IS":
row.style.color = "green";
break;
case "OS":
row.style.color = "red";
break;
case "PO":
row.style.color = "blue";
break;
default:
row.style.color = "orange"; // ?? unknown status ??
break;
} // end of switch
break; // out of for loop on spans
} // end of if-status-span found
} // end of spans loop
} // end of rows loop
}
window.onload = fixStatus;
</script>
If that doesn't work, it might be because the fixStatus code is happening too soon.
You could then try changing that last line to something like
Code:
window.onload = function() { setTimeout(fixStatus, 1000); /* wait 1 second then try */ };
This is all pure guesswork, but it has to be close to the right idea.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Hey OP, first, thanks so much for replying. And yes, it is for an intranet type site and all they use is IE, so we are good there. I've inserted the code in the first window and it didn't work. I also changed the last line, and that didn't work either. It looks like it should work to me, so I'm not sure where it's off. Could you take a look again when you have time and see if there are some changes that would make it work. Once again, I really appreciate it.
Well, the problem is, I don't know *WHEN* MSIE builds the final HTML off of that "data island" stuff.
If it built it all before the window was considered loaded, then the first stuff I gave you should have worked. But it, for example, the page is considered loaded *before* it does the data island stuff and it then takes, say, 5 seconds to do that stuff, then my setTimeout of one second wouldn't be long enough.
It's also possible that the innerHTML of those <span>s actually contains more than just the two letter codes you show. Maybe the data island stuff shoves other HTML in there, as well?
All of this presupposes I didn't make a typo in that code.
I think at this point you either have to provide us with a fully testable page--either a URL to look at or the complete code including some sample XML (maybe just one XML file?)--or you are going to have to try debugging it yourself. MSIE 8 and MSIE 9 have quite usable debuggers built in.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
I just noticed that your HTML is illegal. You are missing the final </table>. Would that affect the iteration through the <tr> rows? Dunno.
But now that I look at it, I can see that one problem is that you are using nested <table>s, so we really need to restrict my code to only looking at the inner <table>.
Not hard.
In place of the line
Code:
var rows = document.getElementsByTagName("tr");
just use
Code:
var rows = document.getElementById("FICTIONTABLE").getElementsByTagName("tr");
If you need to do this for several tables, we can adapt that easily enough. But try it just with FICTIONTABLE first.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
You *MUST* have your HTML tags *correctly* nested.
And by the way where is with this:
Code:
<table id="FICTIONTABLE" table width="100%" datasrc="#nb_fiction"
font size="1" border="0" align="center" bordercolor="#FFFFFF">
Those aren't valid properties of a <table> element! And what's the point of giving a bordercolor when there isn't any border? (border="0" says "no border")
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
OP!!!!!! You are a genius!!! Thanks for figuring it out for me and thanks for reminding me how much of a noob I am at this.
There is only one thing left to do. It changes the color of the data in the table as opposed to the background behind the words. I tried row.style.backgroundcolor in the script but that doesn't work.
You got one more little tidbit for me?
Oh, wait...that was in Firefox. Let me try MSIE 9.
No, worked fine in MSIE 9.
Looks ugly with those color names. You'd probably want to use "#xxxxxxx" instead of names, to get background colors you like.
But this worked:
Code:
function fixStatus( )
{
var rows = document.getElementById("FICTIONTABLE").getElementsByTagName("tr");
for ( var r = 0; r < rows.length; ++r )
{
var row = rows[r];
var spans = row.getElementsByTagName("span");
for ( var s = 0; s < spans.length; ++s )
{
var span = spans[s];
var dfl = span.getAttribute("datafld");
if ( dfl != null && dfl == "status" )
{
var val = span.innerHTML.toUpperCase();
switch ( val )
{
case "IS":
row.style.backgroundColor = "green";
break;
case "OS":
row.style.backgroundColor = "red";
break;
case "PO":
row.style.backgroundColor = "blue";
break;
default:
row.style.backgroundColor = "orange"; // ?? unknown status ??
break;
} // end of switch
break; // out of for loop on spans
} // end of if-status-span found
} // end of spans loop
} // end of rows loop
}
window.onload = fixStatus;
Oh...I know what it might be! You have <span class="style1">
If you are specifying a background color for that style1 it would overrided the row background color.
For that matter, if your <style>s are giving a default background color for the <td>s, that would do it, as well.
function fixStatus( )
{
var rows = document.getElementById("FICTIONTABLE").getElementsByTagName("tr");
for ( var r = 0; r < rows.length; ++r )
{
var row = rows[r];
var spans = row.getElementsByTagName("span");
for ( var s = 0; s < spans.length; ++s )
{
var span = spans[s];
var dfl = span.getAttribute("datafld");
if ( dfl != null && dfl == "status" )
{
var val = span.innerHTML.toUpperCase();
var color = "";
switch ( val )
{
case "IS":
color = "green";
break;
case "OS":
color = "red";
break;
case "PO":
color = "blue";
break;
default:
color = "orange"; // ?? unknown status ?? or just omit this
break;
} // end of switch
if ( color != "" )
{
var elems = row.getElementsByTagName("*");
for ( var e = 0; e < elems.length; ++e )
{
elems[e].style.backgroundColor = color;
}
}
break; // out of for loop on spans
} // end of if-status-span found
} // end of spans loop
} // end of rows loop
}
window.onload = fixStatus;
See? I just run a loop on all sub-elements of the row and force all background colors to the chosen color.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Thank you again OP...you are a gentleman and a scholar! HOWEVER, I'm stuck again. I think this really may be the last time though. You told me in an earlier post that you would show me how to run through all the xml files (tables) once we got the FICTION one working. How do we do that?
"Juanita" is a spammer. That was a clone from my first post. She (ha! wanna bet!) had some illegal html links in there that the forum software removed. Her post should be gone soon, then we can remove these last two posts.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
You told me in an earlier post that you would show me how to run through all the xml files (tables) once we got the FICTION one working. How do we do that?
Change these first 3 rows:
Code:
function fixStatus( )
{
var rows = document.getElementById("FICTIONTABLE").getElementsByTagName("tr");
Into this:
Code:
function fixStatus( )
{
fixTable("FICTIONTABLE");
fixTable("...id of another table...");
... ditto for each table ...
}
function fixTable( tableid )
{
var rows = document.getElementById( tableid ).getElementsByTagName("tr");
and leave all the rest alone.
See? We simply do one table at a time.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.