web/views/editforms.py
changeset 3998 94cc7cad3d2d
parent 3890 d7a270f50f54
parent 3953 19aefd78f61b
child 4007 91d11fda4aa0
equal deleted inserted replaced
3895:92ead039d3d0 3998:94cc7cad3d2d
    26 from cubicweb.web.form import FormViewMixIn, FieldNotFound
    26 from cubicweb.web.form import FormViewMixIn, FieldNotFound
    27 from cubicweb.web.formfields import guess_field
    27 from cubicweb.web.formfields import guess_field
    28 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton
    28 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton
    29 from cubicweb.web.views import forms
    29 from cubicweb.web.views import forms
    30 
    30 
       
    31 _pvdc = uicfg.primaryview_display_ctrl
    31 
    32 
    32 def relation_id(eid, rtype, role, reid):
    33 def relation_id(eid, rtype, role, reid):
    33     """return an identifier for a relation between two entities"""
    34     """return an identifier for a relation between two entities"""
    34     if role == 'subject':
    35     if role == 'subject':
    35         return u'%s:%s:%s' % (eid, rtype, reid)
    36         return u'%s:%s:%s' % (eid, rtype, reid)
    94             # don't use outofcontext view or any other that may contain inline
    95             # don't use outofcontext view or any other that may contain inline
    95             # edition form
    96             # edition form
    96             w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
    97             w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
    97                                       href=entity.absolute_url()))
    98                                       href=entity.absolute_url()))
    98         w(u'</ul>\n')
    99         w(u'</ul>\n')
    99         w(form.form_render())
   100         w(form.render())
   100 
   101 
   101 
   102 
   102 class ClickAndEditFormView(FormViewMixIn, EntityView):
   103 class ClickAndEditFormView(FormViewMixIn, EntityView):
   103     """form used to permit ajax edition of a relation or attribute of an entity
   104     """form used to permit ajax edition of a relation or attribute of an entity
   104     in a view, if logged user have the permission to edit it.
   105     in a view, if logged user have the permission to edit it.
   147                 return
   148                 return
   148             value = entity.printable_value(rtype) or default
   149             value = entity.printable_value(rtype) or default
   149             self.relation_form(lzone, value, form,
   150             self.relation_form(lzone, value, form,
   150                                self._build_renderer(entity, rtype, role))
   151                                self._build_renderer(entity, rtype, role))
   151         else:
   152         else:
   152             if rvid is None:
   153             rvid = self._compute_best_vid(entity.e_schema, rschema, role)
   153                 rvid = self._compute_best_vid(entity.e_schema, rschema, role)
       
   154             rset = entity.related(rtype, role)
   154             rset = entity.related(rtype, role)
   155             if rset:
   155             if rset:
   156                 value = self._cw.view(rvid, rset)
   156                 value = self._cw.view(rvid, rset)
   157             else:
   157             else:
   158                 value = default
   158                 value = default
   200         w(u'<div id="%s-reledit" class="field" '
   200         w(u'<div id="%s-reledit" class="field" '
   201           u'onmouseout="addElementClass(jQuery(\'#%s\'), \'hidden\')" '
   201           u'onmouseout="addElementClass(jQuery(\'#%s\'), \'hidden\')" '
   202           u'onmouseover="removeElementClass(jQuery(\'#%s\'), \'hidden\')">'
   202           u'onmouseover="removeElementClass(jQuery(\'#%s\'), \'hidden\')">'
   203           % (divid, divid, divid))
   203           % (divid, divid, divid))
   204         w(u'<div id="%s-value" class="editableFieldValue">%s</div>' % (divid, value))
   204         w(u'<div id="%s-value" class="editableFieldValue">%s</div>' % (divid, value))
   205         w(form.form_render(renderer=renderer))
   205         w(form.render(renderer=renderer))
   206         w(u'<div id="%s" class="editableField hidden" onclick="%s" title="%s">' % (
   206         w(u'<div id="%s" class="editableField hidden" onclick="%s" title="%s">' % (
   207                 divid, xml_escape(self._onclick % form.event_args),
   207                 divid, xml_escape(self._onclick % form.event_args),
   208                 self.req._(self._landingzonemsg)))
   208                 self.req._(self._landingzonemsg)))
   209         w(lzone)
   209         w(lzone)
   210         w(u'</div>')
   210         w(u'</div>')
   211         w(u'</div>')
   211         w(u'</div>')
   212 
   212 
   213     def _compute_best_vid(self, eschema, rschema, role):
   213     def _compute_best_vid(self, eschema, rschema, role):
       
   214         dispctrl = _pvdc.etype_get(eschema, rschema, role)
       
   215         if dispctrl.get('rvid'):
       
   216             return dispctrl['rvid']
   214         if eschema.cardinality(rschema, role) in '+*':
   217         if eschema.cardinality(rschema, role) in '+*':
   215             return self._many_rvid
   218             return self._many_rvid
   216         return self._one_rvid
   219         return self._one_rvid
   217 
   220 
   218     def _build_landing_zone(self, lzone):
   221     def _build_landing_zone(self, lzone):
   252 
   255 
   253 class DummyForm(object):
   256 class DummyForm(object):
   254     __slots__ = ('event_args',)
   257     __slots__ = ('event_args',)
   255     def form_render(self, **_args):
   258     def form_render(self, **_args):
   256         return u''
   259         return u''
       
   260     def render(self, **_args):
       
   261         return u''
   257     def append_field(self, *args):
   262     def append_field(self, *args):
   258         pass
   263         pass
   259 
   264 
   260 class AutoClickAndEditFormView(ClickAndEditFormView):
   265 class AutoClickAndEditFormView(ClickAndEditFormView):
   261     """same as ClickAndEditFormView but checking if the view *should* be applied
   266     """same as ClickAndEditFormView but checking if the view *should* be applied
   267 
   272 
   268     def should_edit_relation(self, entity, rschema, role, rvid):
   273     def should_edit_relation(self, entity, rschema, role, rvid):
   269         eschema = entity.e_schema
   274         eschema = entity.e_schema
   270         rtype = str(rschema)
   275         rtype = str(rschema)
   271         # XXX check autoform_section. what if 'generic'?
   276         # XXX check autoform_section. what if 'generic'?
   272         dispctrl = uicfg.primaryview_display_ctrl.etype_get(eschema, rtype, role)
   277         dispctrl = _pvdc.etype_get(eschema, rtype, role)
   273         vid = dispctrl.get('vid', 'reledit')
   278         vid = dispctrl.get('vid', 'reledit')
   274         if vid != 'reledit': # reledit explicitly disabled
   279         if vid != 'reledit': # reledit explicitly disabled
   275             return False
   280             return False
   276         if eschema.role_rproperty(role, rschema, 'composite') == role:
   281         if eschema.role_rproperty(role, rschema, 'composite') == role:
   277             return False
   282             return False
   308         form = self._cw.vreg['forms'].select('edition', self._cw, rset=entity.cw_rset,
   313         form = self._cw.vreg['forms'].select('edition', self._cw, rset=entity.cw_rset,
   309                                              row=entity.cw_row, col=entity.cw_col,
   314                                              row=entity.cw_row, col=entity.cw_col,
   310                                              entity=entity,
   315                                              entity=entity,
   311                                              submitmsg=self.submited_message())
   316                                              submitmsg=self.submited_message())
   312         self.init_form(form, entity)
   317         self.init_form(form, entity)
   313         self.w(form.form_render(formvid=u'edition'))
   318         self.w(form.render(rendervalues=dict(formvid=u'edition')))
   314 
   319 
   315     def init_form(self, form, entity):
   320     def init_form(self, form, entity):
   316         """customize your form before rendering here"""
   321         """customize your form before rendering here"""
   317         pass
   322         pass
   318 
   323 
   445         """
   450         """
   446         #self.form_title(entity)
   451         #self.form_title(entity)
   447         form = self._cw.vreg['forms'].select(self.__regid__, self._cw,
   452         form = self._cw.vreg['forms'].select(self.__regid__, self._cw,
   448                                              rset=self.cw_rset,
   453                                              rset=self.cw_rset,
   449                                              copy_nav_params=True)
   454                                              copy_nav_params=True)
   450         self.w(form.form_render())
   455         self.w(form.render())
   451 
   456 
   452 
   457 
   453 class InlineEntityEditionFormView(FormViewMixIn, EntityView):
   458 class InlineEntityEditionFormView(FormViewMixIn, EntityView):
   454     """
   459     """
   455     :attr peid: the parent entity's eid hosting the inline form
   460     :attr peid: the parent entity's eid hosting the inline form
   477     def form(self):
   482     def form(self):
   478         entity = self._entity()
   483         entity = self._entity()
   479         form = self.vreg['forms'].select('edition', self._cw,
   484         form = self.vreg['forms'].select('edition', self._cw,
   480                                          entity=entity,
   485                                          entity=entity,
   481                                          form_renderer_id='inline',
   486                                          form_renderer_id='inline',
   482                                          mainform=False, copy_nav_params=False,
   487                                          copy_nav_params=False,
       
   488                                          mainform=False,
       
   489                                          parent_form=self.pform,
   483                                          **self.extra_kwargs)
   490                                          **self.extra_kwargs)
   484         form.parent_form = self.pform
   491         if self.pform is None:
       
   492             form.restore_previous_post(form.session_key())
       
   493         #assert form.parent_form
   485         self.add_hiddens(form, entity)
   494         self.add_hiddens(form, entity)
   486         return form
   495         return form
   487 
   496 
   488     def cell_call(self, row, col, i18nctx, **kwargs):
   497     def cell_call(self, row, col, i18nctx, **kwargs):
   489         """
   498         """
   498 
   507 
   499     def render_form(self, i18nctx, **kwargs):
   508     def render_form(self, i18nctx, **kwargs):
   500         """fetch and render the form"""
   509         """fetch and render the form"""
   501         entity = self._entity()
   510         entity = self._entity()
   502         divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
   511         divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid)
   503         title = self.req.pgettext(i18nctx, 'This %s' % entity.e_schema)
   512         title = self.form_title(entity, i18nctx)
   504         removejs = self.removejs % (self.peid, self.rtype, entity.eid)
   513         removejs = self.removejs and self.removejs % (
       
   514             self.peid, self.rtype, entity.eid)
   505         countkey = '%s_count' % self.rtype
   515         countkey = '%s_count' % self.rtype
   506         try:
   516         try:
   507             self._cw.data[countkey] += 1
   517             self._cw.data[countkey] += 1
   508         except:
   518         except KeyError:
   509             self._cw.data[countkey] = 1
   519             self._cw.data[countkey] = 1
   510         self.w(self.form.form_render(
   520         self.w(self.form.form.render(
   511             divid=divid, title=title, removejs=removejs, i18nctx=i18nctx,
   521             divid=divid, title=title, removejs=removejs, i18nctx=i18nctx,
   512             counter=self.req.data[countkey], **kwargs))
   522             counter=self.req.data[countkey], **kwargs))
       
   523         self.w(self.form.render(
       
   524             rendervalues=dict(divid=divid, title=title, removejs=removejs,
       
   525                               i18nctx=i18nctx, counter=self._cw.data[countkey]),
       
   526             formvalues=kwargs))
       
   527 
       
   528     def form_title(self, entity, i18nctx):
       
   529         return self.req.pgettext(i18nctx, 'This %s' % entity.e_schema)
   513 
   530 
   514     def add_hiddens(self, form, entity):
   531     def add_hiddens(self, form, entity):
   515         """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
   532         """to ease overriding (see cubes.vcsfile.views.forms for instance)"""
   516         iid = 'rel-%s-%s-%s' % (self.peid, self.rtype, entity.eid)
   533         iid = 'rel-%s-%s-%s' % (self.peid, self.rtype, entity.eid)
   517         #  * str(self.rtype) in case it's a schema object
   534         #  * str(self.rtype) in case it's a schema object
   538     """
   555     """
   539     __regid__ = 'inline-creation'
   556     __regid__ = 'inline-creation'
   540     __select__ = (match_kwargs('peid', 'rtype')
   557     __select__ = (match_kwargs('peid', 'rtype')
   541                   & specified_etype_implements('Any'))
   558                   & specified_etype_implements('Any'))
   542     _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',)
   559     _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',)
   543     removejs = "removeInlineForm('%s', '%s', '%s')"
   560 
       
   561     @property
       
   562     def removejs(self):
       
   563         entity = self._entity()
       
   564         card = entity.e_schema.role_rproperty(neg_role(self.role), self.rtype, 'cardinality')
       
   565         card = card[self.role == 'object']
       
   566         # when one is adding an inline entity for a relation of a single card,
       
   567         # the 'add a new xxx' link disappears. If the user then cancel the addition,
       
   568         # we have to make this link appears back. This is done by giving add new link
       
   569         # id to removeInlineForm.
       
   570         if card not in '?1':
       
   571             return "removeInlineForm('%s', '%s', '%s')"
       
   572         divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid)
       
   573         return "removeInlineForm('%%s', '%%s', '%%s', '%s')" % divid
   544 
   574 
   545     @cached
   575     @cached
   546     def _entity(self):
   576     def _entity(self):
   547         try:
   577         try:
   548             cls = self._cw.vreg['etypes'].etype_class(self.etype)
   578             cls = self._cw.vreg['etypes'].etype_class(self.etype)