rearrangement of schema_macros; added field instance class for number fields
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1975 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
90377b06b9
commit
b167f350f2
4 changed files with 86 additions and 15 deletions
|
@ -24,9 +24,11 @@ $Id$
|
|||
|
||||
from zope.interface import implements
|
||||
from zope.component import adapts
|
||||
from zope import component
|
||||
|
||||
from cybertools.composer.base import Component
|
||||
from cybertools.composer.schema.interfaces import IField, IFieldInstance
|
||||
from cybertools.composer.schema.interfaces import fieldTypes
|
||||
from cybertools.composer.schema.schema import formErrors
|
||||
from cybertools.util.format import toStr, toUnicode
|
||||
|
||||
|
@ -37,11 +39,11 @@ class Field(Component):
|
|||
|
||||
required = False
|
||||
|
||||
def __init__(self, name, title=None, renderFactory=None, **kw):
|
||||
def __init__(self, name, title=None, fieldType='textline', **kw):
|
||||
assert name
|
||||
self.__name__ = name
|
||||
title = title or u''
|
||||
self.renderFactory = renderFactory # use for rendering field content
|
||||
self.fieldType = fieldType
|
||||
super(Field, self).__init__(title, __name__=name, **kw)
|
||||
self.title = title
|
||||
for k, v in kw.items():
|
||||
|
@ -54,6 +56,13 @@ class Field(Component):
|
|||
def getTitleValue(self):
|
||||
return self.title or self.name
|
||||
|
||||
def getFieldTypeInfo(self):
|
||||
return fieldTypes.getTerm(self.fieldType)
|
||||
|
||||
def getFieldInstance(self):
|
||||
instanceName = self.getFieldTypeInfo().instanceName
|
||||
return component.getAdapter(self, IFieldInstance, name=instanceName)
|
||||
|
||||
|
||||
class FieldInstance(object):
|
||||
|
||||
|
@ -79,10 +88,38 @@ class FieldInstance(object):
|
|||
return toUnicode(strValue) or u''
|
||||
|
||||
def validate(self, value):
|
||||
errors = []
|
||||
severity = 0
|
||||
if not value and self.context.required:
|
||||
error = formErrors['required_missing']
|
||||
self.errors.append(error)
|
||||
self.severity = error.severity
|
||||
self.setError('required_missing')
|
||||
|
||||
def setError(self, errorName):
|
||||
error = formErrors[errorName]
|
||||
self.errors.append(error)
|
||||
self.severity = max(error.severity, self.severity)
|
||||
|
||||
|
||||
class NumberFieldInstance(FieldInstance):
|
||||
|
||||
def marshall(self, value):
|
||||
if value is None:
|
||||
return ''
|
||||
return str(value)
|
||||
|
||||
def display(self, value):
|
||||
if value is None:
|
||||
return '-'
|
||||
return str(value)
|
||||
|
||||
def unmarshall(self, strValue):
|
||||
if not strValue:
|
||||
return None
|
||||
return int(strValue)
|
||||
|
||||
def validate(self, value):
|
||||
if value in ('', None):
|
||||
if self.context.required:
|
||||
self.setError('required_missing')
|
||||
else:
|
||||
try:
|
||||
int(value)
|
||||
except (TypeError, ValueError):
|
||||
self.setError('invalid_number')
|
||||
|
|
|
@ -28,7 +28,7 @@ from zope.interface import implements
|
|||
|
||||
from cybertools.composer.instance import Instance
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.composer.schema.interfaces import IClient, IFieldInstance
|
||||
from cybertools.composer.schema.interfaces import IClient
|
||||
from cybertools.composer.schema.schema import FormState
|
||||
|
||||
|
||||
|
@ -75,7 +75,11 @@ class ClientInstance(object):
|
|||
values = attrs.setdefault(self.aspect, {})
|
||||
if template is not None:
|
||||
for f in template.fields:
|
||||
fi = IFieldInstance(f)
|
||||
fieldType = f.getFieldTypeInfo()
|
||||
if not fieldType.storeData:
|
||||
# a dummy field, e.g. a spacer
|
||||
continue
|
||||
fi = f.getFieldInstance()
|
||||
name = f.name
|
||||
value = values.get(name, u'')
|
||||
value = mode == 'view' and fi.display(value) or fi.marshall(value)
|
||||
|
@ -104,8 +108,11 @@ class ClientInstanceEditor(ClientInstance):
|
|||
setattr(self.context, self.attrsName, attrs)
|
||||
values = attrs.setdefault(self.aspect, OOBTree())
|
||||
for f in template.fields:
|
||||
#fi = IFieldInstance(f)
|
||||
name = f.name
|
||||
fieldType = f.getFieldTypeInfo()
|
||||
if not fieldType.storeData:
|
||||
# a dummy field, e.g. a spacer
|
||||
continue
|
||||
fi = formState.fieldInstances[name]
|
||||
value = fi.unmarshall(data.get(name))
|
||||
if name in data:
|
||||
|
@ -119,8 +126,9 @@ class ClientInstanceEditor(ClientInstance):
|
|||
def validate(self, data):
|
||||
formState = FormState()
|
||||
for f in self.template.fields:
|
||||
fi = IFieldInstance(f)
|
||||
value = fi.unmarshall(data.get(f.name))
|
||||
fi = f.getFieldInstance()
|
||||
#value = fi.unmarshall(data.get(f.name))
|
||||
value = data.get(f.name)
|
||||
fi.validate(value)
|
||||
formState.fieldInstances.append(fi)
|
||||
formState.severity = max(formState.severity, fi.severity)
|
||||
|
|
|
@ -25,6 +25,7 @@ $Id$
|
|||
from zope import schema
|
||||
from zope.interface import Interface, Attribute
|
||||
from zope.i18nmessageid import MessageFactory
|
||||
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
|
||||
|
||||
from cybertools.composer.interfaces import ITemplate, IComponent
|
||||
|
||||
|
@ -57,6 +58,30 @@ class ISchema(ITemplate):
|
|||
'with this schema.')
|
||||
|
||||
|
||||
class FieldType(SimpleTerm):
|
||||
|
||||
def __init__(self, value, token=None, title=None, **kw):
|
||||
super(FieldType, self).__init__(value, token, title)
|
||||
self.name = value
|
||||
self.fieldMacro = 'field'
|
||||
self.inputMacro = 'input_' + self.name
|
||||
self.storeData = True
|
||||
self.instanceName = ''
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
|
||||
fieldTypes = SimpleVocabulary((
|
||||
FieldType('textline', 'textline', u'Textline'),
|
||||
FieldType('textarea', 'textarea', u'Textarea'),
|
||||
FieldType('number', 'number', u'Number', inputMacro='input_textline',
|
||||
instanceName='number'),
|
||||
#FieldType('date', 'date', u'Date'),
|
||||
#FieldType('checkbox', 'checkbox', u'Checkbox'),
|
||||
FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer',
|
||||
storeData=False),
|
||||
))
|
||||
|
||||
class IField(IComponent):
|
||||
""" May be used for data entry or display.
|
||||
"""
|
||||
|
@ -78,8 +103,7 @@ class IField(IComponent):
|
|||
description=_(u'The type of the field'),
|
||||
required=True,
|
||||
default='textline',
|
||||
values=('textline', 'textarea', 'number',
|
||||
'date', 'checkbox', 'spacer'))
|
||||
vocabulary=fieldTypes,)
|
||||
defaultValue = schema.TextLine(
|
||||
title=_(u'Default'),
|
||||
description=_(u'Value with which to pre-set the field contents'),
|
||||
|
|
|
@ -83,5 +83,7 @@ class FormError(object):
|
|||
|
||||
formErrors = dict(
|
||||
required_missing=FormError(u'Missing data for required field',
|
||||
u'Please enter data for required field.')
|
||||
u'Please enter data for required field.'),
|
||||
invalid_number=FormError(u'Invalid number',
|
||||
u'Please enter a number, only digits allowed.'),
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue