diff -r 8832e231fad7 -r 11ce4682187d web/views/autoform.py --- a/web/views/autoform.py Tue Sep 29 12:44:06 2009 +0200 +++ b/web/views/autoform.py Tue Sep 29 12:44:50 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" _ = unicode -from logilab.common.decorators import iclassmethod +from logilab.common.decorators import iclassmethod, cached from cubicweb import typed_eid from cubicweb.web import stdmsgs, uicfg @@ -194,6 +194,11 @@ """true if the form needs enctype=multipart/form-data""" return self._subform_needs_multipart() + def build_context(self, rendervalues=None): + super(AutomaticEntityForm, self).build_context(rendervalues) + for form in self.inlined_forms(): + form.build_context(rendervalues) + def _subform_needs_multipart(self, _tested=None): if _tested is None: _tested = set() @@ -337,6 +342,46 @@ # inlined forms support #################################################### + @cached + def inlined_form_views(self): + """compute and return list of inlined form views (hosting the inlined form object) + """ + formviews = [] + entity = self.edited_entity + for rschema, ttypes, role in self.inlined_relations(): + # show inline forms only if there's one possible target type + # for rschema + if len(ttypes) != 1: + self.warning('entity related by the %s relation should have ' + 'inlined form but there is multiple target types, ' + 'dunno what to do', rschema) + continue + ttype = ttypes[0].type + if self.should_inline_relation_form(rschema, ttype, role): + formviews += self.inline_edition_form_view(rschema, ttype, role) + if role == 'subject': + card = rschema.rproperty(entity.e_schema, ttype, 'cardinality')[0] + else: + card = rschema.rproperty(ttype, entity.e_schema, 'cardinality')[1] + # there is no related entity and we need at least one: we need to + # display one explicit inline-creation view + if self.should_display_inline_creation_form(rschema, formviews, card): + formviews += self.inline_creation_form_view(rschema, ttype, role) + # we can create more than one related entity, we thus display a link + # to add new related entities + if self.should_display_add_new_relation_link(rschema, formviews, card): + addnewlink = self.vreg['views'].select( + 'inline-addnew-link', self.req, + etype=ttype, rtype=rschema, role=role, + peid=self.edited_entity.eid, pform=self, card=card) + formviews.append(addnewlink) + return formviews + + def inlined_forms(self): + for formview in self.inlined_form_views(): + if formview.form: # may be None for the addnew_link artefact form + yield formview.form + def should_inline_relation_form(self, rschema, targettype, role): """return true if the given relation with entity has role and a targettype target should be inlined @@ -344,25 +389,6 @@ return self.rinlined.etype_get(self.edited_entity.id, rschema, role, targettype) - def display_inline_edition_form(self, w, rschema, targettype, role, - i18nctx): - """display inline forms for already related entities. - - Return True if some inlined form are actually displayed - """ - existant = False - entity = self.edited_entity - related = entity.has_eid() and entity.related(rschema, role) - if related: - # display inline-edition view for all existing related entities - for i, relentity in enumerate(related.entities()): - if relentity.has_perm('update'): - w(self.view('inline-edition', related, row=i, col=0, - rtype=rschema, role=role, ptype=entity.e_schema, - peid=entity.eid, i18nctx=i18nctx)) - existant = True - return existant - def should_display_inline_creation_form(self, rschema, existant, card): """return true if a creation form should be inlined @@ -370,17 +396,6 @@ """ return not existant and card in '1+' or self.req.form.has_key('force_%s_display' % rschema) - def display_inline_creation_form(self, w, rschema, targettype, role, - i18nctx): - """display inline forms to a newly related (hence created) entity. - - Return True if some inlined form are actually displayed - """ - entity = self.edited_entity - w(self.view('inline-creation', None, etype=targettype, - peid=entity.eid, ptype=entity.e_schema, - rtype=rschema, role=role, i18nctx=i18nctx)) - def should_display_add_new_relation_link(self, rschema, existant, card): """return true if we should add a link to add a new creation form (through ajax call) @@ -398,6 +413,29 @@ """ return card in '1?' + def inline_edition_form_view(self, rschema, ttype, role): + """yield inline form views for already related entities through the + given relation + """ + entity = self.edited_entity + related = entity.has_eid() and entity.related(rschema, role) + if related: + vvreg = self.vreg['views'] + # display inline-edition view for all existing related entities + for i, relentity in enumerate(related.entities()): + if relentity.has_perm('update'): + yield vvreg.select('inline-edition', self.req, related, + row=i, col=0, rtype=rschema, role=role, + peid=entity.eid, pform=self) + + def inline_creation_form_view(self, rschema, ttype, role): + """yield inline form views to a newly related (hence created) entity + through the given relation + """ + yield self.vreg['views'].select('inline-creation', self.req, + etype=ttype, rtype=rschema, role=role, + peid=self.edited_entity.eid, pform=self) + def etype_relation_field(etype, rtype, role='subject'): eschema = AutomaticEntityForm.schema.eschema(etype)