--- a/src/pyams_form/widget/__init__.py Fri Jul 13 12:22:22 2018 +0200
+++ b/src/pyams_form/widget/__init__.py Tue Jul 17 18:02:48 2018 +0200
@@ -25,12 +25,13 @@
IColorWidget, IHTMLWidget, ISelect2Widget, ITextLineListWidget, ISEOTextLineWidget, IActionWidget
from pyams_form.schema import IResetButton, ICloseButton, IActionButton
from pyams_skin.interfaces.tinymce import ITinyMCEConfiguration
+from pyams_utils.interfaces.data import IObjectData
from pyams_utils.schema import IColorField, IHTMLField, ITextLineListField
from pyramid.interfaces import IRequest
from z3c.form.interfaces import INPUT_MODE, DISPLAY_MODE, IFieldWidget, IButtonAction, IWidgetLayoutTemplate, \
- IDataConverter
+ IDataConverter, NO_VALUE
from zope.pagetemplate.interfaces import IPageTemplate
-from zope.schema.interfaces import IDate, IDatetime, ITime, IChoice
+from zope.schema.interfaces import IDate, IDatetime, ITime, IChoice, IList, ITuple, ISet
# import packages
from pyams_utils.adapter import adapter_config
@@ -45,7 +46,7 @@
from z3c.form.button import ButtonAction
from z3c.form.converter import BaseDataConverter, DatetimeDataConverter as BaseDatetimeDataConverter
from z3c.form.widget import FieldWidget, WidgetTemplateFactory, WidgetLayoutFactory
-from zope.interface import implementer_only, directlyProvides, Interface
+from zope.interface import implementer, implementer_only, directlyProvides, Interface
from zope.schema.fieldproperty import FieldProperty
from pyams_form import _
@@ -389,6 +390,60 @@
return FieldWidget(field, Select2Widget(request))
+@widgettemplate_config(mode=INPUT_MODE, template='templates/hidden-select-input.pt', layer=IFormLayer)
+@implementer(IObjectData)
+class HiddenSelect2Widget(Select2Widget):
+ """Hidden select2 widget
+
+ Widget values are provided through IObjectData
+ """
+
+ def extract(self, default=NO_VALUE):
+ if self.name not in self.request and self.name + '-empty-marker' in self.request:
+ return []
+ value = self.request.get(self.name, default)
+ if value != default:
+ if not isinstance(value, (set, tuple, list)):
+ value = set(value.split('|'))
+ # do some kind of validation, at least only use existing values
+ for token in value:
+ if token == self.noValueToken:
+ continue
+ try:
+ self.terms.getTermByToken(token)
+ except LookupError:
+ return default
+ return value
+
+ @property
+ def values(self):
+ return '|'.join(self.value or '')
+
+ @property
+ def values_map(self):
+ result = {}
+ terms = self.terms
+ [result.update({value: terms.getTermByToken(value).title}) for value in self.value or ()]
+ return json.dumps(result)
+
+
+def HiddenSelect2FieldWidget(field, request):
+ return FieldWidget(field, HiddenSelect2Widget(request))
+
+
+@adapter_config(context=(IList, HiddenSelect2Widget), provides=IDataConverter)
+@adapter_config(context=(ITuple, HiddenSelect2Widget), provides=IDataConverter)
+@adapter_config(context=(ISet, HiddenSelect2Widget), provides=IDataConverter)
+class HiddenSelect2DataConverter(BaseDataConverter):
+ """Hidden select2 data converter"""
+
+ def toWidgetValue(self, value):
+ return value or ()
+
+ def toFieldValue(self, value):
+ return set(value or ())
+
+
#
# TextLineList widget
#