Making a global navigation autocomplete¶
This guide demonstrates how to make a global navigation autocomplete like on http://betspire.com or facebook.
There is a living example in test_project/navigation_autocomplete, which this page describes.
Note that there are many ways to implement such a feature, we’re just describing a simple one.
A simple view¶
As we’re just going to use autocomplete.js for this, we only need a view to render the autocomplete:
from django import shortcuts
from django.db.models import Q
from django.contrib.auth.models import User, Group
from cities_light.models import Country, Region, City
def navigation_autocomplete(request,
template_name='navigation_autocomplete/autocomplete.html'):
q = request.GET.get('q', '')
context = {'q': q}
queries = {}
queries['users'] = User.objects.filter(
Q(username__icontains=q) |
Q(first_name__icontains=q) |
Q(last_name__icontains=q) |
Q(email__icontains=q)
).distinct()[:3]
queries['groups'] = Group.objects.filter(name__icontains=q)[:3]
queries['cities'] = City.objects.filter(search_names__icontains=q)[:3]
queries['regions'] = Region.objects.filter(name_ascii__icontains=q)[:3]
queries['countries'] = Country.objects.filter(name_ascii__icontains=q)[:3]
context.update(queries)
return shortcuts.render(request, template_name, context)
And a trivial template
(test_project/navigation_autocomplete/templates/navigation_autocomplete/autocomplete.html
):
{% load url from future %}
{% for country in countrys %}
<a class="div choice" href="{% url 'admin:cities_light_country_change' country.pk %}">{{ country }}</a>
{% endfor %}
{% for region in regions %}
<a class="div choice" href="{% url 'admin:cities_light_region_change' region.pk %}">{{ region }}</a>
{% endfor %}
{% for city in cities %}
<a class="div choice" href="{% url 'admin:cities_light_city_change' city.pk %}">{{ city }}</a>
{% endfor %}
{% for group in groups %}
<a class="div choice" href="{% url 'admin:auth_group_change' group.pk %}">{{ group }}</a>
{% endfor %}
{% for user in users %}
<a class="div choice" href="{% url 'admin:auth_user_change' user.pk %}">{{ user }}</a>
{% endfor %}
And of course a url:
from django.conf.urls import patterns, url
urlpatterns = patterns('navigation_autocomplete.views',
url(r'^$', 'navigation_autocomplete', name='navigation_autocomplete'),
)
A basic autocomplete configuration¶
That’s a pretty basic usage of autocomplete.js
(test_project/navigation_autocomplete/templates/navigation_autocomplete/script.html
):
{% load url from future %}
<script type="text/javascript">
$(document).ready(function() {
$('#navigation_autocomplete').yourlabsAutocomplete({
url: '{% url 'navigation_autocomplete' %}',
choiceSelector: 'a',
}).input.bind('selectChoice', function(e, choice, autocomplete) {
document.location.href = choice.attr('href');
});
});
</script>
Which works on such a simple input
(test_project/navigation_autocomplete/templates/navigation_autocomplete/input.html
):
<input type="text" name="q" id="navigation_autocomplete" style="width: 270px; font-size: 16px;" />
<style type="text/css">
/* cancel out django default for now, or choices are white on white */
#header a.choice:link, #header a.choice:visited {
color: black;
}
</style>
See how admin/base_site.html
includes them:
{% extends "admin/base.html" %}
{% load i18n %}
{% block extrahead %}
{# These are needed to enable autocompletes in forms #}
<script src="{{ STATIC_URL }}jquery.js" type="text/javascript"></script>
{% include 'autocomplete_light/static.html' %}
{% if user.is_authenticated %}
{# This script enables global navigation autocomplete #}
{# refer to the docs about global navigation autocomplete for more information #}
{% include 'navigation_autocomplete/script.html' %}
{% endif %}
{% endblock %}
{% block branding %}
<h1 style="display: inline-block" id="site-name">{% trans 'Autocomplete-light demo' %}</h1>
{% if user.is_authenticated %}
{% comment %}
This is a simple input, used for global navigation autocomplete. It
serves as an example, refer to the documentation to make a navigation
autocomplete.
FYI It leaves in test_project/navigation_autocomplete/templates
{% endcomment %}
{% include 'navigation_autocomplete/input.html' %}
{% endif %}
{% endblock %}