How to Use the jQuery UI Autocomplete Widget

How to Use the jQuery UI Autocomplete Widget

Tutorial Details
  • Program: jQuery UI
  • Difficulty: Intermediate
  • Length: 20-30 Minutes

In this tutorial we’ll be looking at one of jQuery UI 1.8′s newest components – the Autocomplete widget. Auto-completing text fields can be a popular choice with visitors to your site because they make entering information much easier. They can be used on product search fields for example, or when a visitor must enter a country, or a city, or anything else that may be a choice from a common dataset. As well as being popular with visitors, the jQuery UI Autocomplete is popular with developers because it’s easy to use, powerful and flexible.

I’m not a massive fan of Facebook, I much prefer Twitter (@danwellman btw), but one Facebook feature I do like is the messaging feature which lets you send a message to a friend or friends. I like how the autocomplete is used to make selecting your friend’s names easier, and how the names are formatted once they have been selected and added to the ‘to’ field, e.g. they each have a close link in them that allows the name to be easily removed without having to select any text.

In this tutorial we’ll use the jQuery UI Autocomplete widget to replicate this aspect of Facebook’s messaging system. We won’t be looking at actually sending messages however. This is what we’re going to create:


Step 1 Getting Started

We’ll need to build a custom download of jQuery UI containing just the components we need; head over to the download builder at http://jqueryui.com/download. We’ll need to use the following core components:

  • Core
  • Widget
  • Position

We’ll also need the Autocomplete widget itself so ensure that just the above items, as well as Autocomplete, are checked in the Components section at the left. Use the default theme (UI Lightness) and ensure that version 1.8 is selected at the right.

Once downloaded, create a new folder on your computer and call it autocomplete. Then open the archive and copy the css and js folders into the new folder you just created. This will give you all of the library files required for this example including jQuery itself, so this doesn’t need to be downloaded separately.


Step 2 The Underlying HTML

Let’s look at the HTML for the <form> first of all:

<div id="formWrap">
	<form id="messageForm" action="#">
		<fieldset>
			<legend>New message form</legend>
			<span>New Message</span>
			<label id="toLabel">To:</label>
			<div id="friends" class="ui-helper-clearfix">
				<input id="to" type="text">
			</div>
			<label>Subject:</label>
			<input id="subject" name="subject" type="text">
			<label>Message:</label>
			<textarea id="message" name="message" rows="5" cols="50"></textarea>
			<button type="button" id="cancel">Cancel</button>
			<button type="submit" id="send">Send</button>
		</fieldset>
	</form>
</div>

It’s a pretty standard form; there’s an outer container <div> we can use for styling and the <input> that the Autocomplete will be attached to is also within a <div> element; we’ll style the <input> so that it’s slightly hidden, and we’ll style the <div> so that it looks like the other fields in the form. We give the container for the <input> the ui-helper-clearfix class name to make use of this utility class from jQuery UI’s CSS framework.

We’ll also need to link to the files we unpacked from the jQuery UI archive, as well as a custom stylesheet; the following files should go into the <head> of the page:

<link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.custom.css">
<link rel="stylesheet" type="text/css" href="css/autocomplete.css">

The following files should go at the end of the <body>:

<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.custom.min.js"></script>

Step 3 Styling the Form

We use a very simple, neutral theme in this example, most of which is purely as an example. Very few of the styles are required and most can be changed if necessary. The following CSS is used in the autocomplete.css style sheet (all of the jQuery UI styling is in the jquery-ui-1.8.custom.css style sheet):

#formWrap {
	padding:10px; position:absolute; float:left; background-color:#000;
	background:rgba(0,0,0,.5); -moz-border-radius:10px;
	-webkit-border-radius:10px; border-radius:10px;
}
#messageForm {
 width:326px; border:1px solid #666; background-color:#eee;
}
#messageForm fieldset {
	padding:0; margin:0; position:relative; border:none;
	background-color:#eee;
}
#messageForm legend { visibility:hidden; height:0; }
#messageForm span {
	display:block; width:326px; padding:10px 0; margin:0 0 20px;
	text-indent:20px; background-color:#bbb;
	border-bottom:1px solid #333;	font:18px Georgia, Serif; color:#fff;
}
#friends {
	width:274px; padding:3px 3px 0; margin:0 auto;
	border:1px solid #aaa; background-color:#fff; cursor:text;
}
#messageForm #to {
	width:30px; margin:0 0 2px 0; padding:0 0 3px;
	position:relative; top:0; float:left; border:none;
}
#messageForm input, #messageForm textarea {
	display:block; width:274px; padding:3px; margin:0 auto 20px;
	border:1px solid #aaa;
}
#messageForm label {
	display:block; margin:20px 0 3px; text-indent:22px;
	font:bold 11px Verdana, Sans-serif;	color:#666;
}
#messageForm #toLabel { margin-top:0; }
#messageForm button { float:right; margin:0 0 20px 0; }
#messageForm #cancel { margin-right:20px; }
#friends span {
	display:block; margin:0 3px 3px 0; padding:3px 20px 4px 8px;
	position:relative; float:left; background-color:#eee;
	border:1px solid #333; -moz-border-radius:7px;
	-webkit-border-radius:7px; border-radius:7px; color:#333;
	font:normal 11px Verdana, Sans-serif;
}
#friends span a {
	position:absolute; right:8px; top:2px; color:#666;
	font:bold 12px Verdana, Sans-serif; text-decoration:none;
}
#friends span a:hover { color:#ff0000; }
.ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; }

To give the form a nice transparent border with rounded corners we use the CSS3 RGBa rule and the -moz-border-radius, -webkit-border-radius and border-radius rules; most popular browsers now support these rules, including Firefox, Safari, Chrome and Opera. IE doesn’t support either of them, and although it can use a filter to implement rudimentary opacity, rounded corners would need to be supported through the use of images. The effectiveness of the RGBa transparency isn’t shown to its fullest in this example; but this type of form would probably be used as a floating modal overlay in a full implementation, which would sit above actual content on the page.

The container <div> around the <input> field that the Autocomplete text field will be attached to is given the same positioning and styling as the <input> elements, but the <input> within this container has its border removed so that it is hidden. We also reduce its width and float it to the left. This is so that when we add the formatted recipients to the <div> the <input> won’t overflow and increase the height of the <div> unnecessarily.

We also style the recipients, which will be added to the <div> as <span> elements containing a link. Mostly these are styled to match the basic theme and are also given rounded corners. It’s important that these elements are made block-level and also float so that they stack up correctly. We also need to override some of the Automcomplete styling provided by the jQuery UI theme we are using; the last selector simply prevents the individual suggestions in the menu breaking between words, which happens because we have made the <input> it is associated with so small.

At this stage, the form should appear like this:


Step 4 Attaching the Autocomplete

Next we need to attach the Autocomplete widget to the <input> within the <div>; to do this we can use the following script:

<script type="text/javascript">
	$(function(){
			
		//attach autocomplete
		$("#to").autocomplete({
					
			//define callback to format results
			source: function(req, add){
					
				//pass request to server
				$.getJSON("friends.php?callback=?", req, function(data) {
							
					//create array for response objects
					var suggestions = [];
							
					//process response
					$.each(data, function(i, val){								
					suggestions.push(val.name);
				});
							
				//pass array to callback
				add(suggestions);
			});
		},
					
		//define select handler
		select: function(e, ui) {
						
			//create formatted friend
			var friend = ui.item.value,
				span = $("<span>").text(friend),
				a = $("<a>").addClass("remove").attr({
					href: "javascript:",
					title: "Remove " + friend
				}).text("x").appendTo(span);
						
				//add friend to friend div
				span.insertBefore("#to");
			},
					
			//define select handler
			change: function() {
						
				//prevent 'to' field being updated and correct position
				$("#to").val("").css("top", 2);
			}
		});						
	});
</script>

The widget is attached to the <input> using the autocomplete() method. We supply an object literal as an argument to the method, which configures the source option and the select and change event callbacks.

The source option is used to tell the widget where to get the suggestions for the Autocomplete menu from. We use a function as the value of this option, which accepts two arguments; the first is the term entered into the <input>, the second is a callback function which is used to pass the suggestions back to the widget.

Within this function we use jQuery’s getJSON() method to pass the term to a server-side PHP file. The PHP file will use the term to extract matching contact names from a MySql database. We use a JSONP callback to process the data returned from the server; the callback function that is passed as the second argument to the source option expects to receive the data in an array, so we first create an empty array and then use jQuery’s each() method to process each item in the JSON array returned by the server. We simply iterate over each item in this array, and add each suggestion to our new array. Once our new array is built we pass it to the callback function for the widget to display in the menu.

We then define a handler for the Autocomplete’s custom select event; this function will be executed by the widget each time a suggestion is selected from the Autocomplete menu. This function is automatically passed two arguments – the event object and a ui object containing the suggestion that was selected. We use this function to format the recipient name and add it to the <div>. We simply create a <span> element to hold the text and an anchor element that can be used to remove the recipient. Once the formatted recipient has been created we just insert it directly before the camouflaged <input>.

Lastly we add a handler for the change event; this function will be invoked whenever the value of the <input> that the Autocomplete is associated with changes. We just use it to remove the value from the <input> because we’ve already added the formatted version to our container <div>. The carat looks a little high up once a formatted contact name has been added to the <div> so we also use this event handler to correct this.

This is all the configuration we need for this particular implementation, but there are still a couple of additional functions we need to add to tidy things up a little. After the autocomplete() method add the following code:

//add click handler to friends div
$("#friends").click(function(){
					
	//focus 'to' field
	$("#to").focus();
});
				
//add live handler for clicks on remove links
$(".remove", document.getElementById("friends")).live("click", function(){
				
	//remove current friend
	$(this).parent().remove();
					
	//correct 'to' field position
	if($("#friends span").length === 0) {
		$("#to").css("top", 0);
	}				
});

The <input> that our Autocomplete is attached to is partially hidden and its container <div> is styled so that it appears like the other fields on the form; to complete the deception, we add a click handler to the container <div> so that clicking anywhere within it focuses the actual <input>. Visually and functionally now the <div> should be indistinguishable from a regular field.

We also need to handle clicks on the anchor that is added to each formatted recipient; we use jQuery’s live() method because these elements may or may not exist on the page at any given time and it is easier than binding the handler function each time we create one of these anchors. Whenever one of these anchors is clicked all we do is navigate up to the parent of the anchor that was clicked and then remove it from the page. Remember when we corrected the position of the carat earlier in the script? We just need to check whether all the recipients have been removed and if so, reset its position back to its default.


Step 5 Additional Code and Resources

I used a MySql database containing a table listing each of the recipient names, and the following PHP file to accept the data sent by the getJSON() method and pull matching recipients from the database:

<?php

	//connection information
	$host = "localhost";
	$user = "root";
	$password = "your_mysql_password_here";
	$database = "test";
	$param = $_GET["term"];
	
	//make connection
	$server = mysql_connect($host, $user, $password);
	$connection = mysql_select_db($database, $server);

	//query the database
	$query = mysql_query("SELECT * FROM friends WHERE name REGEXP '^$param'");
	
	//build array of results
	for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
		$row = mysql_fetch_assoc($query);
    
		$friends[$x] = array("name" => $row["name"]);		
	}
	
	//echo JSON to page
	$response = $_GET["callback"] . "(" . json_encode($friends) . ")";
	echo $response;
	
	mysql_close($server);
	
?>

To run the downloadable example files, you’ll need a development web server with PHP installed and configured, as well as MySql and the appropriate database and table. When a letter is typed into the ‘to’ field, this letter is passed to the server and used to pull out each name that begins with the letter that was typed. The matching names are then passed back to the page as JSON and displayed in the suggestion menu:

This tutorial showed how to replicate Facebook’s message sending form, specifically, the way friends are added to the messaging form as recipients using an Autocomplete, and how the friend names are formatted once they have been added so that they can easily be removed. Our example form doesn’t actually do anything, but what we would need to do to actually send the form would be to pass the contents of the form to a server-side file for sending using AJAX, which could easily be hooked into the submit event of the send button used on the form.

The recipients would need to have some kind of meaning to back-end system of course, and would probably be mapped to email addresses in the database. We’d need to retrieve the textual content of each of the <span> elements before passing back to the server, although this would be a fairly trivial matter.

The jQuery UI Autocomplete widget makes it easy to connect to any datasource and contains a rich suite of event handlers that we can supply functions to in order to react to text being entered into the associated field, or a suggestion being selected from the menu. The widget is styled using jQuery UI’s extensive CSS framework and can easily be changed so that it matches your existing site theme. All in all, it’s an excellent widget that is easy to use and provides great functionality.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.fluxwise.com junkchaser

    Great tutorial! Anyhow, I wonder why everyone wants to imitate the facebook GUI. It’s not the most innovative around.

    • http://www.danwellman.co.uk Dan Wellman

      Thanks for reading :)

      I don’t love all of their UI, just this bit really…

      Design aside, the functionality is pretty useful

    • http://www.john-clarke.co.za John Clarke

      True, their design is not the best, but it is easily recognizable for users browsing your site the first time :)

  • http://odindutton.com Odin Dutton
    • http://www.danwellman.co.uk Dan Wellman

      I noticed the same in Win/Chrome – it would need looking at in a full implementation, I guess some kind of effect applied to the container div in which the input in question resides

      Thanks for reading :D

  • Rob

    Awesome tut! Love the Starwars contact list hehe!

  • http://www.dinnova.de Marvin Strenger

    I really wonder how such a simple and actually easy feature can end up in such a huge tutorial.^^

  • Ümit Ünal

    Very Good Tutorial.
    Thanks.

  • http://BinaryKitten.me.uk BinaryKitten

    Nice posting,i see a few issues here and there…
    the 1st is that the form has no way of returning who was selected as all that created is the span with the X link.

    Also you should use $(‘#friends’).delegate(‘.remove’, ‘click’, function() { }) instead of the live with the document.getElementById …

    the php code is also subject to sql injection as nothing is done to clean up or sanitize $param after taking it from $_GET

    also in the php
    for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) { is considered overkill compared to while( $row = mysql_fetch_assoc($query) )
    mysql_fetch_assoc returns null when there are no more entries to return which cancels the loop

    possibly using named fields instead of * would be better as well as in the example you're only using the name field. or if you had an id in there, you could use the id to allow passing back the friends selected. also using regexp in the way you have is going to cause issues.. a suggested improvement would be
    $query = mysql_query("SELECT id,name FROM friends WHERE name LIKE '$param%'");

    Apart from these points.. It's a really good tutorial :)

    • http://www.nouveller.com/ Benjamin Reid

      All valid points but beyond the scope of the tutorial really.

      • http://BinaryKitten.me.uk Kathryn Reeve (BinaryKitten)

        Any Tutorial should promote good code. There are many people who will take the code and use it as is, without learning that there are issues. Providing tips that helps the tutorial writer and those who read it was my aim in posting that reply.

        Anything that comments on the points in the code provided is surely within scope is it not?

      • http://www.randomthink.net/ Brian Arnold

        While it’s true that a lot of that is out of the scope of the tutorial, it’d have been much better to provide just a generic JS array of names, rather than give out code that’s vulnerable to SQL injection.

      • Jim Trowbridge

        I disagree, any tutorial, or anything of the like should show how to protect against a SQL injection attack, at least… since the people that may read this and learn may end up building an insecure production website that gets hacked and ruins businesses or people… simply out of ignorance… here’s a quick for instance:
        Your online banking site hires a new developer (a former trainee of this tutorial) to make a ‘Tax Questions’ blog or something, it gets hacked and all PII is now pulled from the database, stolen, sold, etc – just because of poor judgement on the Bank’s management side, inexperience of the new developer, and the tutorial that gave the developer the PARTIAL-know-how to build the system the bank required…. it’s a very simple mistake, but a huge one.

        Better to just show how to do it correctly in the first place…

      • http://www.nouveller.com/ Benjamin Reid

        Well you’d be nieve to copy and paste code from any tutorial site and put it in a live environment, in fact, you probably deserve to get hacked for being so lazy!

        At the very most the author could of added a note explaining that this code is un-secure and would need protecting from injection etc…

        You’re trying to put the blame on the website/author, but it’s the user’s decision what they do with the code at the end of the day. The bank’s not going to sue a learning resource, they’re going to sue the fool who messed up.

    • http://www.danwellman.co.uk Dan Wellman

      I love your avatar :D

      Thanks for the comments, here are my thoughts:

      The recipient names could not be harvested in a normal form submit, but you’d use AJAX to send the contents of the form to the back-end with this type of form/widget anyway, and could easily process each recipient on the client before sending to the server.

      The delegate() method would certainly be a valid alternative to live(), although in this simple implementation I don’t think it would improve the functionality or performance in any way.

      Yes, the PHP would need to check the parameter to prevent malicious input, but the focus of this tutorial was definitely on the front-end. The PHP was just an example, and you’ll notice I didn’t really explain this code, or go through the preparation of the MySql, at all. If the focus of the article had been equally on the back-end, this would have ben included and covered.

      Thanks for the tip re using while(0 in the PHP, I’ll have a look at using that in future with small data sets. I’ve used LIKE $param before, but the problem with that is that it matches any letter that appears anwhere in the name, so e.g. ‘a’ would match both ‘alf’ and ‘dave’, but in this type of feature you;d probably only want to match on the first letter.

      Thanks for reading :)

      • http://BinaryKitten.me.uk Kathryn Reeve (BinaryKitten)

        in reponse to the $param matching issue ” like ‘a%’ ” matches only those that start with ‘a’ or ‘A’ … ” like ‘a’ ” matches only items that equal ‘a’ or ‘A’ ” like ‘%a%’ ” matches anything with ‘a’ or ‘A’ in it.

        delegate is bound to the item rather than to the window with .live it does mean that there is more repsonse to it.

        in the response to the “not returning” issue, you could return the “id” of the user or even use the name as the value for a hidden input

        $(”, {value: ‘name/id’, type:’hidden’, name:’names[]‘}).appendTo(span);

        this would create a new hidden input with the name, which could be sent through.

      • http://BinaryKitten.me.uk Kathryn Reeve (BinaryKitten)

        oops comment code got eaten

        $(‘<input />’, {value: ‘name/id’, type:’hidden’, name:’names[]‘}).appendTo(span);

    • http://www.tomsyweb.com Toé

      I don’t know the utility of “callback”. Can you explain me ? is it possible to call “suggest.php?term=” in $.getJSON and return only “json_encode($friends)” in the php file ?

    • http://www.nathanfriend.co.uk Nathan Friend

      Binary Kitten, how could I get the selected names into a form variable? like $_POST['to']

      Cheers,

      Nathan.

  • http://www.avey.de Way

    I am not as critical as my previous speaker (BinaryKitten) – nevertheless he has right with his hints.

    It’s good to see jquery UI tutorials because the new version 1.8 is really really great. I’m working with it for a new project and take use of some nice new features like button and autocompleter as well and what should I say, it’s recommendable so this tutorial is!

    Ignore the server part at step 5 or improve it because it’s pretty quick and dirty. But the rest is good stuff!

  • aryan

    Nice! I’d like a detailed tutorial on Jquery form validation plugin.

  • Jhon

    Very use full. Thanks!

  • http://www.jordanwalker.net Jordan Walker

    This is a really neat application.

  • Bolso

    BinaryKitten:

    Would you mind to tell me what are the possible issues of using regexp as stated in the tutorial? Why your solution is better?

    • http://BinaryKitten.me.uk Kathryn Reeve (BinaryKitten)

      Bolso – Regexp is a good tool for the right job but in this situation they are just checking to see if the name starts with something. the LIKE keyword is a better option for this.

  • http://www.jessedijkstra.nl/ Jesse Dijkstra

    Interesting ready, was looking for something like this.

    One remark though, the HTML you’re using is quite redundant on itself. You’re using a lot of ID selectors while you only need one, the wrapper DIV. This makes the HTML a lot cleaner. For compatibility with other websites, using classes instead of ID’s for the form buttons makes more sense.

  • Mike

    WOW! I searched all over yesterday looking for more info on this! Now after I broke my neck to get it working properly, this pop’s up hours later!

  • http://www.jeffadams.co.uk Jeff Adams

    This is great thanks alot.

    It’s really weird because I used the jQuery UI plugin for my Admin themes over at Themeforest and for my next one figured I’d use this widget – you”ve saved me the time figuring it out lol.

    Awesome.

  • http://www.kaynatsoft.com parvez

    Great tutorial! I’m going to use this technique on my upcoming project.
    thanks

  • http://www.canaydogan.net Can Aydoğan

    Great arcitle. Thanks for sharing.

  • http://gdesigns.in Karthik

    Better than what you wrote in your book thanks for tut Dan :)

  • http://www.tommybrophy.com Tommy

    Really cool tutorial, well written and easy to follow. Will definately be using this in the future.
    Thanks Dan.

  • http://www.danwellman.co.uk Dan Wellman

    @Jim Trowbridge: I can see your point of view, but this wasn’t a tutorial about security, best practice, or even PHP really. I don’t think a developer could read one single tutorial and then claim, or expect, to be a seasoned developer.

  • http://www.beginnercode.com ^Lestat

    I’ve come to find that the class ui-autocomplete-loading does get applied to the input, but for some reason when the datasource is remote, the ui-autocomplete-loading .gif doesn’t appear. Any ideas?

    • Jigga-J

      I used to have the same problem! The reason is the missing Ajax GIF in the “ui-lightness\images” folder.

      This seems to be reported as a bug. Have a look here:
      http://dev.jqueryui.com/ticket/5432

      I solved this issue by downloading a Ajax loading GIF image and rename it to “ui-anim_basic_16x16.gif” and put it in the specified folder.

      Give it a try!

  • ben

    Is this tutorial nessasary? The documentation isn’t hard to get your head round.

  • Dan

    Everything except the drop down works. The friends.php works, it displays all members I even changed the correct callback URL inside the script… alas… no drop down… :-(

    Whyyyyyyy

  • http://google.com Master Bater

    How convienent, I haven’t worked with JQuery UI in a while and headed over to the website, noticed the additions of the autocomplete and button widgets then headed over to Nettuts and this is on the front page XD

    Nice tutorial Dan. Like that it was short, concise, and you explained the code at every step.

    Not to be picky and this is trivial in the context and purpose of the article, but the send button is too close to the cancel button. Immediately made me think of: “The ejector seat button is inexplicably placed right next to the cabin lights button.” – http://www.codinghorror.com/blog/2010/03/the-opposite-of-fitts-law.html Anyways nice work. Looking forward to reading more of your articles.

  • http://www.xcellence-it.com/ Xcellence IT

    would like to try it…

    thanks for sharing this new feature of jquery with us….

  • Natrium

    This is not unobtrusive.
    Does not work when JavaScript is disabled.

    • http://www.nouveller.com/ Benjamin Reid

      When JS is disabled it just performs like a normal form. What else could you ask for?

      • Natrium

        Yes, I see it now.
        But the To-textbox has some strange behavior in FireFox 3.6.2

  • http://gamerholic.com Justin

    Great script, but exactly how do I submit the value of the friends. I’m using a different ajax script to send the from, I’m not able to pick up the names of the to value any where.

    • http://www.danwellman.co.uk Dan Wellman

      You would need to get the sollection of span elements from the container div and then extract the text from each of them, something like:

      var toArray = [];
      $(“#friends span”).each(function(){
      toArray.push($(this).find(“span”).text());
      });

      Then it would just be a case of passing the array back to the server-side file as JSON (most likely), which if you already have a form that is being submitted via AJAX should be pretty straight-forward. The array may be better being converted to an object, you’d need to test…

      • http://gamerholic.com Justin

        Thanks for replying, I’ve tried everything. It’s just not working. here’s my script.
        http://www.BreezMe.com/sendform.js

        Any idea’s?

      • http://www.danwellman.co.uk Dan Wellman

        >< yeah, the each() method is already being called on the collection of spans, try changing the push line to:

        toArray.push($(this).text());

  • http://www.myastrodata.com/ Vladimir Komarov

    Hi there!

    I’ve just read this tutorial and I think that this is useful, so thank you!

    But what about if you have to use cyrillic in this case?

  • m.o.k

    Great Tut!

    You could also consider using back space to delete names in your “to” field -> like

    http://devthought.com/projects/jquery/textboxlist/

    • http://www.danwellman.co.uk Dan Wellman

      That is a great idea, the Autocomplete widget itself is fully keyboard-navigable, so this kind of implementation should and carry on that functionality wherever possible.

  • http://www.soamazing.eu Rick

    Nice tutorial! Must say that it’s indeed quite a lot of code. Done a similar effect in plain javascript using less code…

    Last month I found many similar tutorials. In many cases is missed a functionality that I think is quite important. The same is missing in this example. Let’s say you only know the surname? In this example that could be ‘Dooko’. Typing that will give you suggestions as ‘Darth Vader’ and ‘Durge’, but not ‘Count Dooko’. Now I think a small change on line 15 in step 5 should do the trick.

    Besides that I often find myself loading every name from the database into an array and add the array into the javascript. In that way there is just one database request loading all the names. On the client side it will then find and give the suggestions. I believe that makes the script faster and avoids many (and sometimes even useless) database requests. I understand that might not be a good idea if you have a million of names in your database since that might make the javascript file quite bloated. But then again, when you have a million names in your database you probably use a dedicated server that can handle all the request ‘live’.

    I’m curious what your thougts are on these 2 points. I’m eager to learn more and especially from masters like you ;-) And again, thanks for the tutorial, will defenitly look more into it when I have a better understanding of just plain javascript (the DOM, AJAX, etc).

    • http://www.danwellman.co.uk Dan Wellman

      Hey Rick,

      That would be a great extra feature, the PHP shown was really just an example to make the Autocomplete itself work. It’s very, very basic and is probably the simplest the code could be and still work. the tutorial was not about the PHP…

      • http://www.soamazing.eu Rick

        Hi Dan,

        Thanks for the reply! Was just on it since I needed an autocomplete for another project and found out that it can be done (when using the Jquery UI) with;

        .autocomplete( “search” , [value] )

        Not sure if it works right, have to test it later when i’m implementing it. The documentation states: http://jqueryui.com/demos/autocomplete/#method-search

  • http://jensbits.com jen
    • http://www.danwellman.co.uk Dan Wellman

      Nice, I did UK cities when the library was back in ver 1.6 (last year sometime). I like how the component has evolved since that initial (and brief) debut :)

      Thanks for reading :)

  • andrew

    i agree, thanks for the tutorial.

    does anyone know of a way to have the first result highlighted automatically?

  • http://misretratos.com mic

    nice this

    • http://misretratos.com mic

      :-o

  • Todd

    Autocomplete is very much broken, any mouse click more than a split second long fails to fire the select event in Firefox and IE. Don’t put this on your site and have it broken for most of your visitors. This shouldn’t be in 1.8 in this state.

    Try it with a longer mouse click (> 0.5 seconds) in either of these demos:
    http://jqueryui.com/demos/autocomplete/#remote
    http://www.danwellman.co.uk/demos/autocomplete.html

  • Kevin

    The indentation of the Javascript is unbalanced – you have to look very carefully at the bracketing. This makes it unnecessarily hard to scan and will likely to lead to errors for some who use this as a guide.

    Tutorial code should be as clear as possible, so I suggest taking a few minutes to correct the indentation. I’m viewing this in IE7, but since indentation uses spaces, I assume it is the same in all browsers.

  • http://achmatim.net achmatim

    cool and ultimated guide. i must try this plugin as soon as possible.

  • Andrés

    Hello there.

    Nicely done tutorial. Do you happen to know a way to give it multi-language support?

    I can see the widget doesn’t offer the option, but I’d like to know how would you do it. For example:

    If I’m looking for “andrés”, it should also return an “andres” suggestion, of course the exact match taking priority (appear in the top) in the list .

    If anyone can help me with this, I’d greatly appreciate it. Thanks in advance.

    • http://www.robfaraj.com Rob

      Also having this issue? Anyone know how to resolve?

  • kenny

    How can i get the id of my friend from this?

  • Nick

    This is exactly what I need for my current project but I cannot get the callback to work. Specifically the add(suggestions) function does not produce a drop-down of candidates.I have tried using different arrays as the add function argument but no luck. Am I missing something?

    • memordial

      i got this problem too, do you have the solution?? the return data was successful. it looks like add(suggestions) is not working. :(

  • JP Gorman

    Nice tutorial, I’ve taken your idean and applied it to another autocomplete tool kit, but I did find that in IE there was a problemd with the last generated span wrapping instead of going onto the next line. This is due to the generated span element needing to have the style white-space:nowrap; which is not used in the tutorial

    Here’s my css amends

    #to {border:medium none;float:left;margin:5px 5px 3px 3px;padding:0 0 3px;position:relative;top:0;width:auto;overflow:hidden;display:block;white-space:pre;}

    #friends span { display: block; width:auto; white-space:nowrap;margin:3px; padding:3px 20px 4px 8px; position:relative; float:left; text-indent:0; background-color:#eee; border:1px solid #333; -moz-border-radius:7px; -webkit-border-radius:7px; border-radius:7px; color:#333; font:normal 11px Verdana, Sans-serif; }

  • Andy

    Hi,

    Thanks for this tutorial – it certainly makes sense of the autocomplete function which, to be honest, the ones on the JQuery website don’t!

    A couple of things:

    1. When submitting the form via POST, nothing is submitted for the “To” field.
    2. How would I update a hidden field with, say, IDs from the recordset? (The solution to this, for me at least, would solve issue 1)

    Thanks

  • http://thesnell.com/blog Nathan Snell

    Great tutorial! Was exactly what I was looking for!

    One thing I’ve been trying to figure out, and any hints/tips you could give would be appreciated. I believe one of the comments touched on it, too. What would be the best way to, when a dropdown element is selected from the autocomplete, to have a hidden input field’s value set. Obviously, what I am going for is being able to set something like the ID of the user(s) being contacted as opposed to just autocompleting their name. Yes, you could just pull the value from the span that”s created based on the ID and do a search based on name but that leaves it open to people with the same name, etc.

    Thanks for your time in creating this tutorial!

  • Balaji

    Hai,
    Thanks for nice plugin…I have modified little bit in css file for my project.
    After modification, i could get the data from Database & i can select it in auto complete box.But after selection of 1st item, again 1st items name appearing in the search box.

    Awaiting for your help….

    • Nick

      I am having the same problem. Anyone have a suggestion?

      • Nick

        Looks like jQuery UI 1.8.1 was the problem. Rolling back to 1.8 fixed the issue.

      • Balaji

        Hai Nick,

        Thanks.. Fixed….

    • Chris

      1.8.1 and 1.8.2 have the problem of duplicating the selected item’s text, next to one another. Can you make a fix?

      Also, you should use the google cdn for the code, instead of including jquery and jquery ui.

      here’s what im using, and it has that error because im using 1.8.2 / 1.8.1

  • wasiq

    Hi,

    Thanks for this tutorial – it certainly makes sense of the autocomplete function which, to be honest, the ones on the JQuery website don’t!

    A couple of things:

    1. When submitting the form via POST, nothing is submitted for the “To” field.
    2. How would I update a hidden field with, say, IDs from the recordset? (The solution to this, for me at least, would solve issue 1)

    Thanks

    please reply this

    • Orhun

      Hi,

      Thanks for the great information.

      I have the same problem with POST. There is nothing posted for “To” field.
      Any one have any idea?

      Thanks in advance.

  • vinod

    I really like this exp. Please let me know how to do in Asp .Net 2.0. It will be very great for if somebody
    tell me.

    thanks

  • Long cat

    Nice tutorial mate! It helped me understanding the JQuery ui Autocomplete!

    Pls check http://www.svenskasynonymer.se/ for an example of Autocomplete with ui-darkness!

  • http://philwigglesworth.net/ philw

    Thanks: I was about to build something like this myself but you saved me a lot of effort.

    I’m kind of amused at the gripers, who seem to either: (a) expect a tutorial which encompasses the entire software engineering field; or (b) are looking for a component they can use out of the box.

    The key point of the tutorial is shifting each new entry into the DOM on select. That’s a great idea and it works well.

    To answer someone’s question about asp.net, well it’s basically the same thing. The bit you have to add is that you will have to copy the spans back into the input field on submit, because asp.net “knows” about the input field, but not stuff JQuery creates in the DOM at the client. You’ll also have to copy any text out of the input field on postback, creating the spans in the same way as shown here. So that’s:

    1) Add a JQuery handler to your form submit button. This hides the input field, then copies each of the spans (minus the decorations) into the input field, so it’s a CSV set of entries. This handler fires when you submit the form, so by the time ASP.NET sees it, it thinks that the text was entered in the form’s input field.

    I implemented this whole thing as a “Field extender” which works well.The back end just has to handle a CSV list in that input field, which is unchanged from before you implement this.

    2) On postback you need to recreate the set of spans. I put my version of the span creation stuff from this tutorial into a function and called that from a document ready handler… it just parses the input field and for each CSV entry in there converts it into a span broadly as shown here.

    3) The web service thing… well there are lots of ways to do that covered by lots of tutorials. My web service returns two values for each thing I look up, but the principles are as shown here.

    Oh yes, and you need JQueryUI 1.8.2 or greater, as 1.8 had an autocomplete defect in it as noted above.

  • http://mmhan.net Mike

    Is there anyway to change the width of the suggestions??

  • dahe

    Hi! i’m trying this, i get the json response, the array, but it does not shows as suggestions list.

    My js code:

    $(“#buscador”).autocomplete({
    //source: “autocompleteDescriptorSearchJSON.php?callback=?”,
    source: function (request, response){
    $.getJSON(“autocompleteDescriptorSearchJSON.php?callback=?”, request, function(data) {

    //create array for response objects
    var suggestions = [];

    //process response
    $.each(data, function(i, val){
    suggestions.push(val.name);
    });

    //pass array to callback
    response(suggestions);
    });
    },
    minLength: 3

    });

    and my script

    $palabra = strtoupper($_GET["term"]);
    $sqlLetras=”SELECT id,descripcion FROM opcionesmenu WHERE descripcion LIKE ‘$palabra%’ ORDER BY descripcion ASC”;
    $rsLetras = ExecSQL($conn,$sqlLetras);
    if (NumFilas($rsLetras)>0){
    $todasPalabrasLetra = Array();
    while ($fila = obResultado($rsLetras)){
    $todasPalabrasLetra[] = $fila[1];
    };

    $response = $_GET["callback"] . “(” . json_encode($todasPalabrasLetra) . “);”;
    echo $response;

    This retuns

    jsonp1284064734897(["APOYO"]);

    Why do you think is this?

  • http://www.bryanstober.com Bryan

    I see lots asking about how to return the form to a specific user id after returning a user name can anyone give a layman’s explanation of how do do this properly?

  • kateram

    i dont understand the css part :

    .ui-menu .ui-menu-item { whitewhite-space:nowrap; padding:0 10px 0 0; }

    where this code is being used?
    anyone? :/

    thx