# HG changeset patch # User Thierry Florac # Date 1568714201 -7200 # Node ID ddd454de3d32c532282156f492f6d2ec6b728c7f # Parent 8030eca2abf3eb8876b293189c984870f154c287 Added widget to display JSON dict diff -r 8030eca2abf3 -r ddd454de3d32 src/pyams_form/interfaces/form.py --- 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 diff -r 8030eca2abf3 -r ddd454de3d32 src/pyams_form/widget/__init__.py --- 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 # diff -r 8030eca2abf3 -r ddd454de3d32 src/pyams_form/widget/templates/json-dict-display.pt --- /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 @@ +
+
+ ${label} (${key}) +
${value}
+
+
\ No newline at end of file