= An AJAX Select 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: [[Image(shot1.png)]] Selections filtered after typing the letter b: [[Image(shot2.png)]] == Requirements == * [http://dojotoolkit.org Dojo 0.3.1] - used for AJAX and widget implementation. * The [http://code.djangoproject.com/attachment/wiki/AJAXWidgetComboBox/nongselect-1.0.tar.gz NongSelect 1.0 widget tarball] attached to this page. == Installation == * Install Dojo in media/js. * Untar nongselect-1.0.tar.gz and copy the {{{nong}}} directory into the same parent 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 templatetags/ formtags.py templates/ myapp/ mymodel_form.html widget/ fieldrow.html selectrow.html media/ js/ dojo/ nong/ }}} == Example Use == In this example we will create a form that uses the Select 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 = patterns('', (r'^reporter_lookup/$', 'myproject.myapp.views.json_lookup', reporter_lookup), ) }}} Now test your new reporter_lookup view my going to {{{http://localhost:8000/myapp/reporter_lookup/?q=}}}, 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 javascript and templatetags to your template: {{{ ... {% load formtags %} {% block extrahead %} {% comment %} load dojo and the select widget {% endcomment %} {% endblock %} ... {% comment %} Two templatetags are included for your convenience. The first, {% fieldrow ... %} splits out a form element similar in style to the Django Admin with the field's help_text displayed. The second, {% selectrow ... %}, splits out all the markup and javascript necessary for the AJAX select widget. Replace the usual {{ form.reporter }} element in the template with this: {% endcomment %} {% fieldrow form.headline %} {% fieldrow form.pub_date %} {% selectrow form.reporter "/myapp/reporter_lookup/?q=%{searchString}" "first_name" %} ... }}} That's it! You should be able to submit this form just like you normally would. Matthew Flanagan (mattimustang A T gmail.com).