--- a/src/pyams_form/interfaces/form.py Tue Sep 08 17:14:58 2015 +0200
+++ b/src/pyams_form/interfaces/form.py Thu Oct 08 09:14:52 2015 +0200
@@ -15,10 +15,11 @@
# import standard library
# import interfaces
+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
+ ITextWidget, ITextAreaWidget, ISelectWidget
from zope.interface.interfaces import IObjectEvent, ObjectEvent
from zope.lifecycleevent.interfaces import IObjectCreatedEvent, IObjectModifiedEvent
@@ -28,7 +29,7 @@
from z3c.form import button
from zope.interface import implementer, Interface, Attribute
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
-from zope.schema import TextLine, List, Object, Bool, Choice, Dict
+from zope.schema import Text, TextLine, List, Object, Bool, Int, Choice, Dict
from pyams_form import _
@@ -71,7 +72,7 @@
edit_permission = TextLine(title="Required edit permission",
required=False,
- default='manage')
+ default=MANAGE_PERMISSION)
def get_skin(self):
"""Get skin associated with this form"""
@@ -301,6 +302,8 @@
tab_label = TextLine(title="Tab label")
+ tab_target = Attribute("View name of tab content target")
+
class IViewletSubForm(ISubForm):
"""Inner viewlet form interface"""
@@ -344,10 +347,37 @@
# Form viewlets
#
+class IFormHelp(Interface):
+ """Form help interface"""
+
+ permission = TextLine(title='Required permission',
+ required=False)
+
+ mode = TextLine(title='Required mode',
+ required=False)
+
+ outer_margin = Int(title='Outer margin size',
+ default=0)
+
+ status = TextLine(title='Help status',
+ default='info')
+
+ header = TextLine(title='Help header')
+
+ message = Text(title='Help message')
+
+ message_format = Choice(title='Help message format',
+ vocabulary='PyAMS HTML renderers')
+
+
class IFormViewletsManager(IViewletManager):
"""Base forms viewlets manager interface"""
+class IFormHeaderViewletsManager(IFormViewletsManager):
+ """Form header viewlets manager interface"""
+
+
class IFormPrefixViewletsManager(IFormViewletsManager):
"""Form prefix viewlets manager interface"""
@@ -393,7 +423,7 @@
class IModalAddFormButtons(Interface):
"""Modal add form buttons"""
- close = CloseButton(name='close', title=_("Close"))
+ close = CloseButton(name='close', title=_("Cancel"))
add = button.Button(name='add', title=_("Add"), condition=check_submit_button)
@@ -407,7 +437,7 @@
class IModalEditFormButtons(Interface):
"""Modal edit form buttons"""
- close = CloseButton(name='close', title=_("Close"))
+ close = CloseButton(name='close', title=_("Cancel"))
submit = button.Button(name='submit', title=_("Submit"), condition=check_submit_button)
@@ -449,6 +479,14 @@
"""HTML editor widget interface"""
+class ISelect2Widget(ISelectWidget):
+ """New select2 based widget"""
+
+
+class ITextLineListWidget(ITextWidget):
+ """Text line list widget"""
+
+
#
# Form events
#
--- a/src/pyams_form/widget/__init__.py Tue Sep 08 17:14:58 2015 +0200
+++ b/src/pyams_form/widget/__init__.py Thu Oct 08 09:14:52 2015 +0200
@@ -21,27 +21,31 @@
# import interfaces
from pyams_form.interfaces.form import IFormLayer, IResetWidget, ICloseWidget, IDateWidget, IDatetimeWidget, ITimeWidget, \
- IColorWidget, IHTMLWidget
+ IColorWidget, IHTMLWidget, ISelect2Widget, ITextLineListWidget
from pyams_form.schema import IResetButton, ICloseButton
from pyams_skin.interfaces.tinymce import ITinyMCEConfiguration
-from pyams_utils.schema import IColorField, IHTMLField
+from pyams_utils.schema import IColorField, IHTMLField, ITextLineListField
from pyramid.interfaces import IRequest
from z3c.form.interfaces import INPUT_MODE, IFieldWidget, IButtonAction, IWidgetLayoutTemplate, IDataConverter
from zope.pagetemplate.interfaces import IPageTemplate
-from zope.schema.interfaces import IDate, IDatetime, ITime
+from zope.schema.interfaces import IDate, IDatetime, ITime, IChoice
# import packages
from pyams_utils.adapter import adapter_config
+from pyams_utils.timezone import tztime, gmtime, localgmtime
from pyramid.exceptions import ConfigurationError
from z3c.form.action import Action
+from z3c.form.browser.select import SelectWidget
from z3c.form.browser.submit import SubmitWidget
from z3c.form.browser.text import TextWidget
from z3c.form.browser.textarea import TextAreaWidget
from z3c.form.button import ButtonAction
-from z3c.form.converter import BaseDataConverter
+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 pyams_form import _
+
#
# Widget template configuration
@@ -224,6 +228,19 @@
# Datetime widget
#
+@adapter_config(context=(IDatetime, IDatetimeWidget), provides=IDataConverter)
+class DatetimeDataConverter(BaseDatetimeDataConverter):
+ """Datetime field data converter"""
+
+ def toWidgetValue(self, value):
+ value = tztime(value)
+ return super(DatetimeDataConverter, self).toWidgetValue(value)
+
+ def toFieldValue(self, value):
+ value = super(DatetimeDataConverter, self).toFieldValue(value)
+ return localgmtime(value)
+
+
@widgettemplate_config(mode='input', template='templates/datetime-input.pt', layer=IFormLayer)
@implementer_only(IDatetimeWidget)
class DatetimeWidget(TextWidget):
@@ -310,3 +327,54 @@
def HTMLFieldWidget(field, request):
return FieldWidget(field, HTMLWidget(request))
+
+#
+# Select2 widget
+#
+
+@widgettemplate_config(mode='input', template='templates/select-input.pt', layer=IFormLayer)
+@implementer_only(ISelect2Widget)
+class Select2Widget(SelectWidget):
+ """Select2 widget"""
+
+ noValueMessage = _("(no selected value)")
+
+ def get_content(self, entry):
+ translate = self.request.localizer.translate
+ return translate(entry['content'])
+
+
+@adapter_config(context=(IChoice, IFormLayer), provides=IFieldWidget)
+def ChoiceFieldWidget(field, request):
+ return FieldWidget(field, Select2Widget(request))
+
+
+#
+# TextLineList widget
+#
+
+@adapter_config(context=(ITextLineListField, ITextLineListWidget), provides=IDataConverter)
+class TextLineListFieldDataConverter(BaseDataConverter):
+ """Text line list field data converter"""
+
+ def toWidgetValue(self, value):
+ return '|'.join(value or [])
+
+ def toFieldValue(self, value):
+ return value.split('|') if value else None
+
+
+@widgettemplate_config(mode='input', template='templates/textlinelist-input.pt', layer=IFormLayer)
+@widgettemplate_config(mode='display', template='templates/textlinelist-display.pt', layer=IFormLayer)
+@implementer_only(ITextLineListWidget)
+class TextLineListWidget(TextWidget):
+ """Text line list widget"""
+
+ @property
+ def tags(self):
+ return json.dumps((self.value or '').split('|'))
+
+
+@adapter_config(context=(ITextLineListField, IFormLayer), provides=IFieldWidget)
+def TextLineListFieldWidget(field, request):
+ return FieldWidget(field, TextLineListWidget(request))
--- a/src/pyams_form/widget/configure.zcml Tue Sep 08 17:14:58 2015 +0200
+++ b/src/pyams_form/widget/configure.zcml Thu Oct 08 09:14:52 2015 +0200
@@ -68,14 +68,14 @@
<z3c:widgetTemplate
mode="input"
+ template="templates/select-input.pt"
widget="z3c.form.interfaces.ISelectWidget"
- layer="pyams_form.interfaces.form.IFormLayer"
- template="templates/select-input.pt" />
+ layer="pyams_form.interfaces.form.IFormLayer" />
<z3c:widgetTemplate
mode="input"
+ template="templates/orderedselect-input.pt"
widget="z3c.form.interfaces.IOrderedSelectWidget"
- layer="pyams_form.interfaces.form.IFormLayer"
- template="templates/orderedselect-input.pt" />
+ layer="pyams_form.interfaces.form.IFormLayer" />
</configure>
--- a/src/pyams_form/widget/templates/orderedselect-input.pt Tue Sep 08 17:14:58 2015 +0200
+++ b/src/pyams_form/widget/templates/orderedselect-input.pt Thu Oct 08 09:14:52 2015 +0200
@@ -3,6 +3,7 @@
<i class="icon-append fa fa-trash-o hint opaque"
title="Clear selected values" i18n:attributes="title"
tal:omit-tag="view/required"
+ data-ams-hint-gravity="se"
data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
tal:attributes="data-ams-select2-target string:${view/name}:list"></i>
<div class="select2-parent"
--- a/src/pyams_form/widget/templates/select-input.pt Tue Sep 08 17:14:58 2015 +0200
+++ b/src/pyams_form/widget/templates/select-input.pt Thu Oct 08 09:14:52 2015 +0200
@@ -25,5 +25,5 @@
<option tal:repeat="entry view/items"
tal:attributes="value entry/value;
selected python:entry['value'] in view.value;"
- tal:content="entry/content"></option>
+ tal:content="python:view.get_content(entry) if hasattr(view, 'get_content') else entry['content']"></option>
</select>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/textlinelist-display.pt Thu Oct 08 09:14:52 2015 +0200
@@ -0,0 +1,34 @@
+<input type="hidden" readonly="readonly"
+ class="select2"
+ multiple="multiple"
+ tal:attributes="id view/id;
+ name string:${view/name};
+ class string:${view/klass} select2;
+ style view/style;
+ title view/title;
+ value view/value;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ size view/size;
+ data-ams-select2-tags view/tags;"
+ data-ams-select2-multiple="true"
+ data-ams-select2-minimum-input-length="3"
+ data-ams-select2-enable-free-tags="true"
+ data-ams-select2-separator="|"
+ data-ams-select2-tokens-separators="|"
+ data-ams-select2-values='{}'>
+</input>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/textlinelist-input.pt Thu Oct 08 09:14:52 2015 +0200
@@ -0,0 +1,37 @@
+<input type="hidden"
+ class="select2"
+ multiple="multiple"
+ tal:attributes="id view/id;
+ name string:${view/name};
+ class string:${view/klass} select2;
+ style view/style;
+ title view/title;
+ value view/value;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ size view/size;
+ data-ams-select2-tags view/tags;"
+ data-ams-select2-multiple="true"
+ data-ams-select2-minimum-input-length="3"
+ data-ams-select2-enable-free-tags="true"
+ data-ams-select2-free-tags-prefix="New keyword: "
+ data-ams-select2-separator="|"
+ data-ams-select2-tokens-separators="|"
+ data-ams-select2-values='{}'
+ i18n:domain="pyams_form"
+ i18n:attributes="data-ams-select2-free-tags-prefix">
+</input>