Using the jQuery-UI Autocomplete Widget

The latest version of jQuery-ui has an autocomplete widget. No more looking for one that will work (you get the point) with the version of jQuery that you have.

All you have to do is pull the latest one down from the jQuery-ui site and you are good to go.

First the jQuery to use the autocomplete plugin:

 
//we will be using this to cache the responses from the server
var ajaxCache = {};
 
//activate autocomplete on boxes that have the autocomplete class
$("input.auto_complete").autocomplete({
	source: function(request, response) {
		//what are we searching for
		var query_type = $(this).attr('element').attr('id');
		//the cacheterm that we use to save it in the cache
		var cachedTerm = (request.term + '' + query_type) . toLowerCase();
		//if the data is in the cache and the data is not too long, use it
		if (ajaxCache[cachedTerm] != undefined && ajaxCache[cachedTerm].length < 13) {
			//map the data into a response that will be understood by the autocomplete widget
			response($.map(ajaxCache[cachedTerm], function(item) {
				return {
					label: item.value,
					value: item.value
				}
			}));
		}
		//get the data from the server
		else {
			$.ajax({
				url: "/ajax/auto_complete.php",
				dataType: "json",
				data: {
					query_type: query_type,
					q: request.term
				},
				success: function(data) {
					//cache the data for later
					ajaxCache[cachedTerm] = data;
					//map the data into a response that will be understood by the autocomplete widget
					response($.map(data, function(item) {
						return {
							label: item.value,
							value: item.value
						}
					}));
				}
			});
		}
	},
	//start looking at 3 characters because mysql's limit is 4
	minLength: 3,
	//when you have selected something
	select: function(event, ui) {
		//close the drop down
		this.close
	},
	//show the drop down
	open: function() {
		$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
	},
	//close the drop down
	close: function() {
		$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
	}
});

The ajax/auto_complete.php would look something like this:

 
<?php
 
//make sure that we only allow valid query types
/**
 * @var array
 */
$validQueryTypes = array(
	'country',
	'city',
	'first_name',
	'last_name',
);
/**
 * @var string
 */
$column = (isset($_POST['query_type']) && in_array($_POST['query_type'], $validQueryTypes))? $_POST['query_type'] : null;
/**
 * @var string
 */
$q = isset($_POST['q'])? $_POST['q'].'%':null;
 
 
if($column && $q){
	switch($column){
		case 'country':
		case 'city':
			$q = new sQuery();
			$results = $q->from('addresses')
				//to make things simpler for the javascript, always select as value
				->column($column . ' as value')
				->where($column, $q, 'LIKE')
				->getAll();
 
			//SELECT $column as value FROM addresses WHERE $column LIKE '$q%';
			break;
		case 'first_name':
		case 'last_name':
			$q = new sQuery();
			$results = $q->from('users')
				->column($column . ' as value')
				->where($column, $q, 'LIKE')
				->getAll();
			//SELECT $column as value FROM users WHERE $column LIKE '$q%';
			break;
	}
 
	//$result is something like this:
	array(
		array('value'=>'Canada'),
		array('value'=>'America'),
		array('value'=>'Mexico'),
		array('value'=>'Netherlands'),
	);
 
	//then return it to the javascript
	echo json_encode($results);
}
exit;

Then the simplest part of the exercise:

 
City:
<input type="text" name="city" id="city" title="enter a city" class="auto_complete" />
 
Country:
<input type="text" name="country" id="country" title="enter a country" class="auto_complete" />
 
First Name:
<input type="text" name="first_name" id="first_name" title="enter a first_name" class="auto_complete" />
 
Last Name:
<input type="text" name="last_name" id="last_name" title="enter a last_name" class="auto_complete" />

And if they don’t have javascript enabled it doesn’t detract from the form (go progressive enhancement!).

Edit:

This post is pretty old, but just in-case you were wondering sQuery is this: https://github.com/SeanJA/ShoestringPHP/blob/master/library/classes/squery.class.php and there is also a better tested more standalone-y version here as a separate project: https://github.com/SeanJA/query-builder.

flattr this!

Daily Digest for December 14th

googlereader (feed #5)
twitter (feed #2)
iPhone users are delusional according to researchers http://news.cnet.com/8301-17852_3-10414356-71.html [SeanJA]
twitter (feed #2)
Do you know how to say…? http://www.explosm.net/comics/1888/ [SeanJA]
twitter (feed #2)
Do I look like I was born yesterday? http://en.wikipedia.org/wiki/Baby_Face_Nelson [SeanJA]
twitter (feed #2)
RT @ManningBooks: Deal of the Day: December Countdown! 50% off all print books! Use code dotd1214 http://www.manning.com [SeanJA]
twitter (feed #2)
Tis the season of when parents willingly drop their children in the lap of a fat stranger in a red suit [SeanJA]
twitter (feed #2)
@gavinblair Gmail for work? I wish… [SeanJA]
twitter (feed #2)
RT @DavidSuzukiFDN: If there were no Caribou left, our quarter would become a collectible. Let’s not let that happen: http://bit.ly/696ENs [SeanJA]
twitter (feed #2)
I’m part of a team #Ralphie [SeanJA]
twitter (feed #2)
RT @jimmycarr: Saw ‘Avatar’ at the IMAX. […] It rules & the Girl Smurf is hot. [SeanJA]
twitter (feed #2)
twitter (feed #2)
What is the underwater velocity of a laden octopus? [SeanJA]
twitter (feed #2)
Yes I realise that the joke is unladen #OctopusCarryingCoconuts [SeanJA]
twitter (feed #2)
twitter (feed #2)
@hijinksensue http://twitpic.com/tkdgg – You don’t have to reload a stick. [SeanJA]
twitter (feed #2)
twitter (feed #2)
Fear the octopus that carries coconuts, for he can run like man #OctopusCarryingCoconuts [SeanJA]
generic (feed #12)
generic (feed #12)
generic (feed #12)
twitter (feed #2)
God has made me indestructible! You know what this means? Now I can go to the zoo and tease the bears! [SeanJA]
generic (feed #13)

flattr this!

links for 2008-12-18

flattr this!