more on schemas and fields: make it usable for interface-driven form generation; + minor bug fixes
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1998 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
aadd146ae8
commit
7b553a5955
5 changed files with 50 additions and 12 deletions
|
@ -220,12 +220,15 @@ Real work can only be done by an adapter to GenericView that provides the
|
||||||
IFormController interface with its update(). There also must be a
|
IFormController interface with its update(). There also must be a
|
||||||
form variable (typically coming from a hidden field) with the name
|
form variable (typically coming from a hidden field) with the name
|
||||||
'form.action' that provides the name under which the form controller is
|
'form.action' that provides the name under which the form controller is
|
||||||
registered.
|
registered. The ``update()`` method should return a boolean that indicates
|
||||||
|
if the view should be rendered or not; return ``False`` e.g. if the form
|
||||||
|
controller issues a redirect.
|
||||||
|
|
||||||
>>> from cybertools.browser.form import IFormController, FormController
|
>>> from cybertools.browser.form import IFormController, FormController
|
||||||
>>> class MyController(FormController):
|
>>> class MyController(FormController):
|
||||||
... def update(self):
|
... def update(self):
|
||||||
... print 'updating...'
|
... print 'updating...'
|
||||||
|
... return True
|
||||||
|
|
||||||
>>> component.provideAdapter(MyController, (View, IBrowserRequest),
|
>>> component.provideAdapter(MyController, (View, IBrowserRequest),
|
||||||
... IFormController, name='save')
|
... IFormController, name='save')
|
||||||
|
|
|
@ -39,6 +39,7 @@ class Field(Component):
|
||||||
|
|
||||||
required = False
|
required = False
|
||||||
standardFieldName = None
|
standardFieldName = None
|
||||||
|
renderFactory = None
|
||||||
|
|
||||||
def __init__(self, name, title=None, fieldType='textline', **kw):
|
def __init__(self, name, title=None, fieldType='textline', **kw):
|
||||||
assert name
|
assert name
|
||||||
|
|
|
@ -24,17 +24,48 @@ $Id$
|
||||||
|
|
||||||
from BTrees.OOBTree import OOBTree
|
from BTrees.OOBTree import OOBTree
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import implements
|
from zope.interface import implements, Interface
|
||||||
|
|
||||||
from cybertools.composer.instance import Instance
|
from cybertools.composer.instance import Instance as BaseInstance
|
||||||
from cybertools.composer.interfaces import IInstance
|
from cybertools.composer.interfaces import IInstance
|
||||||
from cybertools.composer.schema.interfaces import IClient
|
from cybertools.composer.schema.interfaces import IClient
|
||||||
from cybertools.composer.schema.schema import FormState
|
from cybertools.composer.schema.schema import FormState
|
||||||
|
|
||||||
|
|
||||||
class Editor(Instance):
|
class Instance(BaseInstance):
|
||||||
|
|
||||||
|
implements(IInstance)
|
||||||
|
adapts(Interface)
|
||||||
|
|
||||||
aspect = 'schema.editor.default'
|
aspect = 'schema.editor.default'
|
||||||
|
template = None
|
||||||
|
|
||||||
|
def applyTemplate(self, *args, **kw):
|
||||||
|
#result = dict(__name__=self.context.__name__)
|
||||||
|
result = {}
|
||||||
|
mode = kw.get('mode', 'view')
|
||||||
|
template = self.template
|
||||||
|
if template is not None:
|
||||||
|
for f in template.components:
|
||||||
|
fieldType = f.getFieldTypeInfo()
|
||||||
|
if not fieldType.storeData:
|
||||||
|
# a dummy field, e.g. a spacer
|
||||||
|
continue
|
||||||
|
fi = f.getFieldInstance()
|
||||||
|
name = f.name
|
||||||
|
value = getattr(self.context, name, u'')
|
||||||
|
value = (mode == 'view' and fi.display(value)) or fi.marshall(value)
|
||||||
|
result[name] = value
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class Editor(BaseInstance):
|
||||||
|
|
||||||
|
implements(IInstance)
|
||||||
|
adapts(Interface)
|
||||||
|
|
||||||
|
aspect = 'schema.editor.default'
|
||||||
|
template = None
|
||||||
|
|
||||||
def applyTemplate(self, data={}, *args, **kw):
|
def applyTemplate(self, data={}, *args, **kw):
|
||||||
for c in self.template.components:
|
for c in self.template.components:
|
||||||
|
|
|
@ -78,6 +78,7 @@ fieldTypes = SimpleVocabulary((
|
||||||
instanceName='number'),
|
instanceName='number'),
|
||||||
#FieldType('date', 'date', u'Date'),
|
#FieldType('date', 'date', u'Date'),
|
||||||
#FieldType('checkbox', 'checkbox', u'Checkbox'),
|
#FieldType('checkbox', 'checkbox', u'Checkbox'),
|
||||||
|
FieldType('dropdown', 'dropdown', u'Drop-down selection'),
|
||||||
FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer',
|
FieldType('spacer', 'spacer', u'Spacer', fieldMacro='field_spacer',
|
||||||
storeData=False),
|
storeData=False),
|
||||||
))
|
))
|
||||||
|
@ -139,6 +140,12 @@ class IField(IComponent):
|
||||||
default=3,
|
default=3,
|
||||||
required=False,)
|
required=False,)
|
||||||
|
|
||||||
|
renderFactory = Attribute('A class or another factory providing an '
|
||||||
|
'object used for rendering the data e.g. as a '
|
||||||
|
'cell on a tabular report. See cybertools.reporter. '
|
||||||
|
'May become replaced with a more intelligent kind of '
|
||||||
|
'field instance.')
|
||||||
|
|
||||||
|
|
||||||
class IFieldInstance(Interface):
|
class IFieldInstance(Interface):
|
||||||
""" An adapter for checking and converting data values coming
|
""" An adapter for checking and converting data values coming
|
||||||
|
|
|
@ -28,13 +28,14 @@ from cybertools.composer.schema.field import Field
|
||||||
|
|
||||||
|
|
||||||
fieldMapping = {
|
fieldMapping = {
|
||||||
schema.TextLine: ('text',),
|
schema.TextLine: ('textline',),
|
||||||
schema.ASCII: ('text',),
|
schema.ASCII: ('textline',),
|
||||||
schema.Text: ('textarea',),
|
schema.Text: ('textarea',),
|
||||||
schema.Date: ('date',),
|
schema.Date: ('date',),
|
||||||
schema.Int: ('number',),
|
schema.Int: ('number',),
|
||||||
schema.Bool: ('checkbox',),
|
schema.Bool: ('checkbox',),
|
||||||
schema.Choice: ('dropdown',),
|
schema.Choice: ('dropdown',),
|
||||||
|
schema.Bytes: ('fileupload',),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,12 +45,7 @@ def getSchemaFromInterface(ifc, manager):
|
||||||
field = ifc[fname]
|
field = ifc[fname]
|
||||||
if field.__class__ in fieldMapping:
|
if field.__class__ in fieldMapping:
|
||||||
info = fieldMapping[field.__class__]
|
info = fieldMapping[field.__class__]
|
||||||
voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', ())
|
voc = getattr(field, 'vocabulary', ()) or getattr(field, 'vocabularyName', None)
|
||||||
if voc:
|
|
||||||
if isinstance(voc, str):
|
|
||||||
voc = vocabularies[voc]
|
|
||||||
else:
|
|
||||||
voc = [(t.token, t.title or t.token) for t in voc]
|
|
||||||
f = Field(field.getName(),
|
f = Field(field.getName(),
|
||||||
fieldType = info[0],
|
fieldType = info[0],
|
||||||
required=field.required,
|
required=field.required,
|
||||||
|
|
Loading…
Add table
Reference in a new issue