--- a/web/views/forms.py Mon Sep 26 19:46:04 2011 +0200
+++ b/web/views/forms.py Tue Sep 27 18:46:36 2011 +0200
@@ -47,7 +47,7 @@
from warnings import warn
from logilab.common import dictattr, tempattr
-from logilab.common.decorators import iclassmethod
+from logilab.common.decorators import iclassmethod, cached
from logilab.common.compat import any
from logilab.common.textutils import splitstrip
from logilab.common.deprecation import deprecated
@@ -57,7 +57,7 @@
from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
from cubicweb.web import RequestError, ProcessFormError
from cubicweb.web import uicfg, form, formwidgets as fwdgs
-from cubicweb.web.formfields import relvoc_unrelated, guess_field
+from cubicweb.web.formfields import guess_field
class FieldsForm(form.Form):
@@ -376,9 +376,7 @@
if kwargs.get('mainform', True) or kwargs.get('mainentity', False):
self.add_hidden(u'__maineid', self.edited_entity.eid)
# If we need to directly attach the new object to another one
- if self._cw.list_form_param('__linkto'):
- for linkto in self._cw.list_form_param('__linkto'):
- self.add_hidden('__linkto', linkto)
+ if '__linkto' in self._cw.form:
if msg:
msg = '%s %s' % (msg, self._cw._('and linked'))
else:
@@ -387,6 +385,38 @@
msgid = self._cw.set_redirect_message(msg)
self.add_hidden('_cwmsgid', msgid)
+ def add_linkto_hidden(self):
+ '''add the __linkto hidden field used to directly attach the new object
+ to an existing other one when the relation between those two is not
+ already present in the form.
+ Warning: this method must be called only when all form fields are setup'''
+ # if current form is not the main form, exit immediately
+ try:
+ self.field_by_name('__maineid')
+ except form.FieldNotFound:
+ return
+ for (rtype, role), eids in self.linked_to.iteritems():
+ # if the relation is already setup by a form field, do not add it
+ # in a __linkto hidden to avoid setting it twice in the controller
+ try:
+ self.field_by_name(rtype, role)
+ except form.FieldNotFound:
+ for eid in eids:
+ self.add_hidden('__linkto', '%s:%s:%s' % (rtype, role, eid))
+
+ def render(self, *args, **kwargs):
+ self.add_linkto_hidden()
+ return super(EntityFieldsForm, self).render(*args, **kwargs)
+
+ @property
+ @cached
+ def linked_to(self):
+ linked_to = {}
+ for linkto in self._cw.list_form_param('__linkto'):
+ ltrtype, eid, ltrole = linkto.split(':')
+ linked_to.setdefault((ltrtype, ltrole), []).append(typed_eid(eid))
+ return linked_to
+
def session_key(self):
"""return the key that may be used to store / retreive data about a
previous post which failed because of a validation error
@@ -427,16 +457,18 @@
def editable_relations(self):
return ()
- @deprecated('[3.6] use cw.web.formfields.relvoc_unrelated function')
+ @deprecated('[3.6] use cw.web.formfields.RelationField.relvoc_unrelated method')
def subject_relation_vocabulary(self, rtype, limit=None):
"""defaut vocabulary method for the given relation, looking for
relation's object entities (i.e. self is the subject)
"""
- return relvoc_unrelated(self.edited_entity, rtype, 'subject', limit=None)
+ field = self.field_by_name(rtype, 'subject')
+ return field.relvoc_unrelated(form, limit=None)
- @deprecated('[3.6] use cw.web.formfields.relvoc_unrelated function')
+ @deprecated('[3.6] use cw.web.formfields.relvoc_unrelated method')
def object_relation_vocabulary(self, rtype, limit=None):
- return relvoc_unrelated(self.edited_entity, rtype, 'object', limit=None)
+ field = self.field_by_name(rtype, 'object')
+ return field.relvoc_unrelated(form, limit=None)
class CompositeFormMixIn(object):