Updated groups management
authorThierry Florac <thierry.florac@onf.fr>
Thu, 03 May 2018 11:34:51 +0200
changeset 102 728821df9e89
parent 101 ba1d62478119
child 103 d06578da5e84
Updated groups management
src/pyams_form/form.py
src/pyams_form/group.py
src/pyams_form/interfaces/form.py
--- a/src/pyams_form/form.py	Wed May 02 15:44:53 2018 +0200
+++ b/src/pyams_form/form.py	Thu May 03 11:34:51 2018 +0200
@@ -130,6 +130,11 @@
         [tabform.update() for tabform in self.tabforms]
         Form.update(self)
 
+    def updateWidgets(self, prefix=None):
+        super(BaseForm, self).updateWidgets(prefix)
+        if not self._groups:
+            self.updateGroups()
+
     def get_form_action(self):
         return self.action
 
@@ -151,6 +156,17 @@
     def forms(self):
         return [self, ] + self.subforms + self.tabforms
 
+    def get_forms(self, include_self=True):
+        if include_self:
+            yield self
+        for group in self.groups:
+            for subform in group.subforms:
+                yield subform
+        for form in self.subforms:
+            yield form
+        for form in self.tabforms:
+            yield form
+
     @reify
     def warn_on_change(self):
         if self._warn_on_change is True:
@@ -178,9 +194,7 @@
 
     def update_content(self, content, data):
         changes = applyChanges(self, content, data.get(self, data))
-        subforms = self.subforms + self.tabforms
-        [subforms.extend(group.subforms) for group in self.groups]
-        for subform in subforms:
+        for subform in self.get_forms(include_self=False):
             if subform.mode == DISPLAY_MODE:
                 continue
             subform_update = ICustomUpdateSubForm(subform, None)
@@ -196,10 +210,12 @@
         request = self.request
         if isinstance(request, PyramidPublisherRequest):
             request = request._request
-        cdict = {'context': self.context,
-                 'request': request,
-                 'view': self,
-                 'translate': queryUtility(IChameleonTranslate)}
+        cdict = {
+            'context': self.context,
+            'request': request,
+            'view': self,
+            'translate': queryUtility(IChameleonTranslate)
+        }
         if self.template is None:
             registry = request.registry
             template = registry.queryMultiAdapter((self, request, self.context), IContentTemplate)
@@ -216,10 +232,12 @@
         request = self.request
         if isinstance(request, PyramidPublisherRequest):
             request = request._request
-        cdict = {'context': self.context,
-                 'request': request,
-                 'view': self,
-                 'translate': queryUtility(IChameleonTranslate)}
+        cdict = {
+            'context': self.context,
+            'request': request,
+            'view': self,
+            'translate': queryUtility(IChameleonTranslate)
+        }
         cdict.update(kwargs)
         if self.layout is None:
             registry = request.registry
@@ -255,8 +273,10 @@
     def get_ajax_errors(self, ajax_errors=None):
         """Extract form errors in AJAX format"""
         translate = self.request.localizer.translate
-        errors = {'status': u'error',
-                  'error_message': translate(self.status)}
+        errors = {
+            'status': u'error',
+            'error_message': translate(self.status)
+        }
         registry = self.request.registry
         for error in (ajax_errors or self.errors):
             if isinstance(error, Exception):
@@ -268,22 +288,30 @@
                     if hasattr(inner_error, 'widget'):
                         widget = inner_error.widget
                         if widget is not None:
-                            errors.setdefault('widgets', []).append({'name': widget.name,
-                                                                     'label': translate(widget.label),
-                                                                     'message': translate(inner_error.message)})
+                            errors.setdefault('widgets', []).append({
+                                'name': widget.name,
+                                'label': translate(widget.label),
+                                'message': translate(inner_error.message)
+                            })
                         else:
-                            errors.setdefault('messages', []).append({'message': translate(inner_error.message)})
+                            errors.setdefault('messages', []).append({
+                                'message': translate(inner_error.message)
+                            })
                     else:
                         errors.setdefault('messages', []).append(translate(inner_error.message))
             else:
                 if hasattr(error, 'widget'):
                     widget = error.widget
                     if widget is not None:
-                        errors.setdefault('widgets', []).append({'name': widget.name,
-                                                                 'label': translate(widget.label),
-                                                                 'message': translate(error.message)})
+                        errors.setdefault('widgets', []).append({
+                            'name': widget.name,
+                            'label': translate(widget.label),
+                            'message': translate(error.message)
+                        })
                     else:
-                        errors.setdefault('messages', []).append({'message': translate(error.message)})
+                        errors.setdefault('messages', []).append({
+                            'message': translate(error.message)
+                        })
                 else:
                     errors.setdefault('messages', []).append(translate(error.message))
         return errors
@@ -291,7 +319,7 @@
     def get_ajax_output(self, changes):
         """Extract AJAX POST output"""
         output = {}
-        for form in self.subforms + self.tabforms:
+        for form in self.get_forms(include_self=False):
             try:
                 form_output = form.get_ajax_output(changes)
                 if form_output:
@@ -350,10 +378,11 @@
     def __call__(self):
         self.request.registry.notify(PageletCreatedEvent(self))
         data, errors = {}, ()
-        for form in self.forms:
+        for form in self.get_forms():
             form.check_mode()
             form.updateWidgets()
             form.updateActions()
+        for form in self.get_forms():
             form_data, form_errors = form.extractData()
             data[form] = form_data
             errors = errors + form_errors
@@ -364,7 +393,7 @@
         except ValidationError as error:
             # This error can occur with file-type inputs
             registry = self.request.registry
-            for form in self.forms:
+            for form in self.get_forms():
                 try:
                     widget = form.widgets[error.args[-1]]
                 except KeyError:
@@ -387,7 +416,7 @@
 
     def get_ajax_output(self, changes):
         output = {}
-        for form in self.subforms + self.tabforms:
+        for form in self.get_forms(include_self=False):
             try:
                 form_output = form.get_ajax_output(changes)
                 if form_output:
@@ -464,10 +493,11 @@
         # call form elements
         self.request.registry.notify(PageletCreatedEvent(self))
         data, errors = {}, ()
-        for form in self.forms:
+        for form in self.get_forms():
             form.check_mode()
             form.updateWidgets()
             form.updateActions()
+        for form in self.get_forms():
             form_data, form_errors = form.extractData()
             data[form] = form_data
             errors = errors + form_errors
@@ -480,7 +510,7 @@
         except ValidationError as error:
             # This error can occur with file-type inputs
             registry = self.request.registry
-            for form in self.forms:
+            for form in self.get_forms():
                 try:
                     widget = form.widgets[error.args[-1]]
                 except KeyError:
@@ -517,7 +547,7 @@
 
     def get_ajax_output(self, changes):
         output = {}
-        for form in self.subforms + self.tabforms:
+        for form in self.get_forms(include_self=False):
             if form.mode == DISPLAY_MODE:
                 continue
             try:
--- a/src/pyams_form/group.py	Wed May 02 15:44:53 2018 +0200
+++ b/src/pyams_form/group.py	Thu May 03 11:34:51 2018 +0200
@@ -137,6 +137,9 @@
     def update(self):
         [subform.update() for subform in self.subforms]
 
+    def update_content(self, content, data):
+        [subform.update_content(content, data) for subform in self.subforms]
+
 
 def NamedWidgetsGroup(form, id, widgets, names=(), bordered=True, fieldset_class=None, legend=None, help=None,
                       css_class='', switch=False, checkbox_switch=False, checkbox_field=None, checkbox_mode='hide',
@@ -182,3 +185,6 @@
                                               legend=self.main_group_legend,
                                               css_class=self.main_group_class))
         return result
+
+    def updateGroups(self):
+        [group.update() for group in self.groups]
--- a/src/pyams_form/interfaces/form.py	Wed May 02 15:44:53 2018 +0200
+++ b/src/pyams_form/interfaces/form.py	Thu May 03 11:34:51 2018 +0200
@@ -136,6 +136,9 @@
     def get_form_action(self):
         """Get form action URL"""
 
+    def get_forms(self, include_self=True):
+        """Get an iterator over all forms and subforms"""
+
     def get_widget_callback(self, widget):
         """Get submit callback associated with a given widget"""
 
@@ -273,6 +276,9 @@
     def add_group(self, group):
         """Add given group to form groups"""
 
+    def updateGroups(self):
+        """Update inner groups state"""
+
 
 class IViewletsBasedForm(IBaseForm):
     """Viewlets based form"""