--- a/src/pyams_form/interfaces/form.py Tue Sep 17 11:55:32 2019 +0200
+++ b/src/pyams_form/interfaces/form.py Tue Sep 17 11:56:41 2019 +0200
@@ -10,26 +10,23 @@
# FOR A PARTICULAR PURPOSE.
#
-__docformat__ = 'restructuredtext'
+from pyramid.interfaces import IView
+from z3c.form import button
+from z3c.form.interfaces import IButtonWidget, IFormLayer as IBaseFormLayer, INPUT_MODE, \
+ ISelectWidget, ISubForm, ISubmitWidget, ITextAreaWidget, ITextWidget, IWidget
+from zope.interface import Attribute, Interface, implementer
+from zope.interface.interfaces import IObjectEvent, ObjectEvent
+from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
+from zope.lifecycleevent.interfaces import IObjectCreatedEvent, IObjectModifiedEvent
+from zope.schema import Bool, Choice, Dict, Int, List, Object, Text, TextLine
-# import standard library
-
-# import interfaces
+from pyams_form.schema import CloseButton, ResetButton
+from pyams_template.template import template_config
from pyams_utils.interfaces import MANAGE_PERMISSION
from pyams_viewlet.interfaces import IViewletManager
-from pyramid.interfaces import IView
-from z3c.form.interfaces import INPUT_MODE, ISubForm, IWidget, IFormLayer as IBaseFormLayer, ISubmitWidget, \
- ITextWidget, ITextAreaWidget, ISelectWidget, IButtonWidget
-from zope.interface.interfaces import IObjectEvent, ObjectEvent
-from zope.lifecycleevent.interfaces import IObjectCreatedEvent, IObjectModifiedEvent
+
-# import packages
-from pyams_form.schema import ResetButton, CloseButton
-from pyams_template.template import template_config
-from z3c.form import button
-from zope.interface import implementer, Interface, Attribute
-from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
-from zope.schema import Text, TextLine, List, Object, Bool, Int, Choice, Dict
+__docformat__ = 'restructuredtext'
from pyams_form import _
@@ -582,6 +579,10 @@
"""HTML editor widget interface"""
+class IJSONDictWidget(IWidget):
+ """JSON dict widget interface"""
+
+
class ISelect2Widget(ISelectWidget):
"""New select2 based widget"""
@@ -625,7 +626,7 @@
"""Form object created event"""
def __init__(self, object, form):
- self.object = object
+ super(FormObjectCreatedEvent, self).__init__(object)
self.form = form
--- a/src/pyams_form/widget/__init__.py Tue Sep 17 11:55:32 2019 +0200
+++ b/src/pyams_form/widget/__init__.py Tue Sep 17 11:56:41 2019 +0200
@@ -24,26 +24,29 @@
from z3c.form.browser.submit import SubmitWidget
from z3c.form.browser.text import TextWidget
from z3c.form.browser.textarea import TextAreaWidget
+from z3c.form.browser.widget import HTMLInputWidget
from z3c.form.button import ButtonAction
-from z3c.form.converter import BaseDataConverter, DatetimeDataConverter as BaseDatetimeDataConverter, \
- FormatterValidationError
-from z3c.form.interfaces import DISPLAY_MODE, IButtonAction, IDataConverter, IFieldWidget, INPUT_MODE, ITextAreaWidget, \
- IWidgetLayoutTemplate, NO_VALUE
-from z3c.form.widget import FieldWidget, WidgetLayoutFactory, WidgetTemplateFactory
+from z3c.form.converter import BaseDataConverter, \
+ DatetimeDataConverter as BaseDatetimeDataConverter, FormatterValidationError
+from z3c.form.interfaces import DISPLAY_MODE, IButtonAction, IDataConverter, IFieldWidget, \
+ INPUT_MODE, ITextAreaWidget, IWidgetLayoutTemplate, NO_VALUE
+from z3c.form.widget import FieldWidget, Widget, WidgetLayoutFactory, WidgetTemplateFactory
from zope.component import getGlobalSiteManager
from zope.interface import Interface, directlyProvides, implementer, implementer_only
from zope.pagetemplate.interfaces import IPageTemplate
from zope.schema.fieldproperty import FieldProperty
-from zope.schema.interfaces import IBytes, IChoice, IDate, IDatetime, IFloat, IInt, IList, ISet, ITime, ITuple
+from zope.schema.interfaces import IBytes, IChoice, IDate, IDatetime, IFloat, IInt, IList, ISet, \
+ ITime, ITuple
-from pyams_form.interfaces.form import IActionWidget, ICloseWidget, IColorWidget, IDateWidget, IDatetimeWidget, \
- IFloatWidget, IFormLayer, IHTMLWidget, IIntegerWidget, IResetWidget, ISEOTextLineWidget, ISelect2Widget, \
- ITextLineListWidget, ITimeWidget
+from pyams_form.interfaces.form import IActionWidget, ICloseWidget, IColorWidget, IDateWidget, \
+ IDatetimeWidget, IFloatWidget, IFormLayer, IHTMLWidget, IIntegerWidget, IJSONDictWidget, \
+ IResetWidget, ISEOTextLineWidget, ISelect2Widget, ITextLineListWidget, ITimeWidget
from pyams_form.schema import IActionButton, ICloseButton, IResetButton
from pyams_skin.interfaces.tinymce import ITinyMCEConfiguration
from pyams_utils.adapter import adapter_config
from pyams_utils.interfaces.data import IObjectData
-from pyams_utils.schema import IColorField, IHTMLField, ITextLineListField
+from pyams_utils.schema import IColorField, IHTMLField, IJSONDictField, ITextLineListField, \
+ IJSONDictFieldsGetter
from pyams_utils.timezone import localgmtime, tztime
@@ -110,7 +113,7 @@
This function can be used to override a widget template without using ZCML.
Settings are the same as for @widgettemplate_config decorator.
"""
- stack = inspect.stack()[-1]
+ stack = inspect.stack()[1]
template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(stack[0]))),
settings.get('template'))
if not os.path.isfile(template):
@@ -184,7 +187,7 @@
This function can be used to override a widget layout template without using ZCML.
Settings are the same as for @widgetlayout_config decorator.
"""
- stack = inspect.stack()[-1]
+ stack = inspect.stack()[1]
template = os.path.join(os.path.dirname(inspect.getfile(inspect.getmodule(stack[0]))),
settings.get('template'))
if not os.path.isfile(template):
@@ -548,6 +551,42 @@
#
+# JSON dict widget
+#
+
+@adapter_config(context=(IJSONDictField, IJSONDictWidget), provides=IDataConverter)
+class JSONDictDataConverter(BaseDataConverter):
+ """JSON dict data converter"""
+
+ def toWidgetValue(self, value):
+ return value
+
+ def toFieldValue(self, value):
+ return json.loads(value)
+
+
+@widgettemplate_config(mode='display', template='templates/json-dict-display.pt', layer=IFormLayer)
+@implementer_only(IJSONDictWidget)
+class JSONDictWidget(HTMLInputWidget, Widget):
+ """JSON dict field widget"""
+
+ def get_fields(self):
+ form = self.__parent__.form
+ getter = self.request.registry.queryMultiAdapter((form.getContent(), self.request, form),
+ IJSONDictFieldsGetter)
+ if getter is not None:
+ yield from getter.get_fields(self.value)
+ else:
+ yield from map(lambda item: (item[0], item[0], item[1]), self.value.items())
+
+
+@adapter_config(context=(IJSONDictField, IFormLayer), provides=IFieldWidget)
+def JSONDictFieldWidget(field, request):
+ """JSON dict field widget factory"""
+ return FieldWidget(field, JSONDictWidget(request))
+
+
+#
# Select2 widget
#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/json-dict-display.pt Tue Sep 17 11:56:41 2019 +0200
@@ -0,0 +1,6 @@
+<div class="padding-5">
+ <div tal:repeat="(key,label,value) python:view.get_fields()">
+ <strong>${label} (${key})</strong>
+ <div class="padding-left-5">${value}</div>
+ </div>
+</div>
\ No newline at end of file