Javascript/XML and the XMLHttpRequest object

Discussion in 'JavaScript' started by frankiecostello, Jun 3, 2008.

  1. #1
    I have the following javascript file, html file, and xml file. I've been working on all three for a while with no luck. They aren't very large, this is just a starting point. I want to populate a list with userid's from the xml file, then when you click on a userid in the list, all the events associated with that userid go into the details section underneath the list ordered by date. As of now I can't even properly load the xml file. Am I doing it the right way? Can anyone help? Thanks in advance.

    events.xml
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <events>
    	<event>
    		<userid>mark</userid>
    		<name>Tea Time</name>
    		<description>I'm going to have tea with the queen of england than go for a biscuit</description>
    		<time>24/04/08</time>
    	</event>
    	<event>
    		<userid>BigTyme</userid>
    		<name>Drugs</name>
    		<description>Buy drugs from the guy down the street</description>
    		<time>27/04/08</time>
    	</event>
    </events>
    
    Code (markup):
    dynamic.js
    
    // global request and XML document objects
    var req;
    var eventsDB = "events.xml";
    
    loadXMLDoc( eventsDB ); //statically call the function (because we want this to happen when the page loads)
    
    // retrieve XML document (reusable generic function);
    // parameter is URL string (relative or complete) to
    // an .xml file whose Content-Type is a valid XML
    // type, such as text/xml; XML source must be from
    // same domain as HTML file
    
    function loadXMLDoc(url) 
    {    
        // branch for native XMLHttpRequest object
        if (window.XMLHttpRequest) {
            req = new XMLHttpRequest();
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send(null);
        } 
    }
    
    // handle onreadystatechange event of req object
    function processReqChange() 
    {
        // only if req shows "loaded"
        if (req.readyState == 4) 
        {
            // only if "OK"
            if (req.status == 200) 
            {
                clearUserList();
                buildUserList();
             } 
             else 
             {
                alert("XML data wasn't retrieved:\n" + req.statusText);
             }
        }
    }
    
    // invoked by "Category" select element change;
    // loads chosen XML document, clears Topics select
    // element, loads new items into Topics select element
    /*
    function loadDoc(evt) {
        // equalize W3C/IE event models to get event object
        evt = (evt) ? evt : ((window.event) ? window.event : null);
        if (evt) {
            // equalize W3C/IE models to get event target reference
            var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
            if (elem) {
                try {
                    if (elem.selectedIndex > 0) {
                        loadXMLDoc(elem.options[elem.selectedIndex].value);
                    }	
                }
                catch(e) {
                    var msg = (typeof e == "string") ? e : ((e.message) ? e.message : "Unknown Error");
                    alert("Unable to get XML data:\n" + msg);
                    return;
                }
            }
        }
    }
    */
    
    // retrieve text of an XML document element, including
    // elements using namespaces
    function getElementTextNS( prefix, local, parentElem, index ) 
    {
        var result = "";
        
        // the namespace versions of this method 
        // (getElementsByTagNameNS()) operate
        // differently in Safari and Mozilla, but both
        // return value with just local name, provided 
        // there aren't conflicts with non-namespace element
        // names
        result = parentElem.getElementsByTagName( local )[ index ];
        
        if (result) 
        {
            // get text, accounting for possible
            // whitespace (carriage return) text nodes 
            if ( result.childNodes.length > 1 ) 
            {
                return result.childNodes[1].nodeValue;
            } 
            else 
            {
                return result.firstChild.nodeValue;    		
            }
            
        }  
        else 
        {
            return "n/a";
        }
    }
    
    // empty Topics select list content
    function clearUserList() 
    {
        var select = document.getElementById( "userlist" );
        
        while ( select.length > 0 ) 
        {
            select.remove(0);
        }
    }
    
    // add item to select element the less
    // elegant, but compatible way.
    function appendToSelect( select, value, content ) 
    {
        var opt;
        opt = document.createElement("option");
        opt.value = value;
        opt.appendChild( content );
        select.appendChild( opt );
    }
    
    // fill Topics select list with items from
    // the current XML document
    function buildUserList()   //not fully finished?
    {
        var select = document.getElementById( "userlist" );
        
        var items = req.responseXML.getElementsByTagName( "userid" );
        
        // loop through <item> elements, and add each nested
        // <title> element to Topics select element
        for ( var i = 0; i < items.length; i++ ) 
        {
            appendToSelect( select, i, document.createTextNode(getElementTextNS( "", "title", items[i], 0 ) ) );
        }
        // clear detail display
        document.getElementById("details").innerHTML = "";
    }
    
    // display details retrieved from XML document
    function showDetail( evt ) //not fully finished either?
    {
        evt = (evt) ? evt : ((window.event) ? window.event : null);
        
        var item, content, div;
        
        if (evt) 
        {
            var select = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
            
            if ( select && select.options.length > 1 ) 
            {
                // copy <content:encoded> element text for
                // the selected item
                item = req.responseXML.getElementsByTagName("event")[select.value];
                content = getElementTextNS("content", "encoded", item, 0);
                div = document.getElementById("details");
                div.innerHTML = "";
                // blast new HTML content into "details" <div>
                div.innerHTML = content;
            }
        }
    }
    
    Code (markup):
    main.html
    
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    
    <head>
       <title>Calendar System</title>
       <link href="stylesheet.css" rel="stylesheet" type="text/css" />
    </head>
    
    <body>
    
    	<script type="text/javascript" src="dynamic.js"></script>
    
    	<h1> Calendar Sytem </h1>
    	<hr />
    
    	<form>
    		<p>Users:<br />
    		<select size ="10" id="userlist" onchange="showDetail(event)">
    			<option value"">Parsing XML Data...</option>
    		</select>
    		</p>
    	</form>
    
    	<div id="details"><span></span></div>
    
    </body>
    
    </html>
    
    Code (markup):

     
    frankiecostello, Jun 3, 2008 IP