#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    44
    Rep Power
    2

    Dynamic Searchfield Issue (Ajax/Xml)


    Following an example from Lynda.com regarding dynamically populating searchfields. I believe the script I've written has broken down during the searchSuggest function. There are no errors in the console in Chrome dev tools and all of my files seem to have loaded properly, not sure what going on here.

    HTML
    Code:
    <html>
    	<head>
    		<title>Auto-fill States</title>
    		<link href="/ajax_sandbox/script.css" rel="stylesheet" type="text/css" />
    		<script src="/ajax_sandbox/states.js" type="text/javascript"></script>
    	</head>
    	<body>
    		<form action="#">
    			Please enter your state:<br />
    			<input type="text" id="searchField" autocomplete="off" /><br />
    			<div id="popups"></div>
    		</form>
    	</body>
    </html>
    CSS
    Code:
    body, 
    #searchField { font: 1.2em arial, helvetica, sans-serf; }
    
    #popups { position: absolute; }
    #searchField.error { background-color: #fc0; }
    
    div.suggestions {
    	background-color: #fff;
    	padding: 2px 6px;
    	border: 1px solid #000;
    }
    
    div.suggestions:hover { background-color: #69f; }
    AJAX
    Code:
    window.onload = initAll;
    
    var xhr = false;
    var statesArray = new Array();
    
    function initAll() {
    	document.getElementById("searchField").onkeyup = searchSuggest;
    	
    	if (window.XMLHttpRequest) {
    		xhr = new XMLHttpRequest();
    	}
    	else {
    		if (window.ActiveXObject) {
    			try {
    				xhr = new ActiveXObject("Microsoft.XMLHTTP");
    			}
    			catch (e) {}
    		}
    	}
    	
    	if (xhr) {
    		xhr.onreadystatechange = setStatesArray;
    		xhr.open("GET","usStates.xml", true);
    		xhr.send(null);
    	}
    	else {
    		alert("Sorry, but I couldn't create an XMLHttpRequest");
    	}
    }
    
    function setStatesArray() {
    
    	if (xhr.readyState == 4) {
    		if (xhr.status == 200) {
    			if (xhr.responseXML) {
    				var allStates = xhr.responseXML.getElementsByTagName("item");
    				for (var i=0; i<allStates.length; i++) {
    					statesArray[i] = 
    					allStates[i].getElementsByTagName("label")[0].firstChild;
    				}
    			}
    		}
    		else {
    			alert("There was a problem with the request " + xhr.status);
    		}				
    	}
    }
    
    function searchSuggest() {
    	var str = document.getElementById("searchField").value;
    	document.getElementById("searchField").className = "";
    	if (str != "") {
    		document.getElementById("popups").innerHTML = "";
    		
    		for (var i=0; i<statesArray.length; i++) {
    			var thisState = statesArray[i].nodeValue;
    			
    			if (thisState.toLowerCase().indexOf(str.toLowerCase()) == 0) {
    				var tempDiv = document.createElement("div");
    				tempDiv.innerHTML = thisState;
    				tempDiv.onclick = makeChoice;
    				tempDiv.className = "suggestions";
    				document.getElementById("popups").appendChild(tempDiv);
    			}
    		}
    		var foundCt = document.getElementById("popups").childNodes.length;
    		if (foundCt == 0) {
    			document.getElementById("searchField").className = "error";
    		}
    		if (foundCt == 1) {
    			document.getElementById("searchField").value = 
    			document.getElementById("popups").firstChild.innerHTML;
    			document.getElementById("popups").innerHTML = "";
    		}
    	}	
    }
    
    
    
    function makeChoice(evt) {
    	var thisDiv = (evt) ? evt.target : window.event.srcElement;
    	document.getElementById("searchField").value = thisDiv.innerHTML;
    	document.getElementById("popups").innerHTML = "";
    }
    XML
    Code:
    <?xml version="1.0"?>
    <choices xml: lang="EN">
    	<item>
    		<label>Alaska</label>
    		<value>AK</value>
    	</item>
    	<item>
    		<label>Alabama</label>
    		<value>AL</value>
    	</item>
    	<item>
    		<label>Arizona</label>
    		<value>AZ</value>
    	</item>
    	<item>
    		<label>Arkansas</label>
    		<value>AR</value>
    	</item>
    	<item>
    		<label>California</label>
    		<value>CA</value>
    	</item>
    	<item>
    		<label>Colorado</label>
    		<value>CO</value>
    	</item>
    	<item>
    		<label>Connecticut</label>
    		<value>CT</value>
    	</item>
    </choices>
  2. #2
  3. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,131
    Rep Power
    4304
    Welcome to DevShed Forums, solosheff, and thanks for participating in other threads already.

    Let me start from the beginning of how I debugged this. First of all, I added "console.log(xhr.responseText)" before "if (xhr.responseXML)", to be sure that the file was being retrieved properly. Secondly, I added "console.log(statesArray.length)" before the for-loop in "searchSuggest" to make sure that the array was populated -- it wasn't. Thirdly, I added "console.log(allStates.length)" before the for-loop in "setStatesArray", which also showed zero. Next, I set "allStates" to "xhr.responseXML.documentElement.childNodes" and added "console.log(allStates[i].nodeName); continue;" to the body of the loop (the continue statement is to prevent errors from being generated from the existing statement in the loop). That resulted in "2", "#text", "sourcetext", which is not at all what we expected. Then I set "allStates" to "xhr.responseXML.childNodes". That resulted in "2", "xml-stylesheet", "parseerror", which is quite revealing. Lastly, I opened up Firefox's Error Console and it showed that there was a space in the XML file where there shouldn't be, namely after the colon in the <choices> start tag.

    It seems that XML Parse Errors aren't shown in Google Chrome's Console. However, they are in Firefox's Error Console (the built-in one, not the one in Firebug). Also in Google Chrome when there's an XML parse error, it seems that the responseXML object is given no properties at all.
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    44
    Rep Power
    2
    Originally Posted by Kravvitz
    Welcome to DevShed Forums, solosheff, and thanks for participating in other threads already.
    thank you for the in depth response. I'll do my best to live by the "post one leave one" way. I haven't had time to fully go through your post just yet, but I'm sure the fix is in there. Thanks again.

IMN logo majestic logo threadwatch logo seochat tools logo