[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form - widget.py:1.29.4.5
Fred L. Drake, Jr.
fred@zope.com
Mon, 5 May 2003 16:11:32 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/form
In directory cvs.zope.org:/tmp/cvs-serv21443
Modified Files:
Tag: schema-vocabulary-branch
widget.py
Log Message:
- add a basic multi-selection widget for vocabularies
- various minor refactorings to support this
=== Zope3/src/zope/app/browser/form/widget.py 1.29.4.4 => 1.29.4.5 ===
--- Zope3/src/zope/app/browser/form/widget.py:1.29.4.4 Mon May 5 15:11:04 2003
+++ Zope3/src/zope/app/browser/form/widget.py Mon May 5 16:11:32 2003
@@ -769,40 +769,16 @@
return self.textForValue(term)
-class VocabularyEditWidget(VocabularyWidgetBase):
- """Single single-selection edit widget.
-
- This widget can be used when the number of selections isn't going
- to be very large.
- """
- __implements__ = SingleItemsWidget.__implements__
- propertyNames = (SingleItemsWidget.propertyNames +
- ['firstItem', 'size', 'extra']
- )
+class VocabularyEditWidgetBase(VocabularyWidgetBase):
+ propertyNames = (VocabularyWidgetBase.propertyNames
+ + ['extra', 'size', 'tag'])
extra = ''
- firstItem = False
size = 5
tag = 'select'
- def render(self, value):
- rendered_items = self.renderItems(value)
- return renderElement(self.getValue('tag'),
- type = self.getValue('type'),
- name = self.name,
- id = self.name,
- cssClass = self.getValue('cssClass'),
- size = self.getValue('size'),
- contents = "\n".join(rendered_items),
- extra = self.getValue('extra'))
-
- def renderItems(self, value):
- vocabulary = self.context
-
- # check if we want to select first item
- if (value == self._missing
- and getattr(self.context, 'firstItem', False)
- and len(vocabulary) > 0):
- value = iter(vocabulary).next().value
+ def renderItemsWithValues(self, values):
+ """Render the list of possible values, with those found in
+ 'values' being marked as selected."""
cssClass = self.getValue('cssClass')
@@ -810,11 +786,11 @@
# vocabulary, so that need not be considered here
rendered_items = []
count = 0
- for term in vocabulary:
+ for term in self.context:
item_value = term.value
item_text = self.textForValue(term)
- if item_value == value:
+ if item_value in values:
rendered_item = self.renderSelectedItem(count,
item_text,
item_value,
@@ -839,6 +815,70 @@
def renderSelectedItem(self, index, text, value, name, cssClass):
return renderElement('option', contents=text, value=value,
cssClass=cssClass, selected=None)
+
+
+class VocabularyEditWidget(VocabularyEditWidgetBase):
+ """Vocabulary-backed single-selection edit widget.
+
+ This widget can be used when the number of selections isn't going
+ to be very large.
+ """
+ __implements__ = SingleItemsWidget.__implements__
+ propertyNames = (VocabularyEditWidgetBase.propertyNames
+ + ['firstItem'])
+ firstItem = False
+
+ def render(self, value):
+ rendered_items = self.renderItems(value)
+ return renderElement(self.getValue('tag'),
+ type = self.getValue('type'),
+ name = self.name,
+ id = self.name,
+ cssClass = self.getValue('cssClass'),
+ size = self.getValue('size'),
+ contents = "\n".join(rendered_items),
+ extra = self.getValue('extra'))
+
+ def renderItems(self, value):
+ vocabulary = self.context
+
+ # check if we want to select first item
+ if (value == self._missing
+ and getattr(self.context, 'firstItem', False)
+ and len(vocabulary) > 0):
+ # Grab the first item from the iterator:
+ values = [iter(vocabulary).next().value]
+ elif value != self._missing:
+ values = [value]
+ else:
+ values = ()
+
+ return VocabularyEditWidgetBase.renderItemsWithValues(self, values)
+
+
+class VocabularyMultiEditWidget(VocabularyEditWidgetBase):
+ """Vocabulary-backed widget supporting multiple selections."""
+
+ def renderItems(self, value):
+ if value == self._missing:
+ values = ()
+ else:
+ values = list(value)
+ return VocabularyEditWidgetBase.renderItemsWithValues(self, values)
+
+ def render(self, value):
+ # All we really add here is the ':list' in the name argument
+ # to renderElement().
+ rendered_items = self.renderItems(value)
+ return renderElement(self.getValue('tag'),
+ type = self.getValue('type'),
+ name = self.name + ':list',
+ multiple = None,
+ id = self.name,
+ cssClass = self.getValue('cssClass'),
+ size = self.getValue('size'),
+ contents = "\n".join(rendered_items),
+ extra = self.getValue('extra'))
# XXX Note, some HTML quoting is needed in renderTag and renderElement.