diff -r 29fc83fca803 -r 65e460690139 web/views/forms.py --- 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):