Dear All,
I am currently working on an assignment. And I wanted to implement a bit ajax in it.
I've got my html page, and on an onclick event the ajax code is going to populate a table and place it in my html page. The php file is working correctly but there's a problem with the java-script codes.

Can anyone of you please figure out what the error is.

var xmlhttp;

function showUserName(){
		
	var fname= document.getElementById("search_fname");//alert("fname is " + fname);
	var lname= document.getElementById('search_lname');//alert("lname is "+ lname);
	if(window.XMLHttpRequest){
		//code for ie7+,firefox,chrome,opera,safari
		xmlhttp=new XMLHttpRequest();
	}
	else{
		//code for ie6,5
		xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}
	if(xmlhttp==null){
		alert("cannot create XMLHTTP instance");
		return false;
	}
	
	var url="searchUser.php";
	url=url+"?search_fname="+fname+"&search_lname="+lname;
	
	xmlhttp.onreadystatechange=theResponse;
	
	xmlhttp.open("GET",url,true);
	xmlhttp.send();
}

function theResponse(){
		if(xmlhttp.readyState==4){
	
		if(xmlhttp.status==200){
			var tableName="<table><tr><th>First Name</th><th>Last Name</th><th>Email</th></tr>"; 
			var xmlDoc=xmlhttp.responseXML.documentElement;//refers to root position of the xml <Nom>

			var NomNo=xmlDoc.childNodes.length;
				for(var i=0;i<NomNo;i++){
				var namenode=xmlDoc.childNodes[i];//refers to Nom/Name
				tableName=tableName+"<tr>";
				
				var nameNo=namenode.childNodes.length;//refers to no of element under Name
				
				for(var j=0;j<nameNo;j++){
					var Nam=namenode.childNodes[j];//1st object
					var sibl=Nam.childNodes[0];//its value
					if(sibl!=null){
						tableName=tableName+"<td>"+sibl.nodeValue+"</td>";
					}
					else{
						tableName=tableName+"<td>&nbsp</td>";
					}
					tableName=tableName+"</tr>";
				}
				tableName=tableName+"</table>";
				document.getElementById("div_searchname").innerHTML=innerHTML+tableName;
			}
		}
	}
		else{
			alert("there was a problem with the request");
		}
		
}
The php file 
<?php
	$fname="a";//$_GET('search_fname');echo $fname;
	$lname="a";//$_GET('search_lname');
	
include("dbConnect.php");
	mysql_select_db("idareyou",$con);
	//echo "<br/>line just after include dbconnect";	
	//echo $fname;
	
	//$sql="SELECT fname,lname,email FROM user WHERE fname=$fname AND lname=$lname";
	$result=mysql_query("SELECT fname,lname,email FROM user WHERE fname='$fname' AND lname='$lname' ");
	//$result=mysql_query( "SELECT fname,lname,email FROM user WHERE".'"'.fname.'"'.=.'"'.$fname.'"'.

	$numRows=mysql_num_rows($result);//echo $numRows;
	if($numRows<1){
		mysql_close($con);
		echo "No result found";
	}
	 header('Content-Type: text/xml');
 $xml_name = '<?xml version="1.0" encoding="ISO-8859-1"?>';
 $xml_name = $xml_name."<Nom>" ;

	while($rows=mysql_fetch_array($result) ){
		$xml_name=$xml_name."<Name>";
		$xml_name=$xml_name."<fname>".$rows["fname"]."</fname>";
		$xml_name=$xml_name."<lname>".$rows["lname"]."</lname>";
		$xml_name=$xml_name."<email>".$rows['email']."</email>";
		$xml_name=$xml_name."</Name>";
	}
	$xml_name=$xml_name."</Nom>";
	echo $xml_name;
	
	mysql_close($con);
?>

Avi,

I've not checked the PHP or the XML handling logic, but I have had a hack at the overall javascript structure for you.

function getXmlHttpObject() {//By having this as a separate function, it becomes reusable for any other ajax you might have (one day) on the same page.
	if (window.XMLHttpRequest){
		return new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
	}
	if (window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP"); // code for IE6, IE5
	}
	return null;
}

function showUserName() {
	var fname = document.getElementById("search_fname");//alert("fname is " + fname);
	var lname = document.getElementById("search_lname");//alert("lname is "+ lname);
	var xmlhttp = getXmlHttpObject();//No need for global variable
	if(xmlhttp==null) {
		alert("Cannot create XMLHTTP instance");
		return false;
	}
	var url = "searchUser.php?search_fname=" + fname + "&search_lname=" + lname;
	xmlhttp.onreadystatechange = function() { //With lengthy response handlers. it's often better to leave the .readystate and .staus tests behind and just separate out the actual response handler as a separate function.
		if(xmlhttp.readyState==4) {
			if(xmlhttp.status==200) {
				theResponse(xmlhttp.responseXML.documentElement);//refers to root position of the xml <Nom>
			}
			else { alert("There was a problem with the request"); }//moved one line higher, ie. if(xmlhttp.status!=200)
		}
	};
	xmlhttp.open("GET", url, true);
	xmlhttp.send(null);
}

function theResponse(xmlDoc) {
	var htmlArray = [];//An array in which to accumulate HTML fragments in lieu of String += "....", which is horribly inefficient.
	htmlArray.push("<table><tr><th>First Name</th><th>Last Name</th><th>Email</th></tr>");
	var NomNo = xmlDoc.childNodes.length;
	for(var i=0; i<NomNo; i++) {
		var namenode = xmlDoc.childNodes[i];//refers to Nom/Name
		htmlArray.push("<tr>");
		var nameNo = namenode.childNodes.length;//refers to no of element under Name
		for(var j=0; j<nameNo; j++){
			var Nam = namenode.childNodes[j];//1st object
			var sibl = Nam.childNodes[0];//its value
			if(sibl != null){ htmlArray.push("<td>" + sibl.nodeValue + "</td>"); }
			else{ htmlArray.push("<td>&nbsp</td>"); }
			htmlArray.push("</tr>");
		}
		htmlArray.push("</table>");
		document.getElementById("div_searchname").innerHTML = htmlArray.join('');//removed "innerHTML+", and here we use Array.join to put the HTML fragments together
	}
}

Most of this is just your code refactored but there were a coulple of things wrong (I think) - see comments in code.

Airshow

Oh yes, looking at theResponse() again, the "</tr>", "</table>" amd ".innerHTML = ..." statements are all too deeply nested, which would create unbalanced HTML.

Try this:

function theResponse(xmlDoc) {
	var htmlArray = [];//An array in which to accumulate HTML fragments in lieu of String += "....", which is horribly inefficient.
	htmlArray.push("<table><tr><th>First Name</th><th>Last Name</th><th>Email</th></tr>");
	var NomNo = xmlDoc.childNodes.length;
	for(var i=0; i<NomNo; i++) {
		var namenode = xmlDoc.childNodes[i];//refers to Nom/Name
		htmlArray.push("<tr>");
		var nameNo = namenode.childNodes.length;//refers to no of element under Name
		for(var j=0; j<nameNo; j++){
			var Nam = namenode.childNodes[j];//1st object
			var sibl = Nam.childNodes[0];//its value
			if(sibl != null){ htmlArray.push("<td>" + sibl.nodeValue + "</td>"); }
			else{ htmlArray.push("<td>&nbsp</td>"); }
		}
		htmlArray.push("</tr>");
	}
	htmlArray.push("</table>");
	document.getElementById("div_searchname").innerHTML = htmlArray.join('');//removed "innerHTML+", and here we use Array.join to put the HTML fragments together
}

Airshow

The JavaScript codes are awesome. Thanks, you have broaden my horizons in the JS world.

But still I am getting the error "There was a problem with the request".
How can it be possible, should I check something else?

NO.... I think the problem is with the php file.

Thanks again.

The php file is fine now but the ajax is still not working properly.
It continues to give me the error saying there was an error with the request,
please show me where the error is.

Avi,

Modify the alert to see the HTTP response code :

else { alert("There was a problem with the request : " + xmlhttp.status); }

Then look it up here. This will give you a clue as to what needs fixing.

Airshow

I am getting a status of 0. what should i do next?

Avi,

I have only ever seen staus 0 when serving a file directly from the local (Windows) file system rather than from a proper web server (Apache, IIS etc).

You can always liberalise the status test :

if(xmlhttp.status==200 || xmlhttp.status==0) {

but only for development purposes. You should really ensure that proper HTTP headers are applied by serving from a HTTP server and/or getting its settings correct.

How do you currently serve your pages?

Airshow

uhh... I am working directly from local host,everything is local and I am using xammpp also.

I'm not sure how things work under xampp.

You will have to do some background reading.

Try the xampp documentation first.

Airshow

Some websites are saying that the problem might come from a
security issue in browsers.

Thanks again for all your time.
You have helped me a lot.

I've just googled - there's loads of discussion of urls under xampp!!

You could try requesting the page with an absolute url of the form http://localhost/......./search.php?... The exact composition will depend on how xampp is set up and where in the directory structure you serve the site from, but you probably know that already.

This shouldn't be necessary if your master page (from which the ajax request is made) was requested with an absolute url, but give is a try anyway.

Airshow

I somehow managed to debug it a bit.

Now it is sending and receiving the response. I was running in Firefox, I've alerted the xmlhttp.status and it was 0.Then I moved to Internet Explorer. There it told me 3times that the status was 0 and then on the 4th time the status was 200 and the div got the table displayed in it but for only about 4 seconds.
The htlmArray is working and do contain the data fed in it.
Can you all help me with it.

var xmlhttp;
function showUserName(){
 xmlhttp = false;
      /* For Firefox*/    
      if (window.XMLHttpRequest) { 
         xmlhttp = new XMLHttpRequest();
      } else /*For IE*/
         if (window.ActiveXObject) { 
            try {
                /*For some versions of IE*/
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                  /*For some other versions of IE*/
                  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
         }
      }
      if (!xmlhttp) {
         alert('Cannot create XMLHTTP instance');
         return false;
     }
    var fname = document.forms[0].elements["search_fname"].value;
    var lname = document.forms[0].elements["search_lname"].value;
    var url = "searchUser.php?search_fname=" + fname + "&search_lname=" + lname;
    //alert(fname+" "+lname+" "+url);
    xmlhttp.open('GET', url, true);
    xmlhttp.onreadystatechange = theResponse;
    xmlhttp.send(null);
    }
    //End showUserName
function theResponse(){
      alert("entering the function theResponse,readystate= "+xmlhttp.readyState+"status="+xmlhttp.status);
    if(xmlhttp.readyState==4) {
        if(xmlhttp.status==200) {
            var xmlDoc=xmlhttp.responseXML.documentElement;
            var htmlArray=[];//An array in which to accumulate HTML fragments in lieu of String += "....".
            htmlArray.push("<table><tr><th>First Name</th><th>Last Name</th><th>Email</th></tr>");
            var NomNo=xmlDoc.childNodes.length;

            for(var i=0; i<NomNo; i++) {
                var namenode = xmlDoc.childNodes[i];//refers to Nom/Name
                htmlArray.push("<tr>");
                var nameNo = namenode.childNodes.length;//refers to no of element under Name
                for(var j=0; j<nameNo; j++){
                    var Nam = namenode.childNodes[j];//1st object
                    var sibl = Nam.childNodes[0];//its value
                    if(sibl != null){ htmlArray.push("<td>" + sibl.nodeValue + "</td>"); }
                    else{ htmlArray.push("<td>&nbsp</td>"); }
                }
                htmlArray.push("</tr>");
            }
        htmlArray.push("</table>");
            alert("htmlarray = "+htmlArray.join(''));
            document.getElementById("div_searchname").innerHTML = htmlArray.join('');
        }
        else{
            alert('There was a problem with the request.'+xmlhttp.status);
        }
    //removed "innerHTML+", and here we use Array.join to put the HTML fragments together
    }
    else{
            alert('There was a problem with the request.'+xmlhttp.status);
    }   
}//END OF FUNCTION THERESPONSE

Now the codes been improved a bit.
But the table is appearing for only 3 seconds and the page goes blank again.
Can anyone fix it please.

Avi,

No time now ... but it would appear that two things are happening; ajax HTTP request AND a regular browser HTTP request (unsuppressed form submission?).

Airshow

You should delete the outer else { alert('There was a problem ...') } block. This is incorrect because it's an else against if(xmlhttp.readyState==4) and several readyStates other than 4 will always occur, due to perfectly normal HTTP "handshaking". The inner else { alert('There was a problem ...') } is fine.

That said, javascript shouldn't cause the page blanking you describe. It is most likely to do with how showUserName is called. Can you post the relevant HTML please.

Airshow

Now in the javascript code am getting the responseXML as being null.

here the html codes:
<html>
<head>
<script type="text/javascript" src="searchUser_ajax.js"></script>


</head>
<body>
<form action="" onsubmit="showUserName();">
Enter the first name of the person:
<input type="text" name="search_fname" id="search_fname"/><br/>
<br/>
Enter the last name of the person:
<input type="text" name="search_lname" id="search_lname"/><br/><br/>

<input type="submit" value="submit" />
</form>
<br/>
<div id="div_searchname">
</div>
</body>
</html>

Aha, just what I expected. To suppress regular form submission, the onsubmit handler must return false .

<form action="" onsubmit="showUserName(); return false;">

Without return false , showUserName is called, then the form is submitted - which can be the right thing to do (notably after successful form data validation) but not in this case.

Airshow

I've edited it as you told me and also in the php file I've included this
header('Content-Type: text/xml; charset=utf-8');

Now it's working perfectly!!!!

Thanks a lot.

Brilliant :cool:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.