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:
helmutm 2007-08-30 10:56:28 +00:00
parent 90377b06b9
commit b167f350f2
4 changed files with 86 additions and 15 deletions

View file

@ -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')

View file

@ -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)

View file

@ -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'),

View file

@ -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.'),
)