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.interface import implements
from zope.component import adapts from zope.component import adapts
from zope import component
from cybertools.composer.base import Component from cybertools.composer.base import Component
from cybertools.composer.schema.interfaces import IField, IFieldInstance from cybertools.composer.schema.interfaces import IField, IFieldInstance
from cybertools.composer.schema.interfaces import fieldTypes
from cybertools.composer.schema.schema import formErrors from cybertools.composer.schema.schema import formErrors
from cybertools.util.format import toStr, toUnicode from cybertools.util.format import toStr, toUnicode
@ -37,11 +39,11 @@ class Field(Component):
required = False required = False
def __init__(self, name, title=None, renderFactory=None, **kw): def __init__(self, name, title=None, fieldType='textline', **kw):
assert name assert name
self.__name__ = name self.__name__ = name
title = title or u'' title = title or u''
self.renderFactory = renderFactory # use for rendering field content self.fieldType = fieldType
super(Field, self).__init__(title, __name__=name, **kw) super(Field, self).__init__(title, __name__=name, **kw)
self.title = title self.title = title
for k, v in kw.items(): for k, v in kw.items():
@ -54,6 +56,13 @@ class Field(Component):
def getTitleValue(self): def getTitleValue(self):
return self.title or self.name 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): class FieldInstance(object):
@ -79,10 +88,38 @@ class FieldInstance(object):
return toUnicode(strValue) or u'' return toUnicode(strValue) or u''
def validate(self, value): def validate(self, value):
errors = []
severity = 0
if not value and self.context.required: if not value and self.context.required:
error = formErrors['required_missing'] self.setError('required_missing')
self.errors.append(error)
self.severity = error.severity
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.instance import Instance
from cybertools.composer.interfaces import IInstance 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 from cybertools.composer.schema.schema import FormState
@ -75,7 +75,11 @@ class ClientInstance(object):
values = attrs.setdefault(self.aspect, {}) values = attrs.setdefault(self.aspect, {})
if template is not None: if template is not None:
for f in template.fields: 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 name = f.name
value = values.get(name, u'') value = values.get(name, u'')
value = mode == 'view' and fi.display(value) or fi.marshall(value) value = mode == 'view' and fi.display(value) or fi.marshall(value)
@ -104,8 +108,11 @@ class ClientInstanceEditor(ClientInstance):
setattr(self.context, self.attrsName, attrs) setattr(self.context, self.attrsName, attrs)
values = attrs.setdefault(self.aspect, OOBTree()) values = attrs.setdefault(self.aspect, OOBTree())
for f in template.fields: for f in template.fields:
#fi = IFieldInstance(f)
name = f.name name = f.name
fieldType = f.getFieldTypeInfo()
if not fieldType.storeData:
# a dummy field, e.g. a spacer
continue
fi = formState.fieldInstances[name] fi = formState.fieldInstances[name]
value = fi.unmarshall(data.get(name)) value = fi.unmarshall(data.get(name))
if name in data: if name in data:
@ -119,8 +126,9 @@ class ClientInstanceEditor(ClientInstance):
def validate(self, data): def validate(self, data):
formState = FormState() formState = FormState()
for f in self.template.fields: for f in self.template.fields:
fi = IFieldInstance(f) fi = f.getFieldInstance()
value = fi.unmarshall(data.get(f.name)) #value = fi.unmarshall(data.get(f.name))
value = data.get(f.name)
fi.validate(value) fi.validate(value)
formState.fieldInstances.append(fi) formState.fieldInstances.append(fi)
formState.severity = max(formState.severity, fi.severity) formState.severity = max(formState.severity, fi.severity)

View file

@ -25,6 +25,7 @@ $Id$
from zope import schema from zope import schema
from zope.interface import Interface, Attribute from zope.interface import Interface, Attribute
from zope.i18nmessageid import MessageFactory from zope.i18nmessageid import MessageFactory
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from cybertools.composer.interfaces import ITemplate, IComponent from cybertools.composer.interfaces import ITemplate, IComponent
@ -57,6 +58,30 @@ class ISchema(ITemplate):
'with this schema.') '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): class IField(IComponent):
""" May be used for data entry or display. """ May be used for data entry or display.
""" """
@ -78,8 +103,7 @@ class IField(IComponent):
description=_(u'The type of the field'), description=_(u'The type of the field'),
required=True, required=True,
default='textline', default='textline',
values=('textline', 'textarea', 'number', vocabulary=fieldTypes,)
'date', 'checkbox', 'spacer'))
defaultValue = schema.TextLine( defaultValue = schema.TextLine(
title=_(u'Default'), title=_(u'Default'),
description=_(u'Value with which to pre-set the field contents'), description=_(u'Value with which to pre-set the field contents'),

View file

@ -83,5 +83,7 @@ class FormError(object):
formErrors = dict( formErrors = dict(
required_missing=FormError(u'Missing data for required field', 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.'),
) )