Basic example

We’ll suppose that you use Pyramid. If not, you may have to adapt some of the instructions below.

First of all, you need to enable the widget by imperatively calling the deform_ext_autocomplete.includeme function, or by including the deform_ext_autocomplete string in the pyramid.includes directive of your Pyramid configuration file.

Extended Autocomplete uses the same arguments/attributes as Deform defaut deform.widget.AutocompleteInputWidget and an additional display_value argument/attribute which must be a callable. It must accept two arguments: the field and the cstruct (which usually corresponds to the value that is to be stored – see Colander documentation for further details). This callable should return a string that will be displayed to the user in the text input field. This callable is only used when the form has been filled, for example when redisplaying an add form that has an error, or when displaying an edit form.

There is a demo application if you want to see it in action, but here is a basic example of a schema that uses the widget:

from colander import Schema
from colander import SchemaNode
from colander import String

from deform_ext_autocomplete import ExtendedAutocompleteInputWidget

PERSONS = {
    'jhendrix': 'Jimi Hendrix',
    'jpage': 'Jimmy Page',
    'jbonham': 'John Bonham',
    'bcobham': 'Billy Cobham',
}

def display_value(field, person_id):
    return PERSONS.get(person_id, '')

class BasicSchema(Schema):
    person = SchemaNode(
        String(),
        widget=ExtendedAutocompleteInputWidget(
            display_value=display_value,
            values='/ajax_search',
        )
    )

The values argument/attribute must be either an iterable that can be converted to a JSON array, or a string representing a URL. If the latter, an XMLHTTPRequest will be sent to this URL to retrieve a JSON serialization of an iterable. In either case, each value of the iterable must be an associative array that has at least two keys: stored and displayed. Both values must be strings.

In Pyramid, here is an example of a view that would return the required iterable (supposing that the view is configured to return JSON data):

def ajax_search(request):
    term = request.GET['term'].lower()
    res = []
    for person_id, name in PERSONS.items():
        if term not in name.lower():
            continue
        res.append({'displayed': name,
                    'stored': person_id})
    return res

The widget provides additional features that are documented in the Advanced examples chapter.