Author: ianb
Date: 2009-02-11 12:16:15 -0700 (Wed, 11 Feb 2009)
New Revision: 3784

Modified:
   FormEncode/trunk/docs/htmlfill.txt
   FormEncode/trunk/docs/news.txt
   FormEncode/trunk/formencode/htmlfill.py
   FormEncode/trunk/tests/test_htmlfill.py
Log:
Add force_defaults argument to htmlfill.render, which will uncheck checkboxes 
and other controls when a value is missing from the defaults.  From desmaj

Modified: FormEncode/trunk/docs/htmlfill.txt
===================================================================
--- FormEncode/trunk/docs/htmlfill.txt  2009-02-06 13:56:26 UTC (rev 3783)
+++ FormEncode/trunk/docs/htmlfill.txt  2009-02-11 19:16:15 UTC (rev 3784)
@@ -37,7 +37,7 @@
 to errors.
 
 See `formencode.htmlfill.render for more
-<module-formencode.htmlfill.html#render>`_ for more.
+<modules/htmlfill.html#formencode.htmlfill.render>`_ for more.
 
 Errors
 ------

Modified: FormEncode/trunk/docs/news.txt
===================================================================
--- FormEncode/trunk/docs/news.txt      2009-02-06 13:56:26 UTC (rev 3783)
+++ FormEncode/trunk/docs/news.txt      2009-02-11 19:16:15 UTC (rev 3784)
@@ -3,6 +3,14 @@
 
 .. contents::
 
+svn trunk
+---------
+
+* Added keyword argument ``force_defaults`` to
+  :func:`formencode.htmlfill.render`; when this is True (the default)
+  this will uncheck checkboxes, unselect select boxes, etc., when a
+  value is missing from the default dictionary.  
+
 1.2.1
 -----
 

Modified: FormEncode/trunk/formencode/htmlfill.py
===================================================================
--- FormEncode/trunk/formencode/htmlfill.py     2009-02-06 13:56:26 UTC (rev 
3783)
+++ FormEncode/trunk/formencode/htmlfill.py     2009-02-11 19:16:15 UTC (rev 
3784)
@@ -15,7 +15,8 @@
            error_formatters=None, add_attributes=None,
            auto_insert_errors=True, auto_error_formatter=None,
            text_as_default=False, listener=None, encoding=None,
-           error_class='error', prefix_error=True):
+           error_class='error', prefix_error=True,
+           force_defaults=True):
     """
     Render the ``form`` (which should be a string) given the defaults
     and errors.  Defaults are the values that go in the input fields
@@ -59,6 +60,13 @@
     
     ``prefix_error`` specifies if the HTML created by auto_error_formatter is
     put before the input control (default) or after the control.
+    
+    ``force_defaults`` specifies if a field default is not given in
+    the ``defaults`` dictionary then the control associated with the
+    field should be set as an unsuccessful control. So checkboxes will
+    be cleared, radio and select controls will have no value selected,
+    and textareas will be emptied. This defaults to ``True``, which is
+    appropriate the defaults are the result of a form submission.
     """
     if defaults is None:
         defaults = {}
@@ -74,6 +82,7 @@
         listener=listener, encoding=encoding,
         prefix_error=prefix_error,
         error_class=error_class,
+        force_defaults=force_defaults,
         )
     p.feed(form)
     p.close()
@@ -175,13 +184,15 @@
                  error_formatters=None, error_class='error',
                  add_attributes=None, listener=None,
                  auto_error_formatter=None,
-                 text_as_default=False, encoding=None, prefix_error=True):
+                 text_as_default=False, encoding=None, prefix_error=True,
+                 force_defaults=True):
         RewritingParser.__init__(self)
         self.source = None
         self.lines = None
         self.source_pos = None
         self.defaults = defaults
         self.in_textarea = None
+        self.skip_textarea = False
         self.last_textarea_name = None
         self.in_select = None
         self.skip_next = False        
@@ -204,7 +215,8 @@
         self.text_as_default = text_as_default
         self.encoding = encoding
         self.prefix_error = prefix_error
-
+        self.force_defaults = force_defaults
+    
     def str_compare(self, str1, str2):
         """
         Compare the two objects as strings (coercing to strings if necessary).
@@ -262,7 +274,7 @@
         self._text = self._get_text()
 
     def skip_output(self):
-        return self.in_textarea or self.skip_error
+        return (self.in_textarea and self.skip_textarea) or self.skip_error
 
     def add_key(self, key):
         self.used_keys[key] = 1
@@ -362,7 +374,10 @@
             self.skip_next = True
             self.add_key(name)
         elif t == 'checkbox':
-            selected = False
+            if self.force_defaults:
+                selected = False
+            else:
+                selected = self.get_attr(attrs, 'checked')
             if not self.get_attr(attrs, 'value'):
                 selected = value
             elif self.selected_multiple(value,
@@ -378,7 +393,7 @@
         elif t == 'radio':
             if self.str_compare(value, self.get_attr(attrs, 'value', '')):
                 self.set_attr(attrs, 'checked', 'checked')
-            else:
+            elif self.force_defaults or name in self.defaults:
                 self.del_attr(attrs, 'checked')
             self.write_tag('input', attrs, startend)
             self.skip_next = True
@@ -421,15 +436,21 @@
         if (self.error_class
             and self.errors.get(name)):
             self.add_class(attrs, self.error_class)
-        self.write_tag('textarea', attrs)
         value = self.defaults.get(name, '')
-        self.write_text(html_quote(value))
-        self.write_text('</textarea>')
+        if value or self.force_defaults:
+            self.write_tag('textarea', attrs)
+            self.write_text(html_quote(value))
+            self.write_text('</textarea>')
+            self.skip_textarea = True
         self.in_textarea = True
         self.last_textarea_name = name
         self.add_key(name)
 
     def handle_end_textarea(self):
+        if self.skip_textarea:
+            self.skip_textarea = False
+        else:
+            self.write_text('</textarea>')            
         self.in_textarea = False
         self.skip_next = True
         if not self.prefix_error:
@@ -461,13 +482,13 @@
             % self.getpos())
         if self.in_select != False:
             default = self.defaults.get(self.in_select, '')
-
-            if self.selected_multiple(self.defaults.get(self.in_select, ''),
-                                      self.get_attr(attrs, 'value', '')):
-                self.set_attr(attrs, 'selected', 'selected')
-                self.add_key(self.in_select)
-            else:
-                self.del_attr(attrs, 'selected')
+            if self.force_defaults:
+                if self.selected_multiple(self.defaults.get(self.in_select, 
''),
+                                          self.get_attr(attrs, 'value', '')):
+                    self.set_attr(attrs, 'selected', 'selected')
+                    self.add_key(self.in_select)
+                else:
+                    self.del_attr(attrs, 'selected')
         self.write_tag('option', attrs)
         self.skip_next = True
 

Modified: FormEncode/trunk/tests/test_htmlfill.py
===================================================================
--- FormEncode/trunk/tests/test_htmlfill.py     2009-02-06 13:56:26 UTC (rev 
3783)
+++ FormEncode/trunk/tests/test_htmlfill.py     2009-02-11 19:16:15 UTC (rev 
3784)
@@ -133,3 +133,132 @@
     assert (htmlfill.render(u'<input type="checkbox" name="tags" value="2" />',
                            dict(tags=[])) == 
             '<input type="checkbox" name="tags" value="2" />')
+
+def test_defaults_not_form_submission_textarea():
+    html = """<textarea name="textarea-1" class="my_textarea">i like this 
text</textarea>"""
+    rendered_html = htmlfill.render(html, defaults=dict(),
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_textarea_value():
+    html = """<textarea name="textarea-1" class="my_textarea">i like this 
text</textarea>"""
+    expected_html = """<textarea name="textarea-1" class="my_textarea">this 
text is better</textarea>"""
+    rendered_html = htmlfill.render(html, defaults={"textarea-1": "this text 
is better"},
+                                    defaults_as_form_submission=False)
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_as_form_submission_textarea():
+    html = """<textarea name="textarea-1" class="my_textarea">i like this 
text</textarea>"""
+    expected_html = \
+        """<textarea name="textarea-1" class="my_textarea"></textarea>"""
+    rendered_html = htmlfill.render(html, defaults=dict())
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_checkbox():
+    html = """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
checked="checked" value="cb">"""
+    rendered_html = htmlfill.render(html, defaults=dict(),
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+
+def test_defaults_as_form_submission_checkbox():
+    html = """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
checked="checked" value="cb">"""
+    expected_html = \
+        """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
value="cb">"""
+    rendered_html = htmlfill.render(html, defaults=dict())
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_checkbox_default_unchecked():
+    html = """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
checked="checked" value="cb">"""
+    expected_html = \
+        """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
value="cb">"""
+    rendered_html = htmlfill.render(html, defaults={"checkbox-1": False})
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_checkbox_default_checked():
+    html = """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
value="cb">"""
+    expected_html = \
+        """<input type="checkbox" name="checkbox-1" class="my_checkbox" 
value="cb" checked="checked">"""
+    rendered_html = htmlfill.render(html, defaults={"checkbox-1": "cb"},
+                                    defaults_as_form_submission=False)
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_radio():
+    html = """<input type="radio" name="radio-1" class="my_radio" 
checked="checked" value="cb">"""
+    rendered_html = htmlfill.render(html, defaults=dict(),
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_radio_unchecked():
+    html = """<input type="radio" name="radio-1" class="my_radio" 
checked="checked" value="cb">"""
+    expected_html = """<input type="radio" name="radio-1" class="my_radio" 
value="cb">"""
+    rendered_html = htmlfill.render(html, defaults={"radio-1": "ba"},
+                                    defaults_as_form_submission=False)
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_radio_checked():
+    html = """<input type="radio" name="radio-1" class="my_radio" 
value="cb">"""
+    expected_html = """<input type="radio" name="radio-1" class="my_radio" 
value="cb" checked="checked">"""
+    rendered_html = htmlfill.render(html, defaults={"radio-1": "cb"},
+                                    defaults_as_form_submission=False)
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_as_form_submission_radio():
+    html = """<input type="radio" name="radio-1" class="my_radio" 
checked="checked" value="cb">"""
+    expected_html = """<input type="radio" name="radio-1" class="my_radio" 
value="cb">"""
+    rendered_html = htmlfill.render(html, defaults=dict())
+    assert expected_html == rendered_html, rendered_html
+
+def test_defaults_not_form_submission_select():
+    html = """
+<select name="select-1" class="my_select">
+  <option value="option-1" selected="selected">this is option-1</option>
+</select>
+"""
+    rendered_html = htmlfill.render(html, defaults=dict(),
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+    
+def test_defaults_not_form_submission_select_selected():
+    html = """
+<select name="select-1" class="my_select">
+  <option value="option-1">this is option-1</option>
+</select>
+"""
+    expected_html = """
+<select name="select-1" class="my_select">
+  <option value="option-1" selected="selected">this is option-1</option>
+</select>
+"""
+    rendered_html = htmlfill.render(html, defaults={"select-1": "option-1"},
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+    
+def test_defaults_not_form_submission_select_not_selected():
+    html = """
+<select name="select-1" class="my_select">
+  <option value="option-1" selected="selected">this is option-1</option>
+</select>
+"""
+    expected_html = """
+<select name="select-1" class="my_select">
+  <option value="option-1">this is option-1</option>
+</select>
+"""
+    rendered_html = htmlfill.render(html, defaults={"select-1": "option-2"},
+                                    defaults_as_form_submission=False)
+    assert html == rendered_html, rendered_html
+
+def test_defaults_as_form_submission_select():
+    html = """
+<select name="select-1" class="my_select">
+  <option value="option-1" selected="selected">this is option-1</option>
+</select>
+"""
+    expected_html = """
+<select name="select-1" class="my_select">
+  <option value="option-1">this is option-1</option>
+</select>
+"""
+    rendered_html = htmlfill.render(html, defaults=dict())
+    assert expected_html == rendered_html, rendered_html
+


------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com
_______________________________________________
FormEncode-CVS mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/formencode-cvs

Reply via email to