AJAX Autocomplete for Cities in Django

If you’re building a webapp that has user registration, you’ll probably want to keep track of various tidbits of user information such as: username, e-mail,  city, country etc.

Designing the registration page to take in a user’s name and e-mail is easy, just give them an input box and let them type whatever they want (within reason).

Designing the form that lets users enter their city is a bit more difficult.  Some sites use check-boxes (ugh), and some use dropdowns (better, but LONG).  A nicer solution is to create an input box that lets people type in whatever they want, but have an auto-complete feature that helps make the input more uniform.

Make it so!

Now, you could code this all by hand using javascript/JQuery, or you could use the jQuery Autocomplete plugin by pengoworks: http://www.pengoworks.com/workshop/jquery/autocomplete.htm.  The great thing about this particular autocomplete plugin is that it is quite small, somewhere around 13k.  The documentation is a bit sparse, but otherwise quite good.  It has a lot of features: it lets you do AJAX, it manages caching, and it has a lot of configurable options.

Make it work (javascript)!

Okay, so go ahead and download the js, the css, and add references to it in your html template.   Now, you’ll also need a new js file so that you can apply the plugin onto the html when the page is done loading.  If you have an existing js file, then go ahead and use that file instead.

In your js file, you want to write:

$(document).ready(function() {
	$("select your input element").autocomplete("ajax url");
});

And that’s it!  There’s a lot of configurable options, so read up on them on in the documentation.  I use the following settings:

$(document).ready(function() {
	$("select your input element").autocomplete("ajax url", {
		delay:10,
		minChars:2,
		matchSubset:1,
		matchContains:1,
		cacheLength:10,
		autoFill:true
	});
});

Make it work (server-side)!

In Django, setup a new view that follows from your ajax url.  The plugin sends a GET request with a key ‘q’ that contains the partial word entered by the user. The response that the plugin is expecting is a plain text response where each suggestion is on its own line.  So if you want to respond with “Toronto”, “Tahiti”, and “Tornado”, you’d do

if request.method == 'GET':
        GET = request.GET
        if GET.has_key('q'):
            city_matches = 'Toronto\nTahiti\nTornado'
            return HttpResponse(city_matches, mimetype="text/plain")

Now here’s the tricky part, you need a city list to query don’t you?

City List

Now, after a bit of searching, I found a nice (free!) city list at GeoWorldMap: http://www.geobytes.com/freeservices.htm.  You’ll have to do a bit of Python magic to parse it into a Django-friendly format, but it should give you what you need.

Questions?

If you need clarification on the steps (which I must admit, are quite abstract), or you want to look at my json/city list parsing code, give me a shout in the comments.

This entry was posted in Django, Tech and tagged , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>