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.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')
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'),
|
||||||
|
|
|
@ -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.'),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue