Making a global navigation autocomplete ======================================= This guide demonstrates how to make a global navigation autocomplete like on http://betspire.com. Create the view --------------- The global navigation autocomplete is generated by a normal view, with a normal template. Then, you can just test it by openning /your/autocomplete/url/?q=someString Only two things matter: - you should be able to define a selector for your options. For example, your autocomplete template could contain a list of divs with class "option", and your selector would be '.option'. - each option should contain an url of course, to redirect the user when he selects a option Actually, it's not totally true, you could do however you want, but that's a simple way i've found. Once this works, you can follow to the next step. For your inspiration, you may also read the following example. Example ~~~~~~~ Personnaly, I like to have an app called 'project_specific' where I can put my project-specific, non-reusable, code. So in project_specific/autocomplete.py of a project I have this:: from django import shortcuts from django.db.models import Q from art.models import Artist, Artwork def autocomplete(request, template_name='project_specific/autocomplete.html', extra_context=None): q = request.GET['q'] # crash if q is not in the url context = { 'q': q, } queries = {} queries['artworks'] = Artwork.objects.filter( name__icontains=q).distinct()[:3] queries['artists'] = Artist.objects.filter( Q(first_name__icontains=q)|Q(last_name__icontains=q)|Q(name__icontains=q) ).distinct()[:3] # more ... # install queries into the context context.update(queries) # mix options options = 0 for query in queries.values(): options += len(query) context['options'] = options return shortcuts.render(request, template_name, context) And in project_specific/autocomplete.html:: {% load i18n %} {% load thumbnail %} {% load url from future %} {% load humanize %} In this template, my option selector is simply 'li:has(a)'. So every tag that is in an li with an a tag will be considered as a valid option by the autocomplete. As for the url, it looks like this:: url( r'^autocomplete/$', views.autocomplete, name='project_specific_autocomplete', ), So, nothing really special here ... and that's what I like with this autocomplete. You can use the presentation you want as long as you have a selector for your options. Create the input ---------------- Nothing magical here, just add an HTML input to your base template, for example:: Of course, if you have haystack or any kind of search, you could use it as well, it doesn't matter::
{{ search_form.q }}
Loading the script ------------------ If you haven't done it already, load jQuery and the yourlabs_autocomplete extension, for example:: Script usage ------------ The last thing we need to do is to connect the autocomplete script with the input and the autocomplete view. Something like this would work:: There are other options. If these don't work very well for you, you should read autocomplete.js. It's not a fat bloated script like jQueryUi autocomplete with tons of dependencies, so it shouldn't be that hard to figure it out. The other thing you want to do, is bind an event to the event yourlabs_autocomplete.selectOption, that is fired when the user selects an option by clicking on it for example:: That's all folks ! Enjoy your fine global navigation autocomplete. Personnaly I think there should be one in the header of every project, it is just **so** convenient for the user. And if nicely designed, it is very 'web 2.0' whatever it means hahah.