--- a/src/pyams_form/interfaces/form.py Fri May 18 15:54:52 2018 +0200
+++ b/src/pyams_form/interfaces/form.py Fri May 18 15:55:15 2018 +0200
@@ -19,7 +19,7 @@
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
+ ITextWidget, ITextAreaWidget, ISelectWidget, IButtonWidget
from zope.interface.interfaces import IObjectEvent, ObjectEvent
from zope.lifecycleevent.interfaces import IObjectCreatedEvent, IObjectModifiedEvent
@@ -62,7 +62,7 @@
"""Base form interface"""
-@template_config(template='../templates/form.pt', layer=IFormLayer)
+@template_config(template='templates/form.pt', layer=IFormLayer)
class IForm(IBaseForm):
"""Default form interface"""
@@ -292,7 +292,7 @@
# Inner form interfaces
#
-@template_config(template='../templates/inner-form.pt', layer=IFormLayer)
+@template_config(template='templates/inner-form.pt', layer=IFormLayer)
class IInnerForm(IForm):
"""Inner form marker interface"""
@@ -300,7 +300,7 @@
schema=IForm)
-@template_config(template='../templates/widget-form.pt', layer=IFormLayer)
+@template_config(template='templates/widget-form.pt', layer=IFormLayer)
class IWidgetForm(IForm):
"""Widget form marker interface"""
@@ -496,6 +496,28 @@
"""Close button widget interface"""
+class IActionWidget(IButtonWidget):
+ """Action button widget interface"""
+
+ label_css_class = TextLine(title="Label icon CSS class",
+ description="CSS class associated with label",
+ required=True,
+ default='fa fa-fw fa-edit')
+
+ click_handler = TextLine(title="Button click handler",
+ description="Javascript function called by button click",
+ required=False)
+
+ url = TextLine(title="Button target URL",
+ description="Target URL accessed by button click",
+ required=False)
+
+ modal_target = Bool(title="Modal target?",
+ description="If True, target URL is opened in a modal frame",
+ required=False,
+ default=False)
+
+
class IDateWidget(ITextWidget):
"""Date widget interface"""
--- a/src/pyams_form/schema.py Fri May 18 15:54:52 2018 +0200
+++ b/src/pyams_form/schema.py Fri May 18 15:55:15 2018 +0200
@@ -21,6 +21,8 @@
# import packages
from z3c.form.button import Button
from zope.interface import implementer
+from zope.schema import TextLine, Bool
+from zope.schema.fieldproperty import FieldProperty
class IResetButton(IButton):
@@ -39,3 +41,47 @@
@implementer(ICloseButton)
class CloseButton(Button):
"""Close button"""
+
+
+class IActionButton(IButton):
+ """Action button interface"""
+
+ label = TextLine(title="Button label",
+ description="Button label displayed as hint",
+ required=False)
+
+ label_css_class = TextLine(title="Label icon CSS class",
+ description="CSS class associated with label",
+ required=True,
+ default='fa fa-fw fa-edit')
+
+ click_handler = TextLine(title="Button click handler",
+ description="Javascript function called by button click",
+ required=False)
+
+ url = TextLine(title="Button target URL",
+ description="Target URL accessed by button click",
+ required=False)
+
+ modal_target = Bool(title="Modal target?",
+ description="If True, target URL is opened in a modal frame",
+ required=False,
+ default=False)
+
+
+@implementer(IActionButton)
+class ActionButton(Button):
+ """Action button"""
+
+ label_css_class = FieldProperty(IActionButton['label_css_class'])
+ click_handler = FieldProperty(IActionButton['click_handler'])
+ url = FieldProperty(IActionButton['url'])
+ modal_target = FieldProperty(IActionButton['modal_target'])
+
+ def __init__(self, *args, **kwargs):
+ if 'label_css_class' in kwargs:
+ self.label_css_class = kwargs.pop('label_css_class')
+ self.click_handler = kwargs.pop('click_handler', None)
+ self.url = kwargs.pop('url', None)
+ self.modal_target = kwargs.pop('modal_target', None)
+ super(ActionButton, self).__init__(*args, **kwargs)
--- a/src/pyams_form/widget/__init__.py Fri May 18 15:54:52 2018 +0200
+++ b/src/pyams_form/widget/__init__.py Fri May 18 15:55:15 2018 +0200
@@ -22,8 +22,8 @@
# import interfaces
from pyams_form.interfaces.form import IFormLayer, IResetWidget, ICloseWidget, IDateWidget, IDatetimeWidget, \
ITimeWidget, \
- IColorWidget, IHTMLWidget, ISelect2Widget, ITextLineListWidget, ISEOTextLineWidget
-from pyams_form.schema import IResetButton, ICloseButton
+ IColorWidget, IHTMLWidget, ISelect2Widget, ITextLineListWidget, ISEOTextLineWidget, IActionWidget
+from pyams_form.schema import IResetButton, ICloseButton, IActionButton
from pyams_skin.interfaces.tinymce import ITinyMCEConfiguration
from pyams_utils.schema import IColorField, IHTMLField, ITextLineListField
from pyramid.interfaces import IRequest
@@ -37,6 +37,7 @@
from pyams_utils.timezone import tztime, localgmtime
from pyramid.exceptions import ConfigurationError
from z3c.form.action import Action
+from z3c.form.browser.button import ButtonWidget
from z3c.form.browser.select import SelectWidget
from z3c.form.browser.submit import SubmitWidget
from z3c.form.browser.text import TextWidget
@@ -45,6 +46,7 @@
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.schema.fieldproperty import FieldProperty
from pyams_form import _
@@ -212,6 +214,43 @@
#
+# Action button widget and action
+#
+
+@widgettemplate_config(mode=INPUT_MODE, template='templates/action-input.pt', layer=IFormLayer)
+@widgettemplate_config(mode=DISPLAY_MODE, template='templates/action-display.pt', layer=IFormLayer)
+@implementer_only(IActionWidget)
+class ActionWidget(ButtonWidget):
+ """A dialog action button"""
+
+ label_css_class = FieldProperty(IActionWidget['label_css_class'])
+ click_handler = FieldProperty(IActionWidget['click_handler'])
+ url = FieldProperty(IActionWidget['url'])
+ modal_target = FieldProperty(IActionWidget['modal_target'])
+
+
+@adapter_config(context=(IActionButton, IFormLayer), provides=IFieldWidget)
+def ActionFieldWidget(field, request):
+ action = FieldWidget(field, ActionWidget(request))
+ action.value = field.title
+ return action
+
+
+@adapter_config(context=(IFormLayer, IActionButton), provides=IButtonAction)
+class ActionButtonAction(ActionWidget, ButtonAction):
+ """Action button action"""
+
+ def __init__(self, request, field):
+ ActionWidget.__init__(self, request)
+ Action.__init__(self, request, field.title)
+ self.field = field
+ self.label_css_class = field.label_css_class
+ self.click_handler = field.click_handler
+ self.url = field.url
+ self.modal_target = field.modal_target
+
+
+#
# Date widget
#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/action-display.pt Fri May 18 15:55:15 2018 +0200
@@ -0,0 +1,31 @@
+<button type="button"
+ class="btn padding-x-5 hint opaque baseline"
+ tal:define="url extension:absolute_url(view.form.context, view.url)"
+ tal:attributes="id view/id;
+ title view/title;
+ style view/style;
+ 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;
+ value view/value;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ alt view/alt;
+ accesskey view/accesskey;
+ data-ams-url python:url if view.url else None;
+ data-ams-click-handler view/click_handler;
+ data-toggle python:'modal' if view.modal_target else None;
+ data-ams-data extension:object_data(view);">
+ <i tal:attributes="class view/label_css_class"></i>
+</button>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/action-input.pt Fri May 18 15:55:15 2018 +0200
@@ -0,0 +1,32 @@
+<button type="button"
+ class="btn padding-x-5 hint opaque baseline"
+ tal:define="url extension:absolute_url(view.form.context, view.url)"
+ tal:attributes="id view/id;
+ title view/title;
+ style view/style;
+ 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;
+ value view/value;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ alt view/alt;
+ accesskey view/accesskey;
+ data-ams-url python:url if view.url else None;
+ data-ams-click-handler view/click_handler;
+ data-toggle python:'modal' if view.modal_target else None;
+ data-ams-data extension:object_data(view);"
+ data-ams-hint-gravity="s">
+ <i tal:attributes="class view/label_css_class"></i>
+</button>