[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