refactor field's value retreiving from the widget (eg 'display value' concept):
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 21 Jan 2010 10:42:37 +0100
changeset 4304 0b53e850cdb5
parent 4303 35e814dce815
child 4305 3d731478d9a8
refactor field's value retreiving from the widget (eg 'display value' concept): * kill field's display_value method, since getting value specified in a previous post or in req.form should be the widget responsibility (the widget nows what inputs to display, not the field) * new typed_value / format_value on widgets, mainly to ease overriding
web/formfields.py
web/formwidgets.py
--- a/web/formfields.py	Thu Jan 21 10:39:12 2010 +0100
+++ b/web/formfields.py	Thu Jan 21 10:42:37 2010 +0100
@@ -213,40 +213,6 @@
             return eid_param(id, form.edited_entity.eid)
         return id
 
-    def display_value(self, form):
-        """return field's *string* value to use for display
-
-        looks in
-        1. previously submitted form values if any (eg on validation error)
-        2. req.form
-        3. extra form args given to render_form
-        4. field's typed value
-
-        values found in 1. and 2. are expected te be already some 'display'
-        value while those found in 3. and 4. are expected to be correctly typed.
-        """
-        qname = self.input_name(form)
-        if qname in form.form_previous_values:
-            return form.form_previous_values[qname]
-        if qname in form._cw.form:
-            return form._cw.form[qname]
-        if self.name != qname and self.name in form._cw.form:
-            return form._cw.form[self.name]
-        for key in (self, qname):
-            try:
-                value = form.formvalues[key]
-                break
-            except:
-                continue
-        else:
-            if self.name != qname and self.name in form.formvalues:
-                value = form.formvalues[self.name]
-            else:
-                value = self.typed_value(form)
-        if value != INTERNAL_FIELD_VALUE:
-            value = self.format_value(form._cw, value)
-        return value
-
     def typed_value(self, form, load_bytes=False):
         if self.value is not _MARKER:
             if callable(self.value):
@@ -544,7 +510,7 @@
             if self.encoding_field:
                 wdgs.append(self.render_subfield(form, self.encoding_field, renderer))
             wdgs.append(u'</div>')
-        if not self.required and self.display_value(form):
+        if not self.required and self._typed_value(form):
             # trick to be able to delete an uploaded file
             wdgs.append(u'<br/>')
             wdgs.append(tags.input(name=self.input_name(form, u'__detach'),
@@ -805,16 +771,16 @@
         return vocab
 
     def form_init(self, form):
-        if not self.display_value(form):
-            value = form.edited_entity.linked_to(self.name, self.role)
-            if value:
-                searchedvalues = ['%s:%s:%s' % (self.name, eid, self.role)
-                                  for eid in value]
-                # remove associated __linkto hidden fields
-                for field in form.root_form.fields_by_name('__linkto'):
-                    if field.value in searchedvalues:
-                        form.root_form.remove_field(field)
-                form.formvalues[self] = value
+        #if not self.display_value(form):
+        value = form.edited_entity.linked_to(self.name, self.role)
+        if value:
+            searchedvalues = ['%s:%s:%s' % (self.name, eid, self.role)
+                              for eid in value]
+            # remove associated __linkto hidden fields
+            for field in form.root_form.fields_by_name('__linkto'):
+                if field.value in searchedvalues:
+                    form.root_form.remove_field(field)
+            form.formvalues[self] = value
 
     def _typed_value(self, form, load_bytes=False):
         entity = form.edited_entity
--- a/web/formwidgets.py	Thu Jan 21 10:39:12 2010 +0100
+++ b/web/formwidgets.py	Thu Jan 21 10:42:37 2010 +0100
@@ -51,8 +51,48 @@
         """
         raise NotImplementedError
 
+    def typed_value(self, form, field):
+        """return field's *typed* value specified in:
+        3. extra form values given to render()
+        4. field's typed value
+        """
+        qname = field.input_name(form)
+        for key in (field, qname):
+            try:
+                return form.formvalues[key]
+            except KeyError:
+                continue
+        if field.name != qname and field.name in form.formvalues:
+            return form.formvalues[field.name]
+        return field.typed_value(form)
+
+    def format_value(self, form, field, value):
+        return field.format_value(form._cw, value)
+
     def values_and_attributes(self, form, field):
-        values = field.display_value(form)
+        """found field's *string* value in:
+        1. previously submitted form values if any (eg on validation error)
+        2. req.form
+        3. extra form values given to render()
+        4. field's typed value
+
+        values found in 1. and 2. are expected te be already some 'display'
+        value while those found in 3. and 4. are expected to be correctly typed.
+
+        3 and 4 are handle by the .typed_value(form, field) method
+        """
+        qname = field.input_name(form)
+        if qname in form.form_previous_values:
+            values = form.form_previous_values[qname]
+        elif qname in form._cw.form:
+            values = form._cw.form[qname]
+        elif field.name != qname and field.name in form._cw.form:
+            # compat: accept attr=value in req.form to specify value of attr-subject
+            values = form._cw.form[field.name]
+        else:
+            values = self.typed_value(form, field)
+            if values != INTERNAL_FIELD_VALUE:
+                values = self.format_value(form, field, values)
         if not isinstance(values, (tuple, list)):
             values = (values,)
         attrs = dict(self.attrs)
@@ -551,5 +591,6 @@
             'domid': self.domid, 'href': self.href}
 
 
+# more widgets #################################################################
 
 # XXX EntityLinkComboBoxWidget, [Raw]DynamicComboBoxWidget