durusmail: quixote-users: some form2 enhancement proposals
some form2 enhancement proposals
2004-10-01
some form2 enhancement proposals
stietke@diw.de
2004-10-01
Hello everybody,

I am using Quixote and form2 and I must say I am extremely happy
with it. There are a few enhancements I would like to propose.

*** a 'deaf' attribute:

I would like to make it possible to create forms that _don't_ listen
to the POST data, e.g. I receive form input, store some data to a
database, read some new data from a database and display a new form
with new values, but the widget's names are often identical to the
ones used for the POST data. If I don't make the new form 'deaf', they
POST data interferes with my new values. Other uses include several
forms on one page, where you only want one of them to react to user
input.

*** a set_title() method:

Is there a reason why the set_title() method is missing? If not, I
propose there should be one.

*** localisation:

I think for us international users it would be nice if strings that
show up in the user interface were not hardcoded into the source code,
but could get translated somehow independently from the source. There
are a few hard coded strings both in form.py and widget.py, e.g. in
Form --> _render_error_notice, the 'required' string in Widget -->
parse, the error messages in IntWidget and FloatWidget. I'm not sure
what the best method for doing this would be, currently I turned a lot
of those strings into class level constants, which i override after
importing the widget, but there might be a better way.

*** double escape trouble

in ButtonWidget --> render_content I had trouble with the line
value = (self.label and htmlescape(self.label) or None)
My labels ended up getting double escaped. From what I understand from
the sources, this method calls htmltag() with value being one of the
attributes. htmltag() calls _escape_string() on its attributes, so if
value was already htmlescape()'d it now gets escaped a second time.
I changed that to simply value = self.label and it seems to work for
me, but am I missing something here?


So long,
Stefan

the patches:

*** a 'deaf' attribute:

in class Widget:

-------- 8< ------------- 8< ------------- 8< -------------
     def __init__(self, name, value=None, title="", hint="",
                  required=False,
-                 render_br=True, attrs=None, **kwattrs):
+                 render_br=True, deaf = False, attrs=None,**kwattrs):
         assert self.__class__ is not Widget, "abstract class"
         self.name = name
         self.value = value
         self.error = None
         self.title = title
         self.hint = hint
         self.required = required
         self.render_br = render_br
+        self.deaf = deaf
         self.attrs = merge_attrs(attrs, kwattrs)
         self._parsed = False
-------- 8< ------------- 8< ------------- 8< -------------

-------- 8< ------------- 8< ------------- 8< -------------
     def parse(self, request=None):
         if not self._parsed:
             self._parsed = True
             if request is None:
                 request = get_request()
-            if request.form:
+            if not self.deaf and request.form:
                 try:
                     self._parse(request)
                 except WidgetValueError, exc:
                     self.set_error(str(exc))
                 if (self.required and self.value is None and
                     not self.has_error()):
                     self.set_error('required')
         return self.value
-------- 8< ------------- 8< ------------- 8< -------------

in class OptionSelectWidget:

-------- 8< ------------- 8< ------------- 8< -------------
     def parse(self, request=None):
         if not self._parsed:
             if request is None:
                 request = get_request()
-            self._parse(request)
+            if not self.deaf:
+               self._parse(request)
             self._parsed = True
         return self.value
-------- 8< ------------- 8< ------------- 8< -------------

*** a set_title() method:

in class Widget:

-------- 8< ------------- 8< ------------- 8< -------------
     def clear_error(self, request=None):
         self.parse(request=request)
         self.error = None

+    def set_title(self, title):
+        self.title = title
+
     def get_title(self):
         return self.title

     def set_hint(self, hint):
         self.hint = hint
-------- 8< ------------- 8< ------------- 8< -------------


reply