www.webdeveloper.com
Results 1 to 15 of 22

Thread: Simple auto-complete function

Threaded View

  1. #1
    Join Date
    Aug 2006
    Posts
    2

    Smile Simple auto-complete function

    For everybody who wants a way to create an auto-complete or auto-suggest text box in JavaScript, without use of prototype handlers and other advanced things, here is a sample that works perfectly.

    It gives you an auto-complete like Outlook Express does an auto-complete when you type e-mail address that belongs to Address Book...

    Let's create an sample of a text box that completes e-mail addresses, when you type them.

    First of all, you need to create an array with all values used to auto-complete, in this case, three e-mail addresses, but you can add how many addresses (elements) you need.

    After add all elements, use sort() method to order your array.

    Code:
    var aMail = new Array("albert@mail.com","beth@mail.com","harry@mail.com");
    aMail.sort();
    Now you need to use a standard handler (onKeyUp) of textbox to call the auto-complete function:

    Code:
    <input type="text" name="anyName" onKeyUp="Complete(this, event)">
    Note we call the function "Complete" (showed below) with two arguments. The first is the keyword "this" to pass the textbox object to function, so we don't need to manipulate names or IDs of textboxes and we can work with multiple textboxes on a page). The second parameter is the keyword "event" to pass the properties of onKeyUp event, so we can handle which key was pressed on the keyboard.

    Finally we have the function. As you guess, the name of the function is Complete and here is its code:

    Code:
    function Complete(obj, evt) {
    	if ((!obj) || (!evt) || (aMail.length == 0)) {
    		return;
    	}
    
    	if (obj.value.length == 0) {
    		return;
    	}
    
    	var elm = (obj.setSelectionRange) ? evt.which : evt.keyCode;
    
    	if ((elm < 32) || (elm >= 33 && elm <= 46) || (elm >= 112 && elm <= 123)) {
    		return;
    	}
    
    	var txt = obj.value.replace(/;/gi, ",");
    	elm = txt.split(",");
    	txt = elm.pop();
    	txt = txt.replace(/^\s*/, "");
    
    	if (txt.length == 0) {
    		return;
    	}
    
    	if (obj.createTextRange) {
    		var rng = document.selection.createRange();
    		if (rng.parentElement() == obj) {
    			elm = rng.text;
    			var ini = obj.value.lastIndexOf(elm);
    		}
    	} else if (obj.setSelectionRange) {
    		var ini = obj.selectionStart;
    	}
    
    	for (var i = 0; i < aMail.length; i++) {
    		elm = aMail[i].toString();
    
    		if (elm.toLowerCase().indexOf(txt.toLowerCase()) == 0) {
    			obj.value += elm.substring(txt.length, elm.length);
    			break;
    		}
    	}
    
    	if (obj.createTextRange) {
    		rng = obj.createTextRange();
    		rng.moveStart("character", ini);
    		rng.moveEnd("character", obj.value.length);
    		rng.select();
    	} else if (obj.setSelectionRange) {
    		obj.setSelectionRange(ini, obj.value.length);
    	}
    }
    Done! Everything is finished.

    When you type a text that that begins with letter "a", the rest of mail address "lbert@mail.com" will be completed in textbox.

    So let's look the function.

    The first thing we do is ensure that function have all necessary objects to work.

    The "obj" variable receives the "this" parameter = textbox object.
    The "evt" variable receives the "event" parameter = onKeyUp event properties.
    The "aMail" variable is the array created with elements to auto-suggest.

    If one of these variables is missing we quit the function.

    Code:
    if ((!obj) || (!evt) || (aMail.length == 0)) {
    	return;
    }
    Now, we need to check if textbox have something typed. If not there's nothing to complete, so quit function

    Code:
    if (obj.value.length == 0) {
    	return;
    }
    Now we need to know which key was typed in textbox. This can be done reading the properties of event. In the case of MSIE this property is named "KeyCode" and in the case of Mozilla this property is named "which".

    With the code below, we set the "elm" variable with the right value of the key in accordance with the browser.

    Code:
    var elm = (obj.setSelectionRange) ? evt.which : evt.keyCode;
    We need to evaluate the key code aborting the function in the case of non-text keys pressed (arrows, delete, backspace, etc.).

    Code:
    if ((elm < 32) || (elm >= 33 && elm <= 46) || (elm >= 112 && elm <= 123)) {
    	return;
    }
    By now, we separate all text wrote at textbox, to get the last address of e-mail typed.

    In this case we can separate e-mail addresses by coma (,) or semicolons (.

    Note this code is optional, since we are creating an textbox for mail addresses. This code is to ensure that we always are working with te last address typed in textbox.

    Code:
    // change all semicolons (;) by comas (,)
    var txt = obj.value.replace(/;/gi, ",");
    
    // create an array spliting text by comas
    elm = txt.split(",");
    
    // get the last element of array
    txt = elm.pop();
    
    // remove any spaces of the beginning of the text
    txt = txt.replace(/^\s*/, "");
    
    // ensure the text is greater of zero after removing spaces
    if (txt.length == 0) {
    	return;
    }
    And now, we have to retrive the initial position of the selection in textbox

    This can be done by different ways in MSIE and Mozilla, so we have to detect browser and get the information in accordance with it.

    Code:
    if (obj.createTextRange) {
    	// MSIE
    	var rng = document.selection.createRange();
    	if (rng.parentElement() == obj) {
    		elm = rng.text;
    		var ini = obj.value.lastIndexOf(elm);
    	}
    } else if (obj.setSelectionRange) {
    	// Mozilla
    	var ini = obj.selectionStart;
    }
    After this, we search the array using a for loop, searching the text typed in textbox. In the case of match, we break the loop.

    If a text is found it is appended to the end of text in textbox.

    Code:
    for (var i = 0; i < aMail.length; i++) {
    	elm = aMail[i].toString();
    
    	if (elm.toLowerCase().indexOf(txt.toLowerCase()) == 0) {
    		obj.value += elm.substring(txt.length, elm.length);
    		break;
    	}
    }
    Now, we add a selection to the text appended. This is done by different ways in the case of Mozilla or MSIE:

    Code:
    if (obj.createTextRange) {
    	rng = obj.createTextRange();
    	rng.moveStart("character", ini);
    	rng.moveEnd("character", obj.value.length);
    	rng.select();
    } else if (obj.setSelectionRange) {
    	obj.setSelectionRange(ini, obj.value.length);
    }
    That's all.

    Below is a complete sample of a page with this function and a textbox.

    Code:
    <html>
    <head>
    <title>Test</title>
    
    <script language="javascript" type="text/javascript">
    <!--
    
    var aMail = new Array("albert@mail.com","beth@mail.com","harry@mail.com");
    aMail.sort();
    
    function Complete(obj, evt) {
    	if ((!obj) || (!evt) || (aMail.length == 0)) {
    		return;
    	}
    
    	if (obj.value.length == 0) {
    		return;
    	}
    
    	var elm = (obj.setSelectionRange) ? evt.which : evt.keyCode;
    
    	if ((elm < 32) || (elm >= 33 && elm <= 46) || (elm >= 112 && elm <= 123)) {
    		return;
    	}
    
    	var txt = obj.value.replace(/;/gi, ",");
    	elm = txt.split(",");
    	txt = elm.pop();
    	txt = txt.replace(/^\s*/, "");
    
    	if (txt.length == 0) {
    		return;
    	}
    
    	if (obj.createTextRange) {
    		var rng = document.selection.createRange();
    		if (rng.parentElement() == obj) {
    			elm = rng.text;
    			var ini = obj.value.lastIndexOf(elm);
    		}
    	} else if (obj.setSelectionRange) {
    		var ini = obj.selectionStart;
    	}
    
    	for (var i = 0; i < aMail.length; i++) {
    		elm = aMail[i].toString();
    
    		if (elm.toLowerCase().indexOf(txt.toLowerCase()) == 0) {
    			obj.value += elm.substring(txt.length, elm.length);
    			break;
    		}
    	}
    
    	if (obj.createTextRange) {
    		rng = obj.createTextRange();
    		rng.moveStart("character", ini);
    		rng.moveEnd("character", obj.value.length);
    		rng.select();
    	} else if (obj.setSelectionRange) {
    		obj.setSelectionRange(ini, obj.value.length);
    	}
    }
    
    // -->
    </script>
    
    </head>
    
    <body>
    
    <form name="anyForm">
    <input type="text" name="anyName" onKeyUp="Complete(this, event)">
    </form>
    
    </body>
    </html>
    Ok? It's simple!!! Like JavaScript is...
    Last edited by Ilanio; 08-30-2006 at 06:26 PM.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles