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 bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

make this function return true or false 1

Status
Not open for further replies.

guitardave78

Programmer
Sep 5, 2001
1,294
GB
Hi this function checks an xml file to see if the test value matches anything in the xml file.

Here is the funciton
Code:
var xmlhttp
var clans
var matched = false
function testagainstXML(url,node,test) {
//document.getElementById("maps").innerHTML = "Loading...";
	if (window.XMLHttpRequest) {
		xmlhttp = new XMLHttpRequest();
		xmlhttp.overrideMimeType("text/xml");
	}else {
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}

	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4) {
			if (xmlhttp.status == 200) {
				var xmlDoc = xmlhttp.responseXML;
				for(n=0;n<xmlDoc.getElementsByTagName(node).length;n++){				
					var xmlNodes = xmlDoc.getElementsByTagName(node)[n].firstChild.data;
					if(xmlNodes == test){
						var matched = true
					}
				}
			}else{
				alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
			}
		}
	}
	xmlhttp.open("GET",url,true);
	xmlhttp.setRequestHeader('content-type', 'text/xml'); 		
	xmlhttp.send(null);	
} 

alert(testagainstXML("registerxmlgen.asp","clanname","Test1"))

Test1 should return true, but it seems that it returns the value of the function before it executes the bit in the middle (onreadystatechange = function()) so if i set it to retrun a value at the end of the function and then put an alert in the onreadystatechange = function() bit, i get the value of the function then i get the alert box (seems the wrong way round to me).

}...the bane of my life!
 
You really don't want to put two alert statements in. You should have one line that calls the testagainstXML function, and then the callback function would handle everything else (alerts, etc).

Hope this helps,
Dan



[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
Here's the same code, with the anonymous function seperated as doFoo() to clarify:
Code:
[COLOR=purple]
var xmlhttp
var clans
var matched = false
[/color]

function testagainstXML(url,node,test) {
    [COLOR=green]//document.getElementById("maps").innerHTML = "Loading...";[/color]
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.overrideMimeType("text/xml");
    }else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = doFoo;

    xmlhttp.open("GET",url,true);
    xmlhttp.setRequestHeader('content-type', 'text/xml');         
    xmlhttp.send(null);    
} 
[COLOR=blue]
function doFoo() {
    if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
            var xmlDoc = xmlhttp.responseXML;
            for(n=0;n<xmlDoc.getElementsByTagName(node).length;n++){                
                var xmlNodes = xmlDoc.getElementsByTagName(node)[n].firstChild.data;
                if(xmlNodes == test){
                    var matched = true
                }
            }
        }else{
            alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
        }
    }
}
[/color]
[COLOR=purple]
alert(testagainstXML("registerxmlgen.asp","clanname","Test1"))
[/color]

This from W3C Schools:
: An important property in the example above is the onreadystatechange property. This property is an event handler which is triggered each time the state of the request changes. The states run from 0 (uninitialized) to 4 (complete). By having the function xmlhttpChange() check for the state changing, we can tell when the process is complete and continue only if it has been successful.

Your function 'testagainstXML' loads the XML, and attaches an anonymous function as an event handler for when the ready state of the XML changes.

The anonymous function checks to see if the readystate is 4 (ie complete). It then checks that it had a valid HTTP response (200), instead of a bad url (404).
It parses the XML for a specified node; if the node is found, the variable '[tt]matched[/tt]' is set to true.

Test1 should return true
Then you need a [tt]return[/tt] statement in your function. Neither functions include a return statement. You could try adding "[tt]return matched;[/tt]" to the end of the anonymous function.

---
Marcus
better questions get better answers - faq581-3339
accessible web design - zioncore.com
 
There was a retrun, i took it out pasted the wrong code lol.
separating the function is not much help as it still doesnt seem to change the value of matched before returning testagainstXML.
Using the code you gave this is the ideal situation
Code:
function testagainstXML(url,node,test) {
    //document.getElementById("maps").innerHTML = "Loading...";
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.overrideMimeType("text/xml");
    }else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = doFoo(url,node,test);

    xmlhttp.open("GET",url,true);
    xmlhttp.setRequestHeader('content-type', 'text/xml');         
    xmlhttp.send(null);    
	return matched
} 

function doFoo(url,node,test) {
    if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
            var xmlDoc = xmlhttp.responseXML;
            for(n=0;n<xmlDoc.getElementsByTagName(node).length;n++){                
                var xmlNodes = xmlDoc.getElementsByTagName(node)[n].firstChild.data;
                if(xmlNodes == test){
                    var matched = true
                }
            }
        }else{
            alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
        }
    }
}


alert(testagainstXML("registerxmlgen.asp","clanname","Test1"))
it always returns false as it returns the testagainstXML before it finishes doFoo

}...the bane of my life!
 
here is the xml so you can try it :)

Code:
<clans>
	
	<clan>
		<username>Test1</username>
		<clanname>Test1</clanname>
		<clanshortname>Test1</clanshortname>
	</clan>
	
	<clan>
		<username>Test2</username>
		<clanname>Test2</clanname>
		<clanshortname>Test2</clanshortname>
	</clan>
</clan>

}...the bane of my life!
 
Since the httprequest is on async=true, one way to do it is to check the readiness of data via global scope like your xmlhttp. Like this in sketching out. (I use your wrong cut and paste without return value which is even better suited for a revision.)
[tt]
var xmlhttp
var clans
var matched = false
[tt][red]var bavail=false;[/red][/tt]
function testagainstXML(url,node,test) {
//document.getElementById("maps").innerHTML = "Loading...";
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
xmlhttp.overrideMimeType("text/xml");
}else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
[red]bavail=true;[/red]
var xmlDoc = xmlhttp.responseXML;
for(n=0;n<xmlDoc.getElementsByTagName(node).length;n++){
var xmlNodes = xmlDoc.getElementsByTagName(node)[n].firstChild.data;
if(xmlNodes == test){
//[red]var[/red] matched = true //should be there the var
[red]matched=true;
break; //no need to go further[/red]
}
}
}else{
alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
}
}
}
xmlhttp.open("GET",url,true);
xmlhttp.setRequestHeader('content-type', 'text/xml');
xmlhttp.send(null);
[red]checking();[/red]
}

function checking() {
if (bavail) {
//boolean return can be deviced separately using matched value read
alert(matched) //if you want alert it
matched=false; //reset to default
} else {
SetTimeout("checking()",200);
}
}
[blue]
//an example of calling, like onload, otherwise click event of button would be the same
window.onload=function() {
testagainstXML("registerxmlgen.asp","clanname","Test1")
}[/blue]

//no need now
[red]//[/red]alert(testagainstXML("registerxmlgen.asp","clanname","Test1"))
[/tt]
The rest depends on your correct asp's response. The idea is about this. (Watch my typos or slips if any-just edit the script here.)
 
GuitarDave, don't confuse the two functions:
Code:
function testagainstXML(url,node,test) {
    /* ... */
    xmlhttp.onreadystatechange = doFoo(url,node,test);
    /* ... */
}

function doFoo(url,node,test) {
    /* ... */
}
The doFoo function - whether named or anonymous - is attached as an event handler: it should not be called using the variables url,node,test. These are meaningless when attached to an onreadystatechange event.

Your doFoo/anonymous function is what's doing the actual testing, therefore *this* is what should be returning a value. The testagainstXML function simply attaches the event listener and loads the XML. It's should not be returning the results of any testing, therefore "[tt]alert(testagainstXML(foo))[/tt]" is not appropriate.

Oh, your XML is malformed: the last closing tag should be </clans>, not </clan>.

I suspect you're also running into scope issues; your function variables won't be passed between the two functions. And did you intend 'matched' to be global? Because you're not calling doFoo directly (it's being called by an eventState change), you cannot supply the variables to call it with, so you need to pass them in another way (e.g. global variable).


Try this - it shows what's happening in various places:
Code:
function testagainstXML(url,node,test) {
    //document.getElementById("maps").innerHTML = "Loading...";
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.overrideMimeType("text/xml");
    }else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = doFoo;  
    [COLOR=green]/* [b]NOTE:[/b] there are [u]no[/u] brackets after doFoo here.  You're attaching a listener, NOT calling a function. */[/color]

    xmlhttp.open("GET",url,true);
    xmlhttp.setRequestHeader('content-type', 'text/xml');         
    xmlhttp.send(null);    
}



function doFoo() {
    [COLOR=green]/* [b]NOTE:[/b] no function variables.  The only sensible variable that can be used would be an event object. */[/color]
    var node="clanname";
    var test="Test1";
    var matched=false;
    
    if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
            var xmlDoc = xmlhttp.responseXML;
            var matched = false;
            for (n = 0; n < xmlDoc.getElementsByTagName(node).length; n++){                
                var xmlNodes = xmlDoc.getElementsByTagName(node)[n].firstChild.data;

                alert(xmlNodes);

                if (xmlNodes == test){
                    matched = true;
                    alert("It's matched");
                }
            }
        } else {
            alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
        }
    }
}


What's the code actually trying to achieve? (e.g. a user types a clan name into a box, and the script tests to see if it exists?) Do you have a link you can point us at?

---
Marcus
better questions get better answers - faq581-3339
accessible web design - zioncore.com
 
Amendment:

My line
[tt] matched=false; //reset to default[/tt]
should be read
[tt] [red]bavail[/red]=false; //reset to default[/tt]
as the data is already read and xmlhttp is stand-ready for the next query. matched as the returned data is updated only when bavail is at the same time true.
 
Getting there tsuji.
Still need to return a value from it.
I need on a form submit, that function to return true or false.
Must be missing somthing lol.
Manarth, i am not missing what you have said, i understand, but it still wont return a value. The doFoo wether attached to the main function or played as a seperate function still finishes after the main function returns it's value (asuming i put a return matched at the end of the main function)

I am trying to add this to the end of a error check set up i have, which is why i need to somehow see if it is true or false and if it is false it can go on to the next function in the set.

eg

if(testagainstXML){
document.getElementById('name').innerHTML = "Name in use"
}
next test
next test
next test


}...the bane of my life!
 
>Still need to return a value from it.

bavail, matched are already return values. You sure can device any other kind of return along the same construction, namely some other global variables and an indicator that the values so stored there are updated. You can control it even with bavail. There is nothing to hold it back from being other than boolean. It can be more sophisticated per-query message.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top