Login

Newforms Autocomplete Widget with Scriptaculous

Author:
eopadoan
Posted:
May 25, 2007
Language:
Python
Version:
.96
Score:
7 (after 7 ratings)

From here with litle improvements. More about Script.aculo.us and Django

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.http import HttpResponse

from django import newforms as forms
from django.newforms.widgets import TextInput,flatatt
from django.newforms.util import smart_unicode

from django.utils.html import escape

class AutoCompleteField(TextInput):
	def __init__(self, url='', options='{paramName: "text"}', attrs=None):
		self.url = url
		self.options = options
                if attrs is None:
                    attrs = {}
                self.attrs = attrs

	def render(self, name, value=None, attrs=None):
		final_attrs = self.build_attrs(attrs, name=name)
		if value:
			value = smart_unicode(value)
			final_attrs['value'] = escape(value)
		if not self.attrs.has_key('id'):
                    final_attrs['id'] = 'id_%s' % name
		return (u'<input type="text" name="%(name)s" id="%(id)s"/> <div class="autocomplete" id="box_%(name)s"></div>'
                        '<script type="text/javascript">'
                        'new Ajax.Autocompleter(\'%(id)s\', \'box_%(name)s\', \'%(url)s\', %(options)s);'
                        '</script>') % {'attrs'	: flatatt(final_attrs),
                                        'name'	: name,
                                        'id'	: final_attrs['id'],
                                        'url'	: self.url,
                                        'options' : self.options}


#
#  Usage example
#

class TestForm(forms.Form):
    person = forms.CharField(required=False,
                             widget=AutoCompleteField(url='/autocomplete/'))

def test_view(request):
    return render_to_response('test_template.html', {'form': TestForm()},
                              context_instance=RequestContext(request))

def autocomplete(request):
    """ Return a simple response with a <ul>
    """
    if request.method == 'POST':
        text = request['text']
    # Search things on the database with 'text'
    # Or simply perform any computing with this
    # to generate a <ul>
    # But this is not important here.
    return HttpResponse(
        '''
        <ul>
           <li>ACME Inc <span class="informal"> 5012 East 5th Street</span></li>
           <li>Scriptaculous <span class="informal"> 1066 West Redlands Parkway</span></li>
           <li>Test00001</li>
           <li>Test00001</li>
           <li>Another Silly test</li>
           <li>%s</li>

        </ul>'''%text) # put the text in the end of the example list to see if this works

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

cahenan (on June 5, 2007):

very useful, tks! ;)

#

bbolli (on July 5, 2007):

To make this snippet work in my app, I had to replace the %(id)s in the big return statement with %(attrs)s. attrs wasn't used anywhere else, so I think this makes sense.

#

charliesl (on September 28, 2007):

I've modified a little the script, so the value if instancited isnt lost in the path:

return (u'<input type="text" name="%(name)s" id="%(id)s" value="%(value)s"/> <div class="autocomplete" id="box_%(name)s"></div>' '<script type="text/javascript">' 'new Ajax.Autocompleter(\'%(id)s\', \'box_%(name)s\', \'%(url)s\', %(options)s);' '</script>') % {'attrs': flatatt(final_attrs), 'name': name, 'id': final_attrs['id'], 'url': self.url, 'value': value, 'options' : self.options}

Basically, I've added value="%(value)s" in the html input and the corresponding param 'value': value, in the dictionary.

Great snippet, BTW

-charlie-

#

ogw (on January 10, 2009):

I added the following method to AutoCompleteField, so that when this field is required and left empty, it does not validate:

def value_from_datadict(self, data, files, name):
    val = data.get(name, None)
    if val=="-1":
        val = None
    return val

#

Please login first before commenting.