Using the jQuery Autocomplete Plugin with Django

Here’s another look into the development of ComicBinder.

There’s already a good tutorial on how to use an autocomplete plugin with Django, but I wanted to use this much snazzier plugin.

The Process

Load both jquery.autocomplete.min.js and jquery.autocomplete.css in your page.

In your form object, create a CharField to hold your autocomplete. Something like:

title = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': 'The name of a comic'}))

Create a hidden field to hold the primary key of the item you’re selecting (so you don’t have to depend on searching against a ‘name’ field or something else equally brittle):

title_pk = forms.IntegerField(widget=forms.HiddenInput())

Create a view to populate the autocomplete list:

def title_lookup(request):
    results = []
    if request.method == "GET":
        if request.GET.has_key(u'q'):
            value = request.GET[u'q']
            # Ignore queries shorter than length 3
            if len(value) > 2:
                model_results = Title.objects.filter(name__icontains=value)
                results = [ (x.__unicode__(), x.id) for x in model_results ]
    json = simplejson.dumps(results)
    return HttpResponse(json, mimetype='application/json')

This will, of course, need a URLconf:

url(r'^title_lookup/$', view=title_lookup, name='title_lookup'),

And to finish it off, a bit of JavaScript in your template to call the plugin:

<script>
    $(function() {
        $('#id_title').autocomplete('{% url title_lookup %}', {
            dataType: 'json',
            width: 500,
            parse: function(data) {
                return $.map(data, function(row) {
                    return { data:row, value:row[1], result:row[0] };
                });
            }
            }).result(
                function(e, data, value) {
                    $("#id_title_pk").val(value);
                }
            );
        }
    );
</script>

Sources

Comments

bayo opadeyi → December 11th, 2009 at 2:00 am

I already do something like this for my auto-complete. I was wondering if I could make an autocomplete widget that holds all the javascript and all. the view part seems to be the issue, since you need a request object that the widget knows nothing about. I wonder what approach you will take to make this work

Daniel Nyström → December 11th, 2009 at 3:03 am

Is there any way to attach the javascript code into the Form class? It would be a really nice way to make ajax forms. Maybe even put it into the widget itself?

David Avellaneda → December 11th, 2009 at 2:40 pm

I’ve being trying to use this example, but, the plugin doesn’t seem to support the options: dataType and parse. Did you do another adjustment?

Trey → December 11th, 2009 at 2:50 pm

@David – No, there’s nothing fancy going on there. I don’t know why that wouldn’t work for you.

Justin → December 16th, 2009 at 8:51 pm

@Daniel, you could probably use the Media class in the form class http://docs.djangoproject.com/en/dev/topics/forms/media/

or as a widget similar to this http://www.djangosnippets.org/snippets/1097/

What do you think about that?

Elsewhere in the empire: Home, Blog, APOD