#----------------------- widgets.py------------------------
# -*- coding: utf-8 -*-
#
# In order to use this widget you need:
# 1. download YUI library and put it in
# your MEDIA folder (http://developer.yahoo.com/yui/)
# 2. Include necessary js and css imports at your page
# Check for necessary imports at 'YUI autocomplete' page
# My imports are visible at test_ajax.html
# 3. Assign a widget to field (with schema and lookup_url parameters)
# 4. Define view to do a data lookup for ajax queries
#
from django import newforms as forms
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
#AUTOCOMPLETE
AC_SNIPPET = """
"""
def_format_result = 'acAutoComp_%s.formatResult = %s;'
def_item_select_handler = 'acAutoComp_%s.itemSelectEvent.subscribe(%s);'
class AutoCompleteWidget(forms.widgets.TextInput):
""" widget autocomplete for text fields
"""
def __init__(self,
schema=None,
lookup_url=None,
format_result_fname='',
item_select_handler_fname='',
*args, **kw):
super(AutoCompleteWidget, self).__init__(*args, **kw)
# YUI schema
self.schema = schema
# url for YUI XHR Datasource
self.lookup_url = lookup_url
# optional name of javascript function that formats results (YUI)
self.format_result_fname = format_result_fname
# optional name of javascript function that handles item select event (YUI)
self.item_select_handler_fname = item_select_handler_fname
def render(self, name, value, attrs=None):
html_id = attrs.get('id', name)
# url for YUI XHR Datasource
lookup_url = self.lookup_url
# YUI schema
schema = self.schema
# optional name of javascript function that handles item select event (YUI)
item_select_handler_fname = getattr(self, 'item_select_handler_fname', '')
# optional name of javascript function that formats results (YUI)
format_result_fname = getattr(self, 'format_result_fname', '')
if value is None: value = ''
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
if value != '': final_attrs['value'] = force_unicode(value) # Only add the 'value' attribute if a value is non-empty.
final_attrs['class'] = 'autocomplete_widget'
fr = '' # format result
sh = '' # select handler
if self.format_result_fname:
fr = def_format_result % (html_id, self.format_result_fname)
if self.item_select_handler_fname:
sh = def_item_select_handler % (html_id,
self.item_select_handler_fname)
return mark_safe(AC_SNIPPET % (forms.util.flatatt(final_attrs), html_id, html_id,
lookup_url,html_id, schema, html_id, html_id,
html_id, html_id, html_id, html_id,
html_id,html_id, html_id, fr, sh))
#/AUTOCOMPLETE
#/----------------------- widgets.py------------------------
#
#EXAMPLE APPLICATION: ---------------------------------------
#
# code below is a listing of files from example application
# that uses AutocompleteWidget, you don't have to create these
# files! Only thing you need to put into your application
# is code from above: widgets.py
#----------------------- test_ajax.html -------------------
#/----------------------- test_ajax.html -------------------
#----------------------- views.py------------------------
# -*- coding: utf-8 -*-
from import JsonResponse
from django.contrib.auth.models import User
from django.template import RequestContext
import django.db.models
from django.shortcuts import render_to_response
from django import newforms as forms
from widgets import AutoCompleteWidget
def test_ajax_ac(request):
""" returns data displayed at autocomplete list - this function is accessed by AJAX calls
"""
limit = 10
query = request.GET.get('query', None)
qargs = []
# it is up to you how query looks
if query:
qargs = [django.db.models.Q(first_name__startswith=query) | \
django.db.models.Q(last_name__startswith=query) | \
django.db.models.Q(email__startswith=query)]
users = User.objects.filter(django.db.models.Q(*qargs)).order_by('first_name')[:limit]
results = []
for user in users:
results.append({'id':user.pk,
'name':user.get_full_name(),
'email':user.email})
ret_dict = {'resultset':{'totalResultsReturned':len(results),
'results':results}}
return JsonResponse(ret_dict)
class UserForm(forms.Form):
username = forms.CharField(max_length=100)
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
n_lookup_url = reverse('test_ajax_ac')
n_schema = '["resultset.results", "name", "email"]'
self.fields['username'].widget = \
AutoCompleteWidget(lookup_url = n_lookup_url,
schema = n_schema)
def test_ajax(request):
""" Displays user form
"""
user_form = UserForm()
return render_to_response('test_ajax.html',
{'user_form':user_form},
context_instance=RequestContext(request))
#/----------------------- views.py------------------------
#------------------------ urls.py-------------------------
from django.conf.urls.defaults import *
from django.conf import settings
urlpatterns = patterns('views',
url(r'^test_ajax/$', 'test_ajax', name='test_ajax'),
url(r'^test_ajax_ac/$', 'test_ajax_ac', name='test_ajax_ac'),
)
#/------------------------ urls.py-------------------------