Use getElementsByTagName where attribute equals a variable?

jaw0807
jaw0807 used Ask the Experts™
on
I'm trying to make a simple "today in history" function which uses an XML datasource, but I'm running into problems and was wondering if anyone could point out what I'm doing incorrectly. I've done a similar application using server-side code, but wanted to try doing it a different way using AJAX.

Right now the script is using a fixed date, but in the future I'm going to define the variable from today's date, and also allow the user to change the date via dropdown or calendar, which is why I'm playing with the idea of using client-side scripting.

The XML, JS, and HTML are all posted below. Thanks in advance.


test.xml
----------
<?xml version="1.0" encoding="iso-8859-1"?>
<dates>
      <date day="0530">
            <event>
                  <year>1787</year>
                  <fact>Something happened</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0531">
            <event>
                  <year>1776</year>
                  <fact>Blah blah blah</fact>
                  <link>http://www.somelink.com/</link>
            </event>
            <event>
                  <year>1904</year>
                  <fact>Hmmm something had to have happened here</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0601">
            <event>
                  <year>2006</year>
                  <fact>A rat was discovered</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0602">
            <event>
                  <year>1965</year>
                  <fact>Made up information</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0603">
            <event>
                  <year>1932</year>
                  <fact>I have no idea what happened on this date</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0604">
            <event>
                  <year>1843</year>
                  <fact>Blah</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0605">
            <event>
                  <year>1900</year>
                  <fact>Virginia gets its first something or other</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
      <date day="0606">
            <event>
                  <year>1800</year>
                  <fact>More made up gibberish</fact>
                  <link>http://www.somelink.com/</link>
            </event>
      </date>
</dates>


test.js
----------

function todayInHistory(URI) {
      var xmlhttp=false;
      var thediv=document.getElementById("todayinhistory"); //id of div xml will be displayed in
      
      if(!xmlhttp && typeof XMLHttpRequest!='undefined') {
            xmlhttp=new XMLHttpRequest();
      }
      
      xmlhttp.open("GET",URI,true);
      xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4) {
            xmlDoc=xmlhttp.responseXML;
            items=xmlDoc;
            formatXML();      
            }
      }
      
      xmlhttp.send(null);
      
      function formatXML() {
            var mydate="0531" // pass value of today's date...currently static, later create variable from date()
            var thedatescount=items.getElementByTagName('date').length;
            
            //create arrays?
            eventyear=new Array(), eventfact=new Array(), eventlink=new Array()
                        
            for (var i=0;i<thedatescount;i++) {
                  //check if attribute is equal to mydate, if so toss values into array
                  if (items.getElementsByTagName('date')[i].getAttribute('day')==mydate) {
                        if (items.getElementsByTagName('date')[i].getElementsByTagName('event').length==1)
                              eventyear[i]=items.getElementsByTagName('date')[i].getElementsByTagName('year')[0]
                              eventfact[i]=items.getElementsByTagName('date')[i].getElementsByTagName('fact')[0]
                              eventfact[i]=items.getElementsByTagName('date')[i].getElementsByTagName('link')[0];                                                
                  }
            }      
            
            var numberofevents=eventyear.length
            if (numberofevents==0) return false; // check if there is a date to display
                  
            ulTag=document.createElement("ul");
            thediv.appendChild(ulTag);
            
            for (var i=0;i<numberofevents;i++) {
                  var theyear, thefact, thelink
                  theyear=(eventyear.length>0)?theyear[i].firstChild.nodeValue:"null date";
                  thefact=(eventfact.length>0)?thefact[i].firstChild.nodeValue:"nothing happened today";
                  thelink=(eventlink.length>0)?thelink[i].firstChild.nodeValue:"";
                  liTag=document.createElement("li");
                  aTag=document.createElement("a");
                  aTag.setAttribute("href", thelink);
                  aTag.appendChild(document.createTextNode(thefact));
                  liTag.appendChild(document.createTextNode(theyear+": "+aTag))
                  ulTag.appendChild(liTag)
            }      
      }
}

test.html
----------

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script type="text/javascript" language="javascript" src="bin/test.js"></script>
</head>
<body>
<div id="todayinhistory"></div>
<script>
      todayInHistory("http://localhost:80/test.xml");
</script>
</body>
</html>
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2007

Commented:
What problems are you running into?
Also, I don't know if this code is *identical* to your original code, but you have

=items.getElementByTagName('date').length;

but it should be

=items.getElementsByTagName('date').length;  (with an "s", plural...)

Author

Commented:
Nothing is displaying. And I did catch the getElementByTagName. I noticed it while cutting and pasting. But the code still does not display any results.
Commented:
Need to use getElementsByTagName rather than getElementByTagName

Also, you have
if (items.getElementsByTagName('date')[i].getElementsByTagName('event').length==1)
which is missing the brackets, so it is only going to branch for the next line.  Also, for the same line, it won't brank for 0531, since there are two events for that date.
You are setting eventfact twice, the second one should be eventlink.

There are a bunch of errors in the display generation code.  Also, you cannot correctly add the A node to the LI through the createTextNode method.

Here is the (more correct) version, there are probably still bugs, but it works.

function todayInHistory(URI) {
      var xmlhttp=false;
      var thediv=document.getElementById("todayinhistory"); //id of div xml will be displayed in
     
      if(!xmlhttp && typeof XMLHttpRequest!='undefined') {
            xmlhttp=new XMLHttpRequest();
      }
     
      xmlhttp.open("GET",URI,true);
      xmlhttp.onreadystatechange=function() {
            if (xmlhttp.readyState==4) {
            xmlDoc=xmlhttp.responseXML;
            items=xmlDoc;
            formatXML();      
            }
      }
     
      xmlhttp.send(null);
     
      function formatXML() {
            var mydate="0531" // pass value of today's date...currently static, later create variable from date()
            var thedatescount=items.getElementsByTagName('date').length;

            //create arrays?
            eventyear=new Array(), eventfact=new Array(), eventlink=new Array()

            for (var i=0;i<thedatescount;i++) {
                  //check if attribute is equal to mydate, if so toss values into array
                  if (items.getElementsByTagName('date')[i].getAttribute('day')==mydate) {
                  for (var x=0;x<items.getElementsByTagName('date')[i].getElementsByTagName('event').length;x++) {
                              eventyear[eventyear.length]=items.getElementsByTagName('date')[i].getElementsByTagName('year')[0];
                              eventfact[eventfact.length]=items.getElementsByTagName('date')[i].getElementsByTagName('fact')[0];
                              eventlink[eventlink.length]=items.getElementsByTagName('date')[i].getElementsByTagName('link')[0];
                  }
                  }
            }      

            var numberofevents=eventyear.length
            if (numberofevents==0) return false; // check if there is a date to display

            ulTag=document.createElement("ul");
            thediv.appendChild(ulTag);

            for (var i=0;i<numberofevents;i++) {
                  var theyear, thefact, thelink
                  theyear=(eventyear.length>0)?eventyear[i].firstChild.nodeValue:"null date";
                  thefact=(eventfact.length>0)?eventfact[i].firstChild.nodeValue:"nothing happened today";
                  thelink=(eventlink.length>0)?eventlink[i].firstChild.nodeValue:"";
                  liTag=document.createElement("li");
                  aTag=document.createElement("a");
                  aTag.setAttribute("href", thelink);
                  aTag.appendChild(document.createTextNode(thefact));
                  liTag.appendChild(document.createTextNode(theyear+": "))
              liTag.appendChild(aTag)
                  ulTag.appendChild(liTag)
            }      
      }
}

Author

Commented:
Excellent. I should have caught the sloppy errors on my own, but I had completely spaced out iterating through the events, too.

One minor tweak though:

for (var i=0;i<thedatescount;i++) {
                  //check if attribute is equal to mydate, if so toss values into array
                  if (items.getElementsByTagName('date')[i].getAttribute('day')==mydate) {
                  for (var x=0;x<items.getElementsByTagName('date')[i].getElementsByTagName('event').length;x++) {
                              eventyear[eventyear.length]=items.getElementsByTagName('date')[i].getElementsByTagName('year')[x];
                              eventfact[eventfact.length]=items.getElementsByTagName('date')[i].getElementsByTagName('fact')[x];
                              eventlink[eventlink.length]=items.getElementsByTagName('date')[i].getElementsByTagName('link')[x];
                  }
                  }
            }      

Thanks for your help. I will accept your solution shortly, unless you can think of anything else to help me clean up the code a bit.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial