--- a/src/pyams_form/interfaces/form.py Fri Oct 04 19:15:15 2019 +0200
+++ b/src/pyams_form/interfaces/form.py Tue Oct 08 09:23:48 2019 +0200
@@ -560,6 +560,10 @@
default=2)
+class IDottedDecimalWidget(IFloatWidget):
+ """Dotted decimal field widget interface"""
+
+
class IDateWidget(ITextWidget):
"""Date widget interface"""
--- a/src/pyams_form/widget/__init__.py Fri Oct 04 19:15:15 2019 +0200
+++ b/src/pyams_form/widget/__init__.py Tue Oct 08 09:23:48 2019 +0200
@@ -40,14 +40,16 @@
from pyams_form.interfaces.form import IActionWidget, ICloseWidget, IColorWidget, IDateWidget, \
IDatetimeWidget, IFloatWidget, IFormLayer, IHTMLWidget, IIntegerWidget, IJSONDictWidget, \
- IResetWidget, ISEOTextLineWidget, ISelect2Widget, ITextLineListWidget, ITimeWidget
+ IResetWidget, ISEOTextLineWidget, ISelect2Widget, ITextLineListWidget, ITimeWidget, \
+ IDottedDecimalWidget
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, IJSONDictField, ITextLineListField, \
- IJSONDictFieldsGetter
+ IJSONDictFieldsGetter, IDottedDecimalField, DottedDecimalField
from pyams_utils.timezone import localgmtime, tztime
+from pyams_utils.widget.decimal import DottedDecimalDataConverter
__docformat__ = 'restructuredtext'
@@ -429,6 +431,38 @@
return FieldWidget(field, FloatWidget(request))
+@widgettemplate_config(mode=INPUT_MODE, template='templates/decimal-input.pt', layer=IFormLayer)
+@implementer_only(IDottedDecimalWidget)
+class DottedDecimalWidget(FloatWidget):
+ """Dotted decimal field widget"""
+
+ @property
+ def validate_rules(self):
+ conv = locale.localeconv()
+ allow_negative = True
+ if (self.field.min is not None) and (self.field.min >= 0):
+ allow_negative = False
+ rules = {'pattern': '{}[\d{}]+{}?\d*{}'.format(
+ '\{}?'.format(conv.get('negative_sign', '-'))
+ if (allow_negative and (conv.get('n_sign_posn') in SIGN_BEFORE_VALUE)) else '',
+ '', # no thousands separator
+ '\.', # dot as decimal separator !!
+ '\{}?'.format(conv.get('negative_sign', '-'))
+ if (allow_negative and (conv.get('n_sign_posn') in SIGN_AFTER_VALUE)) else '')}
+ return json.dumps(rules)
+
+ @property
+ def validate_messages(self):
+ return json.dumps({
+ 'pattern': self.request.localizer.translate(DottedDecimalDataConverter.errorMessage)
+ })
+
+
+@adapter_config(context=(IDottedDecimalField, IFormLayer), provides=IFieldWidget)
+def DottedDecimalFieldWidget(field, request):
+ return FieldWidget(field, DottedDecimalWidget(request))
+
+
#
# Date widget
#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_form/widget/templates/decimal-input.pt Tue Oct 08 09:23:48 2019 +0200
@@ -0,0 +1,40 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ tal:omit-tag="">
+ <input id="" name="" class="" title="" lang="" disabled=""
+ readonly="" alt="" tabindex="" accesskey="" size="" maxlength=""
+ style="" value="" type="text"
+ data-ams-validate-rules='${view/validate_rules}'
+ data-ams-validate-messages='${view/validate_messages}'
+ tal:attributes='id view/id;
+ name view/name;
+ class view/klass;
+ style view/style;
+ title view/title;
+ 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;
+ readonly view/readonly;
+ alt view/alt;
+ accesskey view/accesskey;
+ onselect view/onselect;
+ size view/size;
+ maxlength view/maxlength;
+ placeholder view/placeholder;
+ autocapitalize view/autocapitalize;
+ data-ams-data tales:object_data(view);' />
+</html>