Advanced examples¶
Showing yet another value in the dropdown¶
An optional third key can be added to the associative array in the
values
argument/attribute of the widget: dropdown
. This value
is displayed in the dropdown menu that may appear when the user starts
typing letters in the autocomplete text input field.
In the example shown in the Basic example chapter, we show the persons’
name in the dropdown that appears when the user starts typing letters.
We could highlight typed letters in the names. To do so, we provide an
additional dropdown
key in each item of values
. The
ajax_search
view would then look like this:
def highlight_term(term, name):
"""Return an HTML representation of ``name`` where ``term`` is
displayed in bold characters.
"""
# This is a very naive implementation.
return name.replace(term, '<strong>%s</strong>' % term)
def ajax_search(request):
term = request.GET['term'].lower()
res = []
for person_id, name in PERSONS.items():
if term not in name.lower():
continue
dropdown = highlight_term(term, name)
res.append({'displayed': name,
'dropdown': dropdown,
'stored': person_id})
return res
You may note that the displayed
key is left untouched. It should
not be the same as the dropdown
key, as the latter contains HTML
tags, which should not be used for the displayed
key.
An advanced display_value
callable¶
As with any widget in Deform, it is possible to bind the field it is attached to, so that the field and/or the widget have access to additional bindings, such as the request.
Here, we will suppose that the persons are stored in a database and
that we can query it through the db
attribute of the request. The
problem is then to access the request from the display_value
callable. To do that, we will define a deferred function:
import colander
@colander.deferred
def deferred_autocomplete_widget(node, kw):
"""Return an instance of ``ExtendedAutocompleteInputWidget``
where the ``display_value`` callable has access to the database
connection through the request.
"""
request = kw['request']
def display_value(field, cstruct):
return request.db.find(person_id=cstruct)
return ExtendedAutocompleteInputWidget(values='/ajax_search',
display_value=display_value)
class AdvancedSchema(Schema):
person = SchemaNode(String(),
widget=deferred_autocomplete_widget)
def make_form(request):
schema = AdvancedSchema().bind(request=request)
return Form(schema)
Again, this is not specific to the Extended Autocomplete widget. This is a pure Colander feature. For further details, see the Colander documentation.