= An AJAX !ComboBox Widget for Django = This widget was written to replace the standard {{{}}} dropdown simply did not scale. This widget supports live lookup of related fields based on a single field in that model and autocompletion. Credit goes to Eric Moritz's original implementation for inspiring this one. == Screenshots == The selection available after clicking the down arrow: http://code.djangoproject.com/attachment/wiki/AJAXWidgetComboBox/shot1.png Selections filtered after typing the letter b: http://code.djangoproject.com/attachment/wiki/AJAXWidgetComboBox/shot2.png == Requirements == * [http://cheeseshop.python.org/pypi/simplejson simplejson 1.3] - used for object serialization. * [http://dojotoolkit.org Dojo] - used for AJAX and widget implementation. I have been using the latest SVN trunk in my project but version 0.2.2 may work for you. * The widget tarball attached to this page. == Installation == * Install simplejson and make sure it is somewhere in your PYTHONPATH. * Install Dojo in media/js. * Untar nongcombobox-0.9.tar.gz and copy the {{{nong}}} directory into the same directory as dojo and copy the contents of {{{views.py}}} into one of your own {{{views.py}}} files. My project layout is as follows: {{{ myproject/ myapp/ models.py views.py urls.py templates/ myapp/ mymodel_form.html media/ js/ dojo/ nong/ }}} == Example Use == In this example we will create a form that uses the !ComboBox widget to for the Article's reporter field in below. === Model === Using the example model from [http://www.djangoproject.com/documentation/models/many_to_one/ Model Examples]: {{{ #!python from django.db import models class Reporter(models.Model): first_name = models.CharField(maxlength=30) last_name = models.CharField(maxlength=30) email = models.EmailField() def __str__(self): return "%s %s" % (self.first_name, self.last_name) class Article(models.Model): headline = models.CharField(maxlength=100) pub_date = models.DateField() reporter = models.ForeignKey(Reporter) def __str__(self): return self.headline }}} === URLconf === Add a url to the applications {{{urls.py}}} for the reporter_lookup view like so: {{{ #!python from myproject.myapp.models import Reporter reporter_lookup = { 'queryset': Reporter.objects.all(), 'field': 'first_name', # this is the field which is searched #'limit': 10, # default is to limit query to 10 results. Increase this if you like. #'login_required': False, # default is to allow anonymous queries. Set to True if you want authenticated access. } urlpatterns = pattern('', (r'^reporter_lookup/$', 'myproject.myapp.views.json_lookup', reporter_lookup), ) }}} Now test your new reporter_lookup view my going to {{{http://localhost:8000/reporter_lookup/?search=}}}, which should return something like: {{{ [["Reporter 1", 1], ["Reporter 2", 2], ...] }}} === Template === Normally you would have just put {{{{{ form.reporter }}}}} somewhere in your {{{article_form.html}}} template to get a drop down menu with a list of the Reporters. To use the new widget in your form you'll need to add the following to your template: {{{ ... {% block extrahead %} {% comment %} load dojo and the combobox widget {% endcomment %} {% comment %} Add the following if you use the same template for both adding and changing. This block pre-populates the new combobox widget with the current value of the article's reporter. {% endcomment %} {% if object %} {% endif %} {% endblock %} ... {% comment %} Replace the usual {{ form.reporter }} element in the template with this: {% endcomment %} ... }}} That's it! You should be able to submit this form just like you normally would.