# HG changeset patch # User Sylvain Thénault # Date 1428478046 -7200 # Node ID 0019b7888dd781b052d1f06166ef3c561e00b2fe # Parent 770b58f99e66964c4ee88534a35480ec426ba032 [forms] don't display 'remove' link of inlined form for the first entity related using a '+' cardinality to its parent entity Closes #5227394 diff -r 770b58f99e66 -r 0019b7888dd7 web/test/unittest_views_forms.py --- a/web/test/unittest_views_forms.py Thu Jul 02 09:20:02 2015 +0200 +++ b/web/test/unittest_views_forms.py Wed Apr 08 09:27:26 2015 +0200 @@ -16,7 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License along # with CubicWeb. If not, see . +from logilab.common import tempattr, attrdict + from cubicweb.devtools.testlib import CubicWebTC +from cubicweb.web.views.autoform import InlinedFormField class InlinedFormTC(CubicWebTC): @@ -39,8 +42,33 @@ petype='Salesterm') self.assertEqual(formview.form.linked_to, {}) + def test_remove_js_depending_on_cardinality(self): + with self.admin_access.web_request() as req: + formview = req.vreg['views'].select( + 'inline-creation', req, + etype='File', rtype='described_by_test', role='subject', + peid='A', + petype='Salesterm') + # cardinality is 1, can't remove + self.assertIsNone(formview._get_removejs()) + rdef = self.schema['Salesterm'].rdef('described_by_test') + with tempattr(rdef, 'cardinality', '?*'): + self.assertTrue(formview._get_removejs()) + with tempattr(rdef, 'cardinality', '+*'): + # formview has no parent info (pform). This is what happens + # when an inline form is requested through AJAX. + self.assertTrue(formview._get_removejs()) + fakeview = attrdict(dict(rtype='described_by_test', role='subject')) + # formview is first, can't be removed + formview.pform = attrdict(fields=[InlinedFormField(view=formview), + InlinedFormField(view=fakeview)]) + self.assertIsNone(formview._get_removejs()) + # formview isn't first, can be removed + formview.pform = attrdict(fields=[InlinedFormField(view=fakeview), + InlinedFormField(view=formview)]) + self.assertTrue(formview._get_removejs()) + if __name__ == '__main__': from logilab.common.testlib import unittest_main unittest_main() - diff -r 770b58f99e66 -r 0019b7888dd7 web/views/autoform.py --- a/web/views/autoform.py Thu Jul 02 09:20:02 2015 +0200 +++ b/web/views/autoform.py Wed Apr 08 09:27:26 2015 +0200 @@ -214,6 +214,12 @@ return self.cw_rset.get_entity(self.cw_row, self.cw_col) @property + def petype(self): + assert isinstance(self.peid, int) + pentity = self._cw.entity_from_eid(self.peid) + return pentity.e_schema.type + + @property @cached def form(self): entity = self._entity() @@ -249,12 +255,25 @@ creation form. """ entity = self._entity() - if isinstance(self.peid, int): - pentity = self._cw.entity_from_eid(self.peid) - petype = pentity.e_schema.type - rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), petype) - card= rdef.role_cardinality(self.role) - if card == '1': # don't display remove link + rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype) + card = rdef.role_cardinality(self.role) + if card == '1': # don't display remove link + return None + # if cardinality is 1..n (+), dont display link to remove an inlined form for the first form + # allowing to edit the relation. To detect so: + # + # * if parent form (pform) is None, we're generated through an ajax call and so we know this + # is not the first form + # + # * if parent form is not None, look for previous InlinedFormField in the parent's form + # fields + if card == '+' and self.pform is not None: + # retrieve all field'views handling this relation and return None if we're the first of + # them + first_view = next(iter((f.view for f in self.pform.fields + if isinstance(f, InlinedFormField) + and f.view.rtype == self.rtype and f.view.role == self.role))) + if self == first_view: return None return self.removejs and self.removejs % ( self.peid, self.rtype, entity.eid) @@ -314,7 +333,7 @@ def removejs(self): entity = self._entity() rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype) - card= rdef.role_cardinality(self.role) + card = rdef.role_cardinality(self.role) # when one is adding an inline entity for a relation of a single card, # the 'add a new xxx' link disappears. If the user then cancel the addition, # we have to make this link appears back. This is done by giving add new link