Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XMLHttpRequest - Reuse function for multiple file requests

Status
Not open for further replies.

pugs421

Technical User
Nov 25, 2002
114
US
I am using XMLHttpRequest to request an XML file and display the data in an HTML page. I would like to call upon multiple XML files in the same HTML document without writing a different loadXMLDoc() function for each file that I will need to request. This more of a question on Javascript fundamentals.

How can I request multiple XML files using XMLHttpRequest on the same page while using the same function (loadXMLDoc) to do it? Perhaps using 'this' keyword or creating a class? Both are new to me, so I'm not sure.

<html>
<head>
<script type="text/javascript" >
var xmlhttp
function loadXMLDoc(url)
{
// code for Mozilla, etc.
if (window.XMLHttpRequest)
{
//alert("mozilla");
xmlhttp=new XMLHttpRequest()
xmlhttp.onreadystatechange=state_Change
xmlhttp.open("GET",url,true)
xmlhttp.send(null)
}
// code for IE
else if (window.ActiveXObject)
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
if (xmlhttp)
{
xmlhttp.onreadystatechange=state_Change
xmlhttp.open("GET",url,true)
xmlhttp.send()
}
}
}


function state_Change()
{
// if xmlhttp shows "loaded"
if (xmlhttp.readyState==4)
{
// if "OK"
if (xmlhttp.status==200)
{
displayLibrary();
}
else
{
alert("Problem retrieving XML data:" + xmlhttp.statusText)
}
}
}


function getElementTextNS(prefix, local, parentElem, index) {
var result = "";
if (prefix && isIE) {
// IE/Windows way of handling namespaces
result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
} else {

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";
}
}



function displayLibrary() {
//loops through xml, builds a table and inserts table into Library div
}


function displayCategories() {
//loops through xml, builds a table and inserts table into Categories div
}

loadXMLDoc('Library.xml');
//loadXMLDoc('Categories.xml');

</script>
</head>

<body>
<table width="760" align="center">
<tr>
<td colspan="3"><H3>HEADER</H3></td>
</tr>
<tr>
<td valign="top"><DIV id="Categories"></DIV></td>
<td><DIV id="Library"></DIV></td>
<td>Other Content</td>
</tr>
<tr>
<td colspan="3" align="center">FOOTER</td>
</tr>
</table>
</body>
</html>
 
you could pass your onload function as well as the url:
Code:
function loadXMLDoc(url, onload)
{
// code for Mozilla, etc.
if (window.XMLHttpRequest)
  {
//alert("mozilla");
  xmlhttp=new XMLHttpRequest()
  xmlhttp.onreadystatechange = function() {state_Change(onload) };
  xmlhttp.open("GET",url,true)
  xmlhttp.send(null)
  }
// code for IE
else if (window.ActiveXObject)
  {
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
    if (xmlhttp)
    {
  	xmlhttp.onreadystatechange = function() {state_Change(onload) };
    xmlhttp.open("GET",url,true)
    xmlhttp.send()
    }
  }
}


function state_Change(onload)
{
// if xmlhttp shows "loaded"
if (xmlhttp.readyState==4)
  {
  // if "OK"
  if (xmlhttp.status==200)
  {
      onload();
  }
  else
  {
  alert("Problem retrieving XML data:" + xmlhttp.statusText)
  }
  }
}

function displayLibrary() {
 //loops through xml, builds a table and inserts table into Library div
}

loadXMLDoc('Library.xml', displayLibrary);

-jeff
try { succeed(); } catch(E) { tryAgain(); } finally { rtfm(); }
i like your sleeves...they're real big
 
Would it be better to prototype the state_Change function as a method of the loadXMLDoc object, and assign the onreadystatechange to that method call, rather than to the generic functin call?

I ask, as currently, what happens if a URL is loaded but takes a long while to return, and in the meantime, a different URL is loaded and returns first?

Hope this helps,
Dan



[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
dan, yes that's a better way... i was having trouble writing a test in that manner in the 15 minutes i spent on it though :)

you might also want to check out some of the existing cross-browser libraries available, like sarissa



-jeff
try { succeed(); } catch(E) { tryAgain(); } finally { rtfm(); }
i like your sleeves...they're real big
 
Thanks for the assistance.

Would you mind pointing me in the right direction for the prototype technique?
 
This is how you do a fully encapulated approach treating loadXMLDoc(surl) as a class. Concrete loading of different document will be realized as independent instance of the class.
Code:
<script type="text/javascript" >
function loadXMLDoc(surl) {
    this.id=loadXMLDoc.instances.length;
    loadXMLDoc.instances[this.id]=this;

    this.displayLibrary=function() {
            //loops through xml, builds a table and inserts table into Library div
        alert(surl+"\n"+"inside displayLibrary");    //testing-showing you are here
        }

    this.displayCategories=function() {
            //loops through xml, builds a table and inserts table into Categories div
            alert(surl+"\n"+"inside displayCategory");    //testing-showing you're here
        }

    // code for Mozilla, etc.
    if (window.XMLHttpRequest) {
        //alert("mozilla");
        this.engine=new XMLHttpRequest();
        this.engine.onreadystatechange=this.state_Change;
        this.engine.open("GET",surl,true)
        this.engine.send(null);
    } else if (window.ActiveXObject) {
        //code for IE
        this.engine=new ActiveXObject("Microsoft.XMLHTTP");
        if (this.engine) {
            var obj=this;
            this.engine.onreadystatechange=function() {
                // if xmlhttp shows "loaded"
                if (obj.engine.readyState==4) {
                    // if "OK"
                    if (obj.engine.status==200) {
                        obj.displayLibrary();
                    } else {
                        alert("Problem retrieving XML data:" + obj.engine.statusText);
                    }
                }
            }
            this.engine.open("GET",url,true);
            this.engine.send();
        }
    }
}

window.onload=function() {
        loadXMLDoc.instances=new Array();
	var obj1=new loadXMLDoc('Library.xml');
	var obj2=new loadXMLDoc('Categories.xml');
    }
</script>
I take out function getElementTextNS as it is not yet integrated organically into the functionality in the op's outline.
- tsuji
 
Further notes:
I edited the ie part of the onreadystate and forgot to do the same for the mozilla part. It is the same there. Just replace the right-hand-side this.state_Change by the same lines as in ie part. That is only a trace of editing from op's outline.
- tsuji
 
Thanks a lot for your help, but I still can't get this to work for Mozilla based browsers. I have tried a lot of things, but I just can't get it. Shouln't I just have to move the :

if (this.engine) {
var obj=this;
this.engine.onreadystatechange=function() {
// if xmlhttp shows "loaded"
if (obj.engine.readyState==4) {
// if "OK"
if (obj.engine.status==200) {
obj.displayLibrary();
} else {
alert("Problem retrieving XML data:" + obj.engine.statusText);
}
}
}


block of code into the "if (window.XMLHttpRequest){" condition, but that doesn't work. Your assistance is greatly appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top