drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 21 Dec 2009 19:18:49 +0100
changeset 4156 1bbb0ee42c8e
parent 4155 80cc9c6ddcf0
child 4157 f7830377b215
drop form_field_name/form_field_id methods from form object, in favor of field.input_name(form) / field.dom_id(form)
web/formfields.py
web/formwidgets.py
web/views/cwproperties.py
web/views/formrenderers.py
web/views/forms.py
--- a/web/formfields.py	Mon Dec 21 18:46:46 2009 +0100
+++ b/web/formfields.py	Mon Dec 21 19:18:49 2009 +0100
@@ -170,6 +170,34 @@
         """return the widget instance associated to this field"""
         return self.widget
 
+    # cached is necessary else we get some pb on entity creation : entity.eid is
+    # modified from creation mark (eg 'X') to its actual eid (eg 123), and then
+    # `field.input_name()` won't return the right key anymore if not cached
+    # (first call to input_name done *before* eventual eid affectation).
+    @cached
+    def input_name(self, form, suffix=None):
+        """return 'qualified name' for this field"""
+        if self.eidparam:
+            if suffix is None:
+                return eid_param(self.role_name(), form.edited_entity.eid)
+            return eid_param(self.role_name() + suffix, form.edited_entity.eid)
+        if suffix is None:
+            return self.name
+        return self.name + suffix
+
+    def role_name(self):
+        """return <field.name>-<field.role> if role is specified, else field.name"""
+        if self.role is not None:
+            return '%s-%s' % (self.name, self.role)
+        return self.name
+
+    def dom_id(self, form):
+        """return an html dom identifier for this field"""
+        id = self.id or self.role_name()
+        if self.eidparam:
+            return eid_param(id, form.edited_entity.eid)
+        return id
+
     def example_format(self, req):
         """return a sample string describing what can be given as input for this
         field
@@ -356,7 +384,7 @@
     def render(self, form, renderer):
         wdgs = [self.get_widget(form).render(form, self, renderer)]
         if self.format_field or self.encoding_field:
-            divid = '%s-advanced' % form.context[self]['name']
+            divid = '%s-advanced' % self.input_name(form)
             wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
                         (xml_escape(uilib.toggle_action(divid)),
                          form._cw._('show advanced fields'),
@@ -373,7 +401,7 @@
         if not self.required and form.context[self]['value']:
             # trick to be able to delete an uploaded file
             wdgs.append(u'<br/>')
-            wdgs.append(tags.input(name=u'%s__detach' % form.context[self]['name'],
+            wdgs.append(tags.input(name=self.input_name(form, u'__detach'),
                                    type=u'checkbox'))
             wdgs.append(form._cw._('detach attached file'))
         return u'\n'.join(wdgs)
@@ -386,11 +414,11 @@
 
     def process_form_value(self, form):
         posted = form._cw.form
-        value = posted.get(form.form_field_name(self))
-        formkey = form.form_field_name(self)
-        if ('%s__detach' % form.context[self]['name']) in posted:
+        if self.input_name(form, u'__detach') in posted:
             # drop current file value
             value = None
+        else:
+            value = posted.get(self.input_name(form))
         # no need to check value when nor explicit detach nor new file
         # submitted, since it will think the attribute is not modified
         elif value:
@@ -434,7 +462,7 @@
         return '\n'.join(wdgs)
 
     def process_form_value(self, form):
-        value = form._cw.form.get(form.form_field_name(self))
+        value = form._cw.form.get(self.input_name(form))
         if isinstance(value, unicode):
             # file modified using a text widget
             encoding = form.form_field_encoding(self)
--- a/web/formwidgets.py	Mon Dec 21 18:46:46 2009 +0100
+++ b/web/formwidgets.py	Mon Dec 21 19:18:49 2009 +0100
@@ -59,7 +59,7 @@
             values = (values,)
         attrs = dict(self.attrs)
         if self.setdomid:
-            attrs['id'] = form.context[field]['id']
+            attrs['id'] = field.dom_id(form)
         if self.settabindex and not 'tabindex' in attrs:
             attrs['tabindex'] = form._cw.next_tabindex()
         return name, values, attrs
@@ -83,7 +83,8 @@
         # ensure something is rendered
         if not values:
             values = (INTERNAL_FIELD_VALUE,)
-        inputs = [tags.input(name=name, value=value, type=self.type, **attrs)
+        inputs = [tags.input(name=field.input_name(form), type=self.type,
+                             value=value, **attrs)
                   for value in values]
         return u'\n'.join(inputs)
 
@@ -106,23 +107,18 @@
         name, values, attrs = self._render_attrs(form, field)
         assert len(values) == 1
         id = attrs.pop('id')
-        try:
-            confirmname = '%s-confirm:%s' % tuple(name.rsplit(':', 1))
-        except TypeError:
-            confirmname = '%s-confirm' % name
-        inputs = [tags.input(name=name, value=values[0], type=self.type, id=id,
-                             **attrs),
+        inputs = [tags.input(name=field.input_name(form),
+                             value=values[0], type=self.type, id=id, **attrs),
                   '<br/>',
-                  tags.input(name=confirmname, value=values[0], type=self.type,
-                             **attrs),
+                  tags.input(name=field.input_name(form, '-confirm'),
+                             value=values[0], type=self.type, **attrs),
                   '&#160;', tags.span(form._cw._('confirm password'),
                                       **{'class': 'emphasis'})]
         return u'\n'.join(inputs)
 
     def process_field_data(self, form, field):
         passwd1 = super(PasswordInput, self).process_field_data(form, field)
-        fieldname = form.form_field_name(field)
-        passwd2 = form._cw.form[fieldname+'-confirm']
+        passwd2 = form._cw.form.get(field.input_name(form, '-confirm'))
         if passwd1 == passwd2:
             if passwd1 is None:
                 return None
@@ -183,7 +179,7 @@
             linecount += len(line) / 80
         attrs.setdefault('cols', 80)
         attrs.setdefault('rows', min(15, linecount + 2))
-        return tags.textarea(value, name=name, **attrs)
+        return tags.textarea(value, name=field.input_name(form), **attrs)
 
 
 class FCKEditor(TextArea):
@@ -231,7 +227,7 @@
                 options.append(tags.option(label, value=value, **oattrs))
         if optgroup_opened:
             options.append(u'</optgroup>')
-        return tags.select(name=name, multiple=self._multiple,
+        return tags.select(name=field.input_name(form), multiple=self._multiple,
                            options=options, **attrs)
 
 
@@ -259,7 +255,8 @@
                 iattrs.setdefault('id', domid)
             if value in curvalues:
                 iattrs['checked'] = u'checked'
-            tag = tags.input(name=name, type=self.type, value=value, **iattrs)
+            tag = tags.input(name=field.input_name(form), type=self.type,
+                             value=value, **iattrs)
             options.append(tag + label)
         return sep.join(options)
 
@@ -351,7 +348,7 @@
         value = form.form_field_value(field)
         if not value:
             value = date.today()
-        inputid = form.context[field]['id']
+        inputid = field.dom_id(form)
         helperid = '%shelper' % inputid
         year, month = value.year, value.month
         return (u"""<a onclick="toggleCalendar('%s', '%s', %s, %s);" class="calhelper">
--- a/web/views/cwproperties.py	Mon Dec 21 18:46:46 2009 +0100
+++ b/web/views/cwproperties.py	Mon Dec 21 19:18:49 2009 +0100
@@ -261,7 +261,7 @@
 class PlaceHolderWidget(object):
 
     def render(self, form, field, renderer):
-        domid = form.context[field]['id']
+        domid = field.dom_id(form)
         # empty span as well else html validation fail (label is refering to
         # this id)
         return '<div id="div:%s"><span id="%s">%s</span></div>' % (
@@ -274,7 +274,7 @@
         self.msg = msg
 
     def render(self, form, field, renderer):
-        domid = form.context[field]['id']
+        domid = field.dom_id(form)
         value = '<span class="value" id="%s">%s</span>' % (domid, self.value)
         if self.msg:
             value + '<div class="helper">%s</div>' % self.msg
--- a/web/views/formrenderers.py	Mon Dec 21 18:46:46 2009 +0100
+++ b/web/views/formrenderers.py	Mon Dec 21 19:18:49 2009 +0100
@@ -97,7 +97,7 @@
             label = self._cw.pgettext(*field.label)
         else:
             label = self._cw._(field.label)
-        attrs = {'for': form.context[field]['id']}
+        attrs = {'for': field.dom_id(form)}
         if field.required:
             attrs['class'] = 'required'
         return tags.label(label, **attrs)
--- a/web/views/forms.py	Mon Dec 21 18:46:46 2009 +0100
+++ b/web/views/forms.py	Mon Dec 21 19:18:49 2009 +0100
@@ -229,14 +229,6 @@
         """return encoding used for the given (text) field"""
         return self._cw.encoding
 
-    def form_field_name(self, field):
-        """return qualified name for the given field"""
-        return field.name
-
-    def form_field_id(self, field):
-        """return dom id for the given field"""
-        return field.id
-
     def form_field_vocabulary(self, field, limit=None):
         """return vocabulary for the given field. Should be overriden in
         specific forms using fields which requires some vocabulary