[Checkins] SVN: zope3org/trunk/src/zorg/multiform/ update

Bernd Dorn bernd.dorn at fhv.at
Sun Apr 9 09:34:45 EDT 2006


Log message for revision 66722:
  update

Changed:
  U   zope3org/trunk/src/zorg/multiform/README.txt
  A   zope3org/trunk/src/zorg/multiform/actions.txt
  U   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-09 13:27:07 UTC (rev 66721)
+++ zope3org/trunk/src/zorg/multiform/README.txt	2006-04-09 13:34:44 UTC (rev 66722)
@@ -91,28 +91,26 @@
     >>> class OrderForm2(ItemFormBase):
     ...     form_fields = form.Fields(IOrder,omit_readonly=False,
     ...     render_context=True)
-    ...     def update(self):
-    ...         super(OrderForm2,self).update()
     ...         
-    ...     @multiform.parentAction(u"Save")
+    ...     @multiform.parentAction(u"Save",condition=form.haveInputWidgets)
     ...     def handle_save_action(self, action, data):
     ...         form.applyChanges(self.context, self.form_fields,
     ...         data, self.adapters)
-    ...     def render(self):
+    ...         
+    ...     def template(self):
     ...         return '\n<div>%s</div>\n' % '</div><div>'.join([w() for w in
     ...     self.widgets])
 
 
 Now we have to set the factory on the OrdersForm.
 
-    >>> class OrdersForm2(OrdersForm):
+    >>> class OrdersForm2(MultiFormBase):
     ...     itemFormFactory=OrderForm2
-    ...     def __call__(self, ignore_request=False):
-    ...         self.setUpWidgets()
+    ...     def template(self):
     ...         res = u''
     ...         names = sorted(self.subForms.keys())
     ...         for name in names:
-    ...             res += '<div>%s</div>\n' % self.subForms[name]()
+    ...             res += '<div>%s</div>\n' % self.subForms[name].render()
     ...         return res
 
 
@@ -123,6 +121,12 @@
     >>> action
     <multiform.multiform.ParentAction object at ...>
 
+All available parent action names of the subforms are available through the
+subActions attribute of the multi form.
+
+    >>> pf.subActionNames
+    [u'actions.save']
+
 The name of the action is without the item key, because it is applied
  to all items.
 
@@ -152,8 +156,91 @@
     <div... value="new name 1" ...
     </div>
 
+The above example uses inputwidgets for all editable fields in the
+forms. In the next example we implement a multiform which uses
+displaywidgets per default. Inputwidgets should only be used if the
+'Edit' action is called.
 
+So let us define a new specialized item form class, which defines a
+new parent action called ``Edit``.
 
+    >>> def haveNoInputWidgets(f,action):
+    ...     return not form.haveInputWidgets(f,action)
+
+    >>> class OrderForm3(ItemFormBase):
+    ...     
+    ...     def __init__(self,context,request,parentForm):
+    ...         super(OrderForm3,self).__init__(context,request,parentForm)
+    ...         self.form_fields = form.Fields(IOrder,omit_readonly=False,
+    ...         render_context=True,for_display=True)
+    ...         
+    ...         
+    ...     @multiform.parentAction(u"Save",condition=form.haveInputWidgets)
+    ...     def handle_save_action(self, action, data):
+    ...         import pdb;pdb.set_trace()
+    ...         for field in self.form_fields:
+    ...             field.for_display=False
+    ...         form.setUpWidgets() 
+    ...         form.applyChanges(self.context, self.form_fields,
+    ...         data, self.adapters)
+    ...         
+    ...     @multiform.parentAction('Edit',condition=haveNoInputWidgets)
+    ...     def handle_edit_action(self, action, data):
+    ...         for field in self.form_fields:
+    ...             field.for_display=False
+    ...         self.form_reset=True
+    ...     def template(self):
+    ...         return '\n<div>%s</div>\n' % '</div><div>'.join([w() for w in
+    ...     self.widgets])
+
+
+    >>> class OrdersForm3(OrdersForm2):
+    ...     itemFormFactory=OrderForm3
+
+So in our new form all widgets are display widgets per default
+
+    >>> request = TestRequest()
+    >>> pf = OrdersForm3(orderMapping,request)
+    >>> print pf()
+    <div>
+    <div>0</div><div>new name 0</div>
+    </div>
+    <div>
+    <div>1</div><div>new name 1</div>
+    </div>
+
+And the save action should not be available, due to the reason that there
+are no input widgets in the sub forms.
+
+    >>> pf.subActionNames
+    [u'actions.edit']
+
+Now let's call the edit action to set the widgets to input widgets.
+
+    >>> request.form['form.actions.edit']=u''
+    >>> pf =  OrdersForm3(orderMapping,request)
+    >>> print pf()
+    <div>
+    <div...<input class="textType" ... value="new name 0" ...
+    </div>
+    <div>
+    <div...<input class="textType" ... value="new name 1" ...
+
+Now only the save action should be available.
+
+    >>> pf.subActionNames
+    [u'actions.save']
+
+Let us save some data.
+
+    >>> request = TestRequest()
+    >>> request.form['form.actions.save']=u''
+    >>> for i in range(2):
+    ...     request.form['form.%s.name' % i]='newer name %s' % i
+    ...     request.form['form.%s.identifier' % i]= i
+    >>> print OrdersForm3(orderMapping,request)()
+
+
 TODO:
 
 - encode prefix, do we have to do it?

Added: zope3org/trunk/src/zorg/multiform/actions.txt
===================================================================
--- zope3org/trunk/src/zorg/multiform/actions.txt	2006-04-09 13:27:07 UTC (rev 66721)
+++ zope3org/trunk/src/zorg/multiform/actions.txt	2006-04-09 13:34:44 UTC (rev 66722)
@@ -0,0 +1,103 @@
+So let us define a new specialized item form class, which defines a
+new parent action called ``Edit``.
+
+
+    >>> from multiform.multiform import ItemFormBase,MultiFormBase
+    >>> from zope.formlib import form
+    >>> from multiform import multiform
+    >>> from zope.publisher.browser import TestRequest
+    >>> 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(2)])
+
+    >>> def haveNoInputWidgets(f,action):
+    ...     return not form.haveInputWidgets(f,action)
+
+    >>> class OrderForm3(ItemFormBase):
+    ...     
+    ...     def __init__(self,context,request,parentForm):
+    ...         super(OrderForm3,self).__init__(context,request,parentForm)
+    ...         self.form_fields = form.Fields(IOrder,omit_readonly=False,
+    ...         render_context=True,for_display=True)
+    ...         
+    ...     @multiform.parentAction(u"Save",condition=form.haveInputWidgets)
+    ...     def handle_save_action(self, action, data):
+    ...         import pdb;pdb.set_trace()
+    ...         for field in self.form_fields:
+    ...             field.for_display=False
+    ...         form.setUpWidgets() 
+    ...         form.applyChanges(self.context, self.form_fields,
+    ...         data, self.adapters)
+    ...         
+    ...     @multiform.parentAction('Edit',condition=haveNoInputWidgets)
+    ...     def handle_edit_action(self, action, data):
+    ...         for field in self.form_fields:
+    ...             field.for_display=False
+    ...         self.form_reset=True
+    ...         
+    ...     def template(self):
+    ...         return '\n<div>%s</div>\n' % '</div><div>'.join([w() for w in
+    ...     self.widgets])
+
+
+    >>> class OrdersForm3(MultiFormBase):
+    ...     itemFormFactory=OrderForm3
+    ...     def template(self):
+    ...         res = u''
+    ...         names = sorted(self.subForms.keys())
+    ...         for name in names:
+    ...             res += '<div>%s</div>\n' % self.subForms[name].render()
+    ...         return res
+
+So in our new form all widgets are display widgets per default
+
+    >>> request = TestRequest()
+    >>> pf = OrdersForm3(orderMapping,request)
+    >>> print pf()
+    <div>
+    <div>0</div><div>n0</div>
+    </div>
+    <div>
+    <div>1</div><div>n1</div>
+    </div>
+
+And the save action should not be available, due to the reason that there
+are no input widgets in the sub forms.
+
+    >>> pf.subActionNames
+    [u'actions.edit']
+
+Now let's call the edit action to set the widgets to input widgets.
+
+    >>> request.form['form.actions.edit']=u''
+    >>> pf =  OrdersForm3(orderMapping,request)
+    >>> print pf()
+    <div>
+    <div...<input class="textType" ... value="n0" ...
+    </div>
+    <div>
+    <div...<input class="textType" ... value="n1" ...
+
+Now only the save action should be available.
+
+    >>> pf.subActionNames
+    [u'actions.save']
+
+Let us save some data.
+
+    >>> request = TestRequest()
+    >>> request.form['form.actions.save']=u''
+    >>> for i in range(2):
+    ...     request.form['form.%s.name' % i]='newer name %s' % i
+    ...     request.form['form.%s.identifier' % i]= i
+    >>> print OrdersForm3(orderMapping,request)()
+

Modified: zope3org/trunk/src/zorg/multiform/interfaces.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/interfaces.py	2006-04-09 13:27:07 UTC (rev 66721)
+++ zope3org/trunk/src/zorg/multiform/interfaces.py	2006-04-09 13:34:44 UTC (rev 66722)
@@ -1,7 +1,10 @@
 from zope.interface import Interface
+from zope.formlib.interfaces import IAction
 
-
 class IMultiForm(Interface):
 
     """multiform"""
 
+
+class IParentAction(IAction):
+    """a parent action"""

Modified: zope3org/trunk/src/zorg/multiform/multiform.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/multiform.py	2006-04-09 13:27:07 UTC (rev 66721)
+++ zope3org/trunk/src/zorg/multiform/multiform.py	2006-04-09 13:34:44 UTC (rev 66722)
@@ -1,20 +1,21 @@
 from zope.app.publisher.browser import BrowserView
 from zope.interface import implements
-
 from zope.app import zapi
 from zope.app.form.browser.interfaces import IWidgetInputErrorView
 
 from zope.formlib import form
 from zope.formlib.interfaces import IBoundAction
 from zope.formlib.i18n import _
-from interfaces import IMultiForm
+from interfaces import IMultiForm, IParentAction
 from zope import interface
 
 class ParentAction(form.Action):
 
     """an action that is rendered in the parent multiform object and
     is applied to all subForms"""
-
+    
+    implements(IParentAction)
+    
     def __get__(self, form, class_=None):
         if form is None:
             return self
@@ -50,32 +51,66 @@
         super(ItemFormBase,self).__init__(context,request)
         self.parentForm=parentForm
 
+    def update(self):
+        super(ItemFormBase,self).update()
+        
+    def availableParentActions(self):
+        actions=[]
+        if hasattr(self,'actions'):
+            for action in self.actions:
+                if IParentAction.providedBy(action):
+                    actions.append(action)
+                    
+        actions= form.availableActions(self, actions)
+        return actions
 
-
 class MultiFormBase(form.FormBase):
 
 
     itemFormFactory = ItemFormBase
     subForms={}
     form_fields = []
-
-
+    actions = []
+    subActionNames = []
+    
     def update(self):
         super(MultiFormBase,self).update()
+        subFormReset = False
         for form in self.subForms.values():
             form.update()
+            if form.form_result is None:
+                if form.form_reset:
+                    subFormReset=True
+                    form.resetForm()
+                    form.form_reset=False
+        if subFormReset:
+            self.refreshSubActionNames()
 
+
     def setUpWidgets(self, *args, **kw):
         super(MultiFormBase,self).setUpWidgets(*args,**kw)
         self.subForms = {}
         self.setUpForms(*args, **kw)
 
     def setUpForms(self, *args, **kw):
-        for name,item in self.context.items():
+
+        for name,item in self.context.items(): 
             prefix = (self.prefix and self.prefix+'.' or '') + name
             subForm = self.itemFormFactory(item,self.request,self)
             subForm.setPrefix(prefix)
             subForm.setUpWidgets(*args, **kw)
             self.subForms[name] = subForm
+        self.refreshSubActionNames()
 
-
+    def refreshSubActionNames(self):
+        availableActions = set()
+        for subForm in self.subForms.values():
+            availableActions.update([action.__name__ for action in \
+                                     subForm.availableParentActions()])
+        self.subActionNames = []
+        if hasattr(self.itemFormFactory,'actions'):
+            for action in self.itemFormFactory.actions:
+                if action.__name__ in availableActions:
+                    self.subActionNames.append(action.__name__)
+                    
+            

Modified: zope3org/trunk/src/zorg/multiform/tests.py
===================================================================
--- zope3org/trunk/src/zorg/multiform/tests.py	2006-04-09 13:27:07 UTC (rev 66721)
+++ zope3org/trunk/src/zorg/multiform/tests.py	2006-04-09 13:34:44 UTC (rev 66722)
@@ -53,6 +53,10 @@
                      setUp=setUp, tearDown=tearDown,
                      optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
                      ),
+        DocFileSuite('actions.txt',
+                     setUp=setUp, tearDown=tearDown,
+                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+                     ),
         ))
 
 



More information about the Checkins mailing list