Add custom widget for "percent" field
so that storage can use "traditional" (0.3612) format but UI can use "human-friendly" format (36.12 %)
This commit is contained in:
parent
7bf509097f
commit
d659e62fda
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Rattail -- Retail Software Framework
|
# Rattail -- Retail Software Framework
|
||||||
# Copyright © 2010-2018 Lance Edgar
|
# Copyright © 2010-2019 Lance Edgar
|
||||||
#
|
#
|
||||||
# This file is part of Rattail.
|
# This file is part of Rattail.
|
||||||
#
|
#
|
||||||
|
@ -24,10 +24,11 @@
|
||||||
Form Widgets
|
Form Widgets
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import, division
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
import decimal
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
@ -55,6 +56,35 @@ class NumberInputWidget(dfwidget.TextInputWidget):
|
||||||
autocomplete = 'off'
|
autocomplete = 'off'
|
||||||
|
|
||||||
|
|
||||||
|
class PercentInputWidget(dfwidget.TextInputWidget):
|
||||||
|
"""
|
||||||
|
Custom text input widget, used for "percent" type fields. This widget
|
||||||
|
assumes that the underlying storage for the value is a "traditional"
|
||||||
|
percent value, e.g. ``0.36135`` - but the UI should represent this as a
|
||||||
|
"human-friendly" value, e.g. ``36.135 %``.
|
||||||
|
"""
|
||||||
|
template = 'percentinput'
|
||||||
|
autocomplete = 'off'
|
||||||
|
|
||||||
|
def serialize(self, field, cstruct, **kw):
|
||||||
|
if cstruct not in (colander.null, None):
|
||||||
|
# convert "traditional" value to "human-friendly"
|
||||||
|
value = decimal.Decimal(cstruct) * 100
|
||||||
|
value = value.quantize(decimal.Decimal('0.001'))
|
||||||
|
cstruct = six.text_type(value)
|
||||||
|
return super(PercentInputWidget, self).serialize(field, cstruct, **kw)
|
||||||
|
|
||||||
|
def deserialize(self, field, pstruct):
|
||||||
|
pstruct = super(PercentInputWidget, self).deserialize(field, pstruct)
|
||||||
|
if pstruct is colander.null:
|
||||||
|
return colander.null
|
||||||
|
# convert "human-friendly" value to "traditional"
|
||||||
|
value = decimal.Decimal(pstruct)
|
||||||
|
value = value.quantize(decimal.Decimal('0.00001'))
|
||||||
|
value /= 100
|
||||||
|
return six.text_type(value)
|
||||||
|
|
||||||
|
|
||||||
class PlainSelectWidget(dfwidget.SelectWidget):
|
class PlainSelectWidget(dfwidget.SelectWidget):
|
||||||
template = 'select_plain'
|
template = 'select_plain'
|
||||||
|
|
||||||
|
|
25
tailbone/templates/deform/percentinput.pt
Normal file
25
tailbone/templates/deform/percentinput.pt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<span tal:define="name name|field.name;
|
||||||
|
css_class css_class|field.widget.css_class;
|
||||||
|
oid oid|field.oid;
|
||||||
|
mask mask|field.widget.mask;
|
||||||
|
mask_placeholder mask_placeholder|field.widget.mask_placeholder;
|
||||||
|
style style|field.widget.style;
|
||||||
|
autocomplete autocomplete|field.widget.autocomplete|'off';
|
||||||
|
"
|
||||||
|
tal:omit-tag="">
|
||||||
|
<input type="text" name="${name}" value="${cstruct}"
|
||||||
|
tal:attributes="class string: form-control ${css_class or ''};
|
||||||
|
style style;
|
||||||
|
autocomplete autocomplete;
|
||||||
|
"
|
||||||
|
id="${oid}"/>
|
||||||
|
%
|
||||||
|
<script tal:condition="mask" type="text/javascript">
|
||||||
|
deform.addCallback(
|
||||||
|
'${oid}',
|
||||||
|
function (oid) {
|
||||||
|
$("#" + oid).mask("${mask}",
|
||||||
|
{placeholder:"${mask_placeholder}"});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</span>
|
Loading…
Reference in a new issue