Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 1 of 1
  1. #1
    Regular Coder
    Join Date
    Jan 2005
    Posts
    113
    Thanks
    0
    Thanked 0 Times in 0 Posts

    onkeyup Form Submission

    I am writing a text auto-complete feature for an input type="text" form. It brings up the list of available options fine, and allows me to select one however the problem is is that I use the keyup event (addEventListener) and so when one presses enter to select an auto-complete item it goes and submits the form before my event handler has a chance to kick in. (In firefox this is, Konqueror it works fine).

    Firefox does not seem to care what I return, it will either bubble the event up the tree or it won't (and it always seems to do the opposite one to what I want).

    Does anyone have any ideas?

    EDIT: Here is the source code (still need to work on the mouse control and styles)
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    		  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
    	<head>
    		<title>News &amp; Comment :: Tring Campus Talks</title>
    		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    		<style type="text/css">
    			.selected
    			{
    				background: black;
    				color: white;
    			}
    		</style>
    		<script type="text/javascript">			
    			function AutocompleteBox (elementID)
    			{
    				/*
    				 * Responds to a blur event
    				 */
    				this.handleBlur = function (e)
    				{
    					if (this.autocomplete.optionsBox)
    						this.autocomplete.destroyOptionsBox();
    				}
    				
    				/*
    				 * Responds to a key-press event on a text field 
    				 */
    				this.handleKeypress = function (e)
    				{
    					// Find out what key was pressed
    					var keyPressed = this.autocomplete.getKey(e);
    
    					var bubble = true
    					
    					/*
    					 * If the autocomplete box is currently active and the key
    					 * pressed was a control key (up, down, enter) then we need
    					 * respond to it and then return (as it will not affect the
    					 * list of available options)
    					 */
    					if (this.autocomplete.optionsBox)
    					{
    						switch (keyPressed)
    						{
    							// Enter
    							case 13:
    								this.autocomplete.insertCurrentOption();
    								bubble = false;
    								break;
    							// Up arrow
    							case 38:
    								this.autocomplete.decrementSelectedOption();
    								bubble = false;
    								break;
    							// Down arrow
    							case 40:
    								this.autocomplete.incrementSelectedOption();
    								bubble = false;
    								break;
    							default:
    								break;
    						}
    					}
    					
    					// Update the autocomplete box (create/delete if necessary)
    					this.autocomplete.setText(this.value);
    					
    					return bubble;
    				}
    				
    				/*
    				 * Updates the autocompletion box, showing potential matches
    				 * for newText (deleting/creating the box as required)
    				 */
    				this.setText = function (newText)
    				{
    					// If newText is the same as currentText we can return
    					if (newText == this.currentText)
    						return;
    					
    					// Get the possible options for newText
    					this.currentText = newText;
    					var possibleOptions = this.getPossibleOptions(this.currentText);
    					
    					/*
    					 * If there are no options and the box is active then
    					 * destroy it
    					 */
    					if (this.optionsBox && !possibleOptions.length)
    					{
    						this.destroyOptionsBox();
    					}
    					/*
    					 * If no box exists and there are options
    					 */
    					else if (!this.optionsBox && possibleOptions.length)
    					{
    						this.createOptionsBox();
    						this.populateOptionsBox(possibleOptions);
    					}
    					/*
    					 * If there are some options populate the box with them
    					 */
    					else
    					{
    						this.populateOptionsBox(possibleOptions);
    					}
    				}
    				
    				/*
    				 * Creates the options box
    				 */
    				this.createOptionsBox = function ()
    				{
    					// Create the <ul>
    					var optionsBox = document.createElement("ul");
    					
    					// Set the class of it
    					optionsBox.className = "autocomplexBox";
    					
    					/*
    					 * Set the width and position of the box; this box needs to
    					 * be absolutely positioned so that it is just below the
    					 * input, has the same width as it and the same left offset
    					 */
    					optionsBox.style.position = "absolute";
    					optionsBox.style.width = this.inputElement.offsetWidth + "px";
    					optionsBox.style.top = (this.inputElement.offsetTop +
    						this.inputElement.offsetHeight) + "px";
    					optionsBox.style.left = this.inputElement.offsetLeft + "px";
    					
    					// Make the box a child of the input fields parent
    					this.inputElement.parentNode.appendChild(optionsBox);
    					
    					// Store a reference to optionsBox
    					this.optionsBox = optionsBox;
    				}
    				
    				/*
    				 * Removes the options box
    				 */
    				this.destroyOptionsBox = function ()
    				{
    					this.inputElement.parentNode.removeChild(this.optionsBox);
    					this.optionsBox = null;
    				}
    				
    				/*
    				 * Populates the options box (fills it with a list of available
    				 * autocomplete options)
    				 */
    				this.populateOptionsBox = function (possibleOptions)
    				{
    					// Remove all of the child nodes from the box
    					while (this.optionsBox.childNodes.length)
    						this.optionsBox.removeChild(this.optionsBox.childNodes[0]);
    					
    					// Loop through the options adding them to the box
    					for (var i = 0; i < possibleOptions.length; i++)
    					{
    						// Create an <li>
    						var option = document.createElement("li");
    						
    						// Create the text node with the option itself
    						var optionText = document.createTextNode(possibleOptions[i]);
    						
    						// Add the text node to option
    						option.appendChild(optionText);
    						
    						// Add the option to the box
    						this.optionsBox.appendChild(option);
    					}
    					
    					// Save the currently available options
    					this.currentOptions = possibleOptions;
    					
    					// Set the currently selected option to -1 (no selection)
    					this.currentOption = -1;
    					
    					// Make the first item selected (by default)
    					this.setSelectedOption(0);
    				}
    				
    				/*
    				 * Sets the currently selected option in the autocomplete box
    				 * to be the option at index optionIndex in the
    				 * this.currentOptions array
    				 */
    				this.setSelectedOption = function (optionIndex)
    				{
    					// Deselect the currently selected option (if any)
    					if (this.currentOption != -1)
    						this.optionsBox.childNodes[this.currentOption].className = "";
    					
    					// Set the class of the option to be selected
    					this.optionsBox.childNodes[optionIndex].className = "selected";
    					
    					// Select the option
    					this.currentOption = optionIndex;
    				}
    				
    				/*
    				 * Increments the selected option by 1 (so moves selection
    				 * `cursor' down by one)
    				 */
    				this.incrementSelectedOption = function ()
    				{
    					/*
    					 * So long as there is an option after the current one,
    					 * select it
    					 */
    					if (this.currentOption + 1 <= this.currentOptions.length - 1)
    						this.setSelectedOption(this.currentOption + 1);
    				}
    				
    				/*
    				 * Decrements the selected option by 1
    				 */
    				this.decrementSelectedOption = function ()
    				{
    					/*
    					 * So long as decreasing the current option does not result
    					 * in a negative number then select the option above it
    					 */
    					if ((this.currentOption - 1) >= 0)
    						this.setSelectedOption(this.currentOption - 1);
    				}
    				
    				/*
    				 * Sets the value of the input field to be that of the
    				 * currently selected option
    				 */
    				this.insertCurrentOption = function ()
    				{
    					/*
    					 * So long as an option is selected, insert it and then
    					 * destroy the options box
    					 */
    					 if (this.currentOption != -1)
    					 {
    						this.inputElement.value = this.currentText =  this.currentOptions[this.currentOption];
    						this.destroyOptionsBox();
    					 }
    				}
    				
    				/*
    				 * Extracts and returns the events key-code
    				 */
    				this.getKey = function (e)
    				{
    					return e.keyCode;
    				}
    				
    				this.getPossibleOptions = function (text)
    				{
    					return new Array("Hello", "Help", "Hola");
    				}
    				
    				/*
    				 * Constructor code
    				 */
    				this.inputElement = document.getElementById(elementID);
    				this.currentText = this.inputElement.value;
    				
    				// Install the event handler
    				this.inputElement.addEventListener("keyup", this.handleKeypress, false);
    				this.inputElement.addEventListener("blur", this.handleBlur, false);
    				this.inputElement.autocomplete = this;
    			}
    			onload = function ()
    			{
    				new AutocompleteBox('textInput');
    			}
    		</script>
    	</head>
    	<body>
    		<form method="get" action="index.html">
    			<p>
    				<input id="textInput" name="name" type="text" />
    			</p>
    		</form>
      </body>
    </html>
    Last edited by evilguru; 02-25-2007 at 12:58 AM.


 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •