SVN: r24005 - trunk/quixote/form2

Anton Benard <abenard-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Mon, 19 Apr 2004 14:24:15 -0400
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Author: abenard
Date: 2004-04-19 14:24:15 -0400 (Mon, 19 Apr 2004)
New Revision: 24005

Modified:
   trunk/quixote/form2/form.py
   trunk/quixote/form2/widget.py
Log:
- Fix .clear_errors() for form2 Form. Errors can only be reliably cleared
  after the widget has parsed.
- Add .render_title() to make title rendering more consitent with hint and
  error rendering.
- Fix SubmitWidget .__init__() to set the .value to None.
- Fix OptionSelect to always return a value from the options list.
- Fix some bugs in WidgetList.


Modified: trunk/quixote/form2/form.py
===================================================================
--- trunk/quixote/form2/form.py	2004-04-19 15:51:11 UTC (rev 24004)
+++ trunk/quixote/form2/form.py	2004-04-19 18:24:15 UTC (rev 24005)
@@ -156,7 +156,9 @@
         return False
 
     def clear_errors(self):
+        request = get_request()
         for widget in self.get_all_widgets():
+            widget.parse(request)
             widget.set_error(None)
 
     def get_submit(self):
@@ -290,6 +292,13 @@
                         'See below for details.'
                         '</td></tr>')
 
+    def render_title(self, title, required):
+        if required:
+            title += htmltext('&nbsp;*')
+        return htmltext('<tr><th colspan="3" align="left">'
+                        '%s'
+                        '</th></tr>') % title
+
     def render_error(self, error):
         return htmltext('<font color="red">%s</font><br />') % nl2br(error)
 
@@ -297,14 +306,10 @@
         return htmltext('<em>%s</em>') % hint
 
     def render_field(self, title, contents, hint, error, required=False):
-        title = title or ''
-        if title and required:
-            title = title + htmltext('&nbsp;*')
         r = TemplateIO(html=True)
-        r += htmltext('<tr><th colspan="3" align="left">')
-        r += title
-        r += htmltext('</th></tr>'
-                      '<tr><td>&nbsp;&nbsp;</td><td>')
+        if title:
+            r += self.render_title(title, required)
+        r += htmltext('<tr><td>&nbsp;&nbsp;</td><td>')
         r += contents
         r += htmltext('</td><td>')
         if error:

Modified: trunk/quixote/form2/widget.py
===================================================================
--- trunk/quixote/form2/widget.py	2004-04-19 15:51:11 UTC (rev 24004)
+++ trunk/quixote/form2/widget.py	2004-04-19 18:24:15 UTC (rev 24005)
@@ -524,7 +524,7 @@
     HTML_TYPE = "button"
 
     def __init__(self, name, value=None, **kwargs):
-        Widget.__init__(self, name, value, **kwargs)
+        Widget.__init__(self, name, value=None, **kwargs)
         self.label = value
 
     def set_error(self, error):
@@ -626,11 +626,11 @@
 
 
 class OptionSelectWidget(SingleSelectWidget):
-    """Widget for single selection with automatic submission and early
-    parsing.  This widget parses the request when it is created.  This
-    allows its value to be used to decide what other widgets need to be
-    created in a form.  It's a powerful feature but it can be hard to
-    understand what's going on.
+    """Widget for single selection with automatic submission. Parse
+    will always return a value from it's options, even if the form is
+    not submitted. This allows its value to be used to decide what
+    other widgets need to be created in a form.  It's a powerful
+    feature but it can be hard to understand what's going on.
 
     Instance attributes:
       value : any
@@ -642,6 +642,24 @@
         SingleSelectWidget.__init__(self, name, value, options=options,
                                     onchange='submit()', **kwargs)
 
+    def parse(self, request=None):
+        if not self._parsed:
+            if request is None:
+                request = get_request()
+            self._parse(request)
+            self._parsed = True
+        return self.value
+
+    def _parse(self, request):
+        parsed_key = request.form.get(self.name)
+        if parsed_key:
+            if type(parsed_key) is ListType:
+                self.error = "cannot select multiple values"
+            else:
+                self.value = self._parse_single_selection(parsed_key)
+        elif self.value is None:
+            self.value = self.options[0][0]
+
     def render(self):
         return (SingleSelectWidget.render(self) +
                 htmltext('<noscript>'
@@ -715,23 +733,16 @@
       element_names : [string]
     """
 
-    def __init__(self,
-                 name,
-                 element_type=StringWidget,
-                 value=None,
-                 element_name="row",
-                 title="",
-                 hint="",
-                 required=False,
-                 **kwargs):
+    def __init__(self, name, value=None,
+                 element_type=StringWidget, element_name="row", **kwargs):
         assert value is None or type(value) is ListType, (
             "value '%s' not a list: got %r" % (name, value))
         assert type(element_name) in (StringType, htmltext), (
             "value '%s' element_name not a string: "
             "got %r" % (name, element_name))
-        CompositeWidget.__init__(self, name, value, title=title, hint=hint,
-                                 required=required)
 
+        CompositeWidget.__init__(self, name, value, **kwargs)
+
         self.element_names = []
         def add_element(value=None):
             name = "element%d" % len(self.element_names)
@@ -745,10 +756,10 @@
         num_added = int(self["added_elements"] or 1)
         for i in range(num_added):
             add_element()
-        if self.add_button.parse():
+        if self.get('add_element'):
             add_element()
             num_added += 1
-        self.added_elements.set_value(num_added)
+        self.get_widget('added_elements').set_value(num_added)
 
     def _parse(self, request):
         values = []
@@ -760,15 +771,10 @@
 
     def form_render(self, form):
         r = TemplateIO(html=True)
-        widget = self.get_widget(self.element_names[0])
-        r += form.render_field(self.title,
-                               widget.render(),
-                               self.hint,
-                               self.error or widget.get_error(),
-                               self.required)
-        for name in self.element_names[1:]:
-            widget = self.get_widget(name)
-            r += form.render_field('', widget.render(), '', widget.get_error())
-        r += self.get_widget("add_button").render()
-        r += self.get_widget("added_elements").render()
+        if self.title:
+            r += form.render_title(self.title, self.required)
+        for name in self.element_names:
+            r += self.get_widget(name).form_render(form)
+        r += self.get_widget("add_element").form_render(form)
+        r += self.get_widget("added_elements").form_render(form)
         return r.getvalue()