[Checkins] SVN: zope3org/trunk/src/zorg/multiform/ intermediate commit

Bernd Dorn bernd.dorn at fhv.at
Sat Apr 8 17:30:53 EDT 2006


Log message for revision 66693:
  intermediate commit

Changed:
  U   zope3org/trunk/src/zorg/multiform/README.txt
  A   zope3org/trunk/src/zorg/multiform/interfaces.py
  U   zope3org/trunk/src/zorg/multiform/multiform.py
  U   zope3org/trunk/src/zorg/multiform/tests.py

-=-
Modified: zope3org/trunk/src/zorg/multiform/README.txt
===================================================================
--- zope3org/trunk/src/zorg/multiform/README.txt	2006-04-08 21:30:39 UTC (rev 66692)
+++ zope3org/trunk/src/zorg/multiform/README.txt	2006-04-08 21:30:52 UTC (rev 66693)
@@ -2,4 +2,70 @@
  Multiform Package
 ===================
 
+This Package provides an API to handle multiple forms with matching
+form fields on multiple items. The cration of multiforms is derived
+from the Form class of the formlib package.
 
+    >>> from zope import interface, schema
+    >>> class IOrder(interface.Interface):
+    ...     identifier = schema.Int(title=u"Identifier", readonly=True)
+    ...     name = schema.TextLine(title=u"Name")
+    >>> class Order:
+    ...     interface.implements(IOrder)
+    ...
+    ...     def __init__(self, identifier, name=''):
+    ...         self.identifier = identifier
+    ...         self.name = name
+
+    >>> orderMapping = dict([(str(k),Order(k,name='n%s'%k)) for k in range(5)])
+
+
+Let us create a new multiform class which should display IOrder objects.
+
+    >>> from multiform.multiform import MultiForm,ItemFormBase
+    >>> from zope.formlib import form
+
+    >>> class OrderForm(ItemFormBase):
+    ...     def __call__(self, ignore_request=False):
+    ...         widgets = form.setUpWidgets(
+    ...             self.form_fields, self.prefix, self.context, self.request,
+    ...             ignore_request=ignore_request)
+    ...         return '\n<div>%s</div>\n' % '</div><div>'.join([w() for w in
+    ...     widgets])
+
+
+    >>> class OrdersForm(MultiForm):
+    ...     
+    ...     form_fields = form.Fields(IOrder)
+    ...     
+    ...     def __call__(self, ignore_request=False):
+    ...         self.setUpForms()
+    ...         res = u''
+    ...         for form in self.forms.values():
+    ...             res += '<div>%s</div>\n' % form(ignore_request=True)
+    ...         return res
+    ...     
+    ...     def itemForm(self, item, **kwargs):
+    ...         return OrderForm(item, self, **kwargs)
+
+
+
+    >>> from zope.publisher.browser import TestRequest
+    >>> request = TestRequest()
+    >>> view = OrdersForm(orderMapping, request)
+    >>> print view()
+    <div>
+    <div>1</div><div>n1</div>
+    </div>
+    <div>
+    ...
+    <div>
+    <div>4</div><div>n4</div>
+    </div>
+
+
+
+TODO:
+
+- encode prefix, do we have to do it?
+

Added: zope3org/trunk/src/zorg/multiform/interfaces.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/interfaces.py	2006-04-08 21:30:39 UTC (rev 66692)
+++ zope3org/trunk/src/zorg/multiform/interfaces.py	2006-04-08 21:30:52 UTC (rev 66693)
@@ -0,0 +1,7 @@
+from zope.interface import Interface
+
+
+class IMultiForm(Interface):
+
+    """multiform"""
+

Modified: zope3org/trunk/src/zorg/multiform/multiform.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/multiform.py	2006-04-08 21:30:39 UTC (rev 66692)
+++ zope3org/trunk/src/zorg/multiform/multiform.py	2006-04-08 21:30:52 UTC (rev 66693)
@@ -1,4 +1,4 @@
-
+from zope.app.publisher.browser import BrowserView
 from zope.interface import implements
 
 from zope.app import zapi
@@ -6,10 +6,8 @@
 
 from zope.formlib import form
 from zope.formlib.i18n import _
+from interfaces import IMultiForm
 
-from interfaces import ITableForm
-
-
 def availableActions(form, actions):
     result = []
     for action in actions:
@@ -69,32 +67,36 @@
     return form.mode == 'display' and action.label in form.table.config.actions
 
 
-class RowFormBase(form.FormBase):
+class ItemFormBase(form.FormBase):
 
     newmode = None
 
-    def __init__(self, view, mode, **kwargs):
-        super(RowFormBase,self).__init__(view.context, view.request)
-        self.view = view
-        self.row = view.row
-        self.table = view.row.table
-        self.mode = mode
-        self.setPrefix(view.prefix)
+    def __init__(self, item, multiForm, **kwargs):
+        super(ItemFormBase,self).__init__(item,
+                                         multiForm.request)
+        self.multiForm = multiForm
         self.baseRow_actions = form.Actions()
-        
+
         # build up form_fields
         # kwargs includes form relevant parameters
         self.form_fields = form.Fields()
-        for cellView in view.getCells():
-            if cellView.useForm:
-                field = cellView.field
-                isDisplay = not(mode == 'edit' and cellView.cell.selected)
-                fieldkwargs = {}
-                fieldkwargs['for_display'] = isDisplay
-                if not isDisplay and cellView.widget is not None:
-                    fieldkwargs['custom_widget'] = cellView.widget
-                self.form_fields = self.form_fields + form.Fields(form.Field(field, **fieldkwargs),**kwargs)
-        
+        for field in self.multiForm.form_fields:
+            isDisplay = not(self.multiForm.mode == 'edit' and self.isSelected())
+            fieldkwargs = {}
+            fieldkwargs['for_display'] = isDisplay
+            # XXX why is render_context not set?
+            fieldkwargs['render_context'] = True
+            if not isDisplay and field.widget is not None:
+                fieldkwargs['custom_widget'] = field.widget
+            self.form_fields = self.form_fields + form.Fields(
+                form.Field(field.field, **fieldkwargs),**kwargs)
+
+
+    def isSelected(self):
+
+        # XXX implement this, default is selected
+        return True
+    
     def actions():
         def _getActions(self):
             return self.baseRow_actions
@@ -124,13 +126,15 @@
     return form.mode == 'display' and action.label in form.table.config.actions
 
 
-class TableFormBase(object):
-    
-    implements(ITableForm)
 
+
+class MultiForm(BrowserView):
+
+    implements(IMultiForm)
+
     label = u''
 
-    prefix = 'grid'
+    prefix = ''
 
     status = ''
 
@@ -142,20 +146,9 @@
 
     newmode = None
 
-    def __init__(self, view):
-        self.context = view.context
-        self.view = view
-        self.table = view.table
-        self.request = view.request
-        self.prefix = view.table.config.prefix   
-        self.base_actions = form.Actions()
+    actions =[]
 
-    def actions():
-        def _getActions(self):
-            return self.base_actions
-        return property(_getActions)
-    
-    actions = actions()
+    selectionField = ISelectable(['isSelected'])
 
     def availableActions(self, actions=None):
         if actions is not None:
@@ -176,26 +169,32 @@
             self.newmode = None
             self.form_reset = True
 
-    def rowForm(self, row, **kwargs):
-        return RowFormBase(row, self.mode, **kwargs)
+    def itemForm(self, item, **kwargs):
+        return ItemFormBase(item, self, **kwargs)
 
     def setUpForms(self, ignore_request=False):
         self.forms = {}
-        for row in self.view.getRows():
-                if not ignore_request:
-                    # check edit mode with row actions
-                    self.checkEditMode(row.prefix)
-                kwargs = {
-                    'omit_readonly':False,
-                    'render_context':True}
-                self.forms[row.row.key] = self.rowForm(row, **kwargs)
-                
+        # the context must implement IReadMapping
+        for name,item in self.context.items():
+            itemPrefix = self.prefix and self.prefix+'.' or '' + name
+            if not ignore_request:
+                # check edit mode with row actions
+                self.checkEditMode(itemPrefix)
+            kwargs = {
+                'omit_readonly':False,
+                'render_context':True,
+                'fields':self.form_fields}
+            self.forms[name] = self.itemForm(item, **kwargs)
+            self.forms[name].setPrefix(itemPrefix)
+
+                                            
     def resetForm(self):
         self.setUpForms(ignore_request=True)
         for fo in self.forms.values():
             fo.resetForm()
 
     def validate(self, action, data):
+        # XXX implement this
 #        return (getFormsData(self.widgets, self.prefix, data)
 #                + checkInvariants(self.form_fields, data))
         return ()
@@ -249,22 +248,6 @@
             # build up new forms
             self.resetForm()
             form_reset = False
-          
-    def render(self):
-        # if the form has been updated, it will already have a result
-        return self.form_result
-#        if self.form_result is None:
-#            if self.form_reset:
-#                # we reset, in case data has changed in a way that
-#                # causes the widgets to have different data
-#                self.resetForm()
-#                for fo in self.forms.values():
-#                    fo.form_reset = True
-#                self.form_reset = False
-#            for fo in self.forms.values():
-#                fo.render()
-#            self.form_result = self.template()
-#        return self.form_result
 
     def error_views(self):
         for error in self.errors:
@@ -284,8 +267,8 @@
         """hand over action table action to row actions with same name, label
            of all selected rows."""
         selected = False
-        for fo in self.forms.values():
-            if fo.row.selected:
+        for formName,fo in self.forms.values():
+            if self.isSelected(formName):
                 # hand over submit of action to all forms
                 action = "%s.actions.%s" % (fo.prefix, name)
                 self.request.form[action] = label
@@ -296,3 +279,18 @@
         self.update()
         return self.render()
 
+
+    def isSelected(self,name):
+        # XXX get from request
+        return False
+
+    def render(self):
+        # if the form has been updated, it will already have a result
+        if self.form_result is None:
+            if self.form_reset:
+                # we reset, in case data has changed in a way that
+                # causes the widgets to have different data
+                self.resetForm()
+                self.form_reset = False
+            self.form_result = self.template()
+        return self.form_result

Modified: zope3org/trunk/src/zorg/multiform/tests.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/tests.py	2006-04-08 21:30:39 UTC (rev 66692)
+++ zope3org/trunk/src/zorg/multiform/tests.py	2006-04-08 21:30:52 UTC (rev 66693)
@@ -2,10 +2,45 @@
 import unittest
 from zope.testing.doctestunit import DocFileSuite, DocTestSuite
 from zope.app.testing import setup
-
+from zope import component
+import zope.schema.interfaces
+import zope.app.form.browser
+import zope.publisher.interfaces.browser
+import zope.app.form.interfaces
 def setUp(test):
-    setup.placefulSetUp()                   
+    setup.placefulSetUp()
 
+    component.provideAdapter(
+        zope.app.form.browser.TextWidget,
+        [zope.schema.interfaces.ITextLine,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.app.form.interfaces.IInputWidget,
+        )
+    component.provideAdapter(
+        zope.app.form.browser.UnicodeDisplayWidget,
+        [zope.schema.interfaces.ITextLine,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.app.form.interfaces.IDisplayWidget,
+        )
+    component.provideAdapter(
+        zope.app.form.browser.UnicodeDisplayWidget,
+        [zope.schema.interfaces.IInt,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.app.form.interfaces.IDisplayWidget,
+        )
+    component.provideAdapter(
+        zope.app.form.browser.IntWidget,
+        [zope.schema.interfaces.IInt,
+         zope.publisher.interfaces.browser.IBrowserRequest,
+         ],
+        zope.app.form.interfaces.IInputWidget,
+        )
+
+    
+
 def tearDown(test):
     setup.placefulTearDown()
 



More information about the Checkins mailing list