UberSelectionWidget
===================
First we need to prepare some things. For this we need some imports.
>>> from zope.browser.interfaces import ITerms
>>> from zope.component import provideAdapter, adapts
>>> from zope.interface import Interface, implements
>>> from zope.schema import Choice, List
>>> from zope.schema.interfaces import IIterableSource
>>> from plone.app.vocabularies.catalog import SearchableTextSource
>>> from zope.publisher.interfaces.browser import IBrowserRequest
>>> from zope.schema.vocabulary import SimpleTerm
The source itself.
>>> class SourceList(list):
... implements(IIterableSource)
An adapter to ITerms.
>>> class ListTerms(object):
...
... implements(ITerms)
...
... def __init__(self, source, request):
... pass # We don't actually need the source or the request :)
...
... def getTerm(self, value):
... title = unicode(value)
... try:
... token = title.encode('base64').strip()
... except binascii.Error:
... raise LookupError(token)
... return SimpleTerm(value, token=token, title=title)
...
... def getValue(self, token):
... return token.decode('base64')
>>> provideAdapter(
... ListTerms,
... (SourceList, IBrowserRequest))
An adapter to ISourceQueryView to make the source searchable.
>>> from zope.formlib.interfaces import ISourceQueryView
>>> class ListQueryView:
...
... implements(ISourceQueryView)
... adapts(
... SourceList,
... IBrowserRequest,
... )
...
... def __init__(self, source, request):
... self.source = source
... self.request = request
...
... def render(self, name):
... return (
... '\n'
... ''
... % (name, name)
... )
...
... def results(self, name):
... if name+".search" in self.request:
... search_string = self.request.get(name+'.query')
... if search_string is not None:
... return [value
... for value in self.source
... if search_string in value
... ]
... return None
>>> provideAdapter(ListQueryView)
Then we can start to test the widget.
>>> from zope.publisher.browser import TestRequest
>>> from plone.app.form.widgets.uberselectionwidget import UberSelectionWidget, UberMultiSelectionWidget
>>> from xml.dom.minidom import parseString
We need a request.
>>> request = TestRequest()
A choice field with the source.
>>> selection = Choice(__name__='selection',
... title=u'Single select',
... source=SourceList(['spot', 'bowser', 'prince', 'duchess', 'lassie']))
And the widget itself.
>>> widget = UberSelectionWidget(selection, request)
Now we can render the widget and inspect it.
>>> dom = parseString(widget())
>>> inputs = dom.getElementsByTagName('input')
>>> inputs[0].getAttributeNode('name').value
u'field.selection.query'
>>> inputs[1].getAttributeNode('name').value
u'field.selection.search'
>>> dom.unlink()
Now we want to make a query and see whether we get selectable results.
>>> request.form['field.selection.query'] = u'o'
>>> request.form['field.selection.search'] = u'Search'
>>> dom = parseString(widget())
>>> inputs = [x for x in dom.getElementsByTagName('input')
... if u'type="radio"' in x.toxml()]
>>> len(inputs)
2
>>> u'c3BvdA==' in inputs[0].toxml()
True
>>> u'spot' in inputs[0].nextSibling.nextSibling.toxml()
True
>>> u'Ym93c2Vy' in inputs[1].toxml()
True
>>> u'bowser' in inputs[1].nextSibling.nextSibling.toxml()
True
>>> dom.unlink()
Test multiselection
>>> from zope.schema import List
>>> selection = List(__name__='selection',
... title=u'Multi select',
... value_type=Choice(
... source = SourceList(['spot', 'bowser', 'prince', 'duchess', 'lassie']))
... )
And the widget itself.
>>> widget = UberMultiSelectionWidget(selection, request)
Widget value should always be list
>>> widget._value()
[]
>>> widget._getRenderValue()
[]
Fine, so far everything works!