Onkeypress changes className but changes back

Hello everyone,

I am working on a AJAX autocomplete script and the autocomplete is working, but I would like to add some more functionality to by adding navigation through the list with the UP and DOWN arrow keys. I seem to have the javascript working where when I press down one of the arrow keys it seems to change the className, but it immediately will change the className back to the original className. Would anybody be able to tell me why this is happening? What am I doing wrong?


document.onkeypress = KeyCheck;

 var HighlightSelection = -1;
	function KeyCheck(e){
		   var KeyID = (window.event) ? event.keyCode : e.keyCode;
 
		switch(KeyID){
 
			case 38:
		    HighlightSelection--;
			setHighlightSelection(HighlightSelection);	
		    break;
			
			case 40:
			HighlightSelection++;
			setHighlightSelection(HighlightSelection);
			break;
 
		}
	}
	
function setHighlightSelection(num){
	document.getElementById(num).className = "suggest_link_over";
}

I know that the function “setHighlightSelection” is very basic, but it’s being used for testing purposes.

Thank you in advance.
milamsteve

Whatever is changing class name back is not in code you posted.

CyberAlien,
Here is all of the code for the autocomplete script.


var HighlightSelection = -1;

//Our XmlHttpRequest object to get the auto suggest
var searchReq = getXmlHttpRequestObject();

//Called from keyup on the search textbox.
//Starts the AJAX request.
function searchSuggest() {
	if (searchReq.readyState == 4 || searchReq.readyState == 0) {
		var str = escape(document.getElementById('txtSearch').value);
		searchReq.open("GET", 'autoComplete/searchSuggest.php?search=' + str, true);
		searchReq.onreadystatechange = handleSearchSuggest; 
		searchReq.send(null);
	}		
}

//Called when the AJAX response is returned.
function handleSearchSuggest() {
	
	if (searchReq.readyState == 4) {
		var ss = document.getElementById('search_suggest')
		
		ss.style.display = "block";
		ss.innerHTML = '';
		
		var str = searchReq.responseText.split("\
");
		for(i=0; i < str.length - 1; i++) {
			
			var suggest = '<div id=' + i + ' onmouseover="javascript:suggestOver(this);" ';
			suggest += 'onmouseout="javascript:suggestOut(this);" ';
			suggest += 'onclick="javascript:setSearch(\\'' + SetInnerHTMLId(str[i]) + '\\');" ';
			suggest += 'class="suggest_link">' + SplitStringforDisplay(str[i]) + '</div>';
			ss.innerHTML += suggest;
			document.onkeypress = KeyCheck;
			
		}
	}
}

// Set the ID for the setSearch function to input the just the customer Id into the textbox.
function SetInnerHTMLId(GetId){
	var SetId = GetId.split("--");
	return SetId[0];
}

// Spit the string form handleSearchSuggest() to display in the dropdown
function SplitStringforDisplay(HandleString){
	var splitStr = HandleString.split("--");
	
	for(x = 0; x < splitStr.length -1; x++){
		var StrSplits = '<div style="float: left; min-width: 50px; margin-right: 10px;">' + splitStr[0] + '</div>';
			StrSplits += '<div style="float: left;">' + splitStr[1];
			StrSplits += '<p class="suggest-address">' + splitStr[2] + '</p></div>';
			StrSplits += '<div style="clear: both;"></div>';
	}
	return StrSplits;
}

//Mouse over function
function suggestOver(div_value) {
	div_value.className = 'suggest_link_over';
}
//Mouse out function
function suggestOut(div_value) {
	div_value.className = 'suggest_link';
}
//Click function
function setSearch(value) {
	var splitValue = value.split("--");
	
	document.getElementById('txtSearch').value = value;
	
	document.getElementById('search_suggest').innerHTML = '';
	document.getElementById('search_suggest').style.display = "none";
}

	function KeyCheck(e){
		   var KeyID = (window.event) ? event.keyCode : e.keyCode;
 
		switch(KeyID){
			case 13: // Enter Key
			//
			break;
			
			case 27: // Escape Key
			setSearch('');
			break;
			
			case 38: // Up Arrow Key
		    HighlightSelection--;
			setHighlightSelection(HighlightSelection);
		    break;
			
			case 40: // Down Arrow Key
			HighlightSelection++;
			setHighlightSelection(HighlightSelection);
			break;
			 
		}

	}
	
function setHighlightSelection(num){
	return document.getElementById(num).className = "suggest_link_over";
}

I hope this helps shed some light on this, because I can’t figure it out was I’m doing wrong.
Thank you in advance
milamsteve

I notice you have document.onkeypress = = KeyCheck; in side a loop.

What browser are you using?

I believe I have seen issues with onkeypress no handling the arrow keys and keydown being preferred.

Hi PhilipToop,
You are correct about document.onkeypress = KeyCheck; being inside a loop. I was trying to see if that was the problem on why the class was changing back. I have also tried putting document.onkeypress = = KeyCheck; outside of the loop and I get the same results.

I am testing this script in FF 3.5.

Thanks for letting me know about the onkeypress issue. I have tried the keydown, but I still get the same results. I will however make that change though.

milamsteve

Difficult to get much further without a fuller picture. Is it possible to post a URL to the page in question?

Can’t see anything in the script that would indicate the behaviour you are describing which would leave me to suspect something outside of that code.

In the test code I put together, admittedly on FF 3.6.17, when in a text box the up and down arrow did not seem to fire the keypress event! The left and right arrow did, as did the del, insert and home, but not the page up, page down.

Sorry, I can’t post a URL page because this is on a testing server and our production server isn’t set up to run these files. Below is the HTML, PHP and Javascript that is associated with the autocomplete.

Here is the simple HTML Page


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title>AutoComplete Test</title>
<style type="text/css" media="screen">
    .suggest_link, .suggest_link_over{
        font: 11px arial;
		border-bottom: 1px solid #333333;
    }
	.suggest_link {
		background-color: #FFFFFF;
		padding: 2px 6px 2px 6px;
		
	}
	.suggest_link_over {
		background-color: #344052;
		padding: 2px 6px 2px 6px;
		color: #FFFFFF;
	}
	#search_suggest {
		display: none;
		position: absolute;
		/*left: 231px;*/
		left: 126px;
		top: 20px;
		background-color: #FFFFFF;
		text-align: left;
		border: 1px solid #000000;
	}
	.suggest-address{
		font-size: 8pt; 
		color: #C0C0C0; 
		text-align: left;
		margin:0;
		padding: 0;
	}
</style>

</head>
   		
<body>
<form method="post" action="pendcheck.php" autocomplete="off">
<p style="text-align: center;">
<input class="formfield" type="text" name="fcustomer_id" size="20" id="txtSearch" onkeyup="searchSuggest();" tabindex="1" autocomplete="off" />
</p>
<!-- AutoComplete DIV box -->
<div id="search_suggest"></div>
</form>
</body>
</html>

Here is the PHP page


<?php
// Database connection goes here

///Make sure that a value was sent.
if (isset($_GET['search']) && $_GET['search'] != '') {
	//Add slashes to any quotes to avoid SQL problems.
	$search = addslashes($_GET['search']);
	//Get every page title for the site.
	$suggest_query = mysql_query("SELECT customer_id, cusbillname, shipadd1 FROM customer WHERE customer.cusbillname like('" .
		$search . "%') OR customer.customer_id LIKE('" . $search . "%') ORDER BY customer.customer_id LIMIT 10");

	while($suggest = mysql_fetch_array($suggest_query)) {
		//Return each page title seperated by a newline.
		echo $suggest['customer_id'] . "--" . $suggest['cusbillname'] . "--" . $suggest['shipadd1'] . "\
";
	}
}
?>

And Here is the JavaScript Code


	var HighlightSelection = -1;
	
	document.onkeydown = KeyCheck;
	
//Gets the browser specific XmlHttpRequest Object
function getXmlHttpRequestObject() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	} else if(window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	} else {
		alert("Your Browser Sucks!\
It's about time to upgrade don't you think?");
	}
}

//Our XmlHttpRequest object to get the auto suggest
var searchReq = getXmlHttpRequestObject();

//Called from keyup on the search textbox.
//Starts the AJAX request.
function searchSuggest() {
	
	if (searchReq.readyState == 4 || searchReq.readyState == 0) {
		var str = escape(document.getElementById('txtSearch').value);
		searchReq.open("GET", 'autoComplete/searchSuggest.php?search=' + str, true);
		searchReq.onreadystatechange = handleSearchSuggest; 
		searchReq.send(null);
	}		
}

//Called when the AJAX response is returned.
function handleSearchSuggest() {
	
	if (searchReq.readyState == 4) {
	//document.getElementById('search_suggest').style.display = "block";
		var ss = document.getElementById('search_suggest')
		
		ss.style.display = "block";
		ss.innerHTML = '';
		
		var str = searchReq.responseText.split("\
");
		for(i=0; i < str.length - 1; i++) {
			//Build our element string.  This is cleaner using the DOM, but
			//IE doesn't support dynamically added attributes.
			
			var suggest = '<div id=' + i + ' onmouseover="javascript:suggestOver(this);" ';
			suggest += 'onmouseout="javascript:suggestOut(this);" ';
			suggest += 'onclick="javascript:setSearch(\\'' + SetInnerHTMLId(str[i]) + '\\');" ';
			suggest += 'class="suggest_link">' + SplitStringforDisplay(str[i]) + '</div>';
			ss.innerHTML += suggest;
			
			
		}
	}
}

// Set the ID for the setSearch function to input the just the customer Id into the textbox.
function SetInnerHTMLId(GetId){
	var SetId = GetId.split("--");
	return SetId[0];
}

// Spit the string form handleSearchSuggest() to display in the dropdown
function SplitStringforDisplay(HandleString){
	var splitStr = HandleString.split("--");
	
	for(x = 0; x < splitStr.length -1; x++){
		var StrSplits = '<div style="float: left; min-width: 50px; margin-right: 10px;">' + splitStr[0] + '</div>';
			StrSplits += '<div style="float: left;">' + splitStr[1];
			StrSplits += '<p class="suggest-address">' + splitStr[2] + '</p></div>';
			StrSplits += '<div style="clear: both;"></div>';
	}
	return StrSplits;
}

//Mouse over function
function suggestOver(div_value) {
	div_value.className = 'suggest_link_over';
}
//Mouse out function
function suggestOut(div_value) {
	div_value.className = 'suggest_link';
}
//Click function
function setSearch(value) {
	var splitValue = value.split("--");
	
	document.getElementById('txtSearch').value = value;
	
	document.getElementById('search_suggest').innerHTML = '';
	document.getElementById('search_suggest').style.display = "none";
}

	function KeyCheck(e){
		   var KeyID = (window.event) ? event.keyCode : e.keyCode;
 
		switch(KeyID){
			case 13: // Enter Key
			//setSearch(this.value);
			break;
			
			case 27: // Escape Key
			setSearch('');
			HighlightSelection = -1;
			break;
			
			case 38: // Up Arrow Key
		    HighlightSelection--;
			setHighlightSelection(HighlightSelection);
		    break;
			
			case 40: // Down Arrow Key
			HighlightSelection++;
			setHighlightSelection(HighlightSelection);
			break;
			 
		}

	}
	
function setHighlightSelection(num){
	document.getElementById(num).className = "suggest_link_over";
}

Does this help?
Thanks again in advance.
milamsteve

onkeyup="searchSuggest();

will get fired for the arrow keys as well.

PhilipToop,

Sorry for the delay. It was a Holiday weekend. Thanks for pointing that out to me. After noticing that, I figured out how to handle the onkeyup issue. I think the way the code was written, it was calling “searchReq.onreadystatechange = handleSearchSuggest;” again at the very end of execution. I was able to solve it by writing a conditional statement. That seems to work.

Thanks again for all of your help.
milamsteve:D