web/views/editforms.py
changeset 4378 785c56bdacc6
parent 4366 d51f28ba9399
child 4380 5613d7c06339
equal deleted inserted replaced
4377:0e9cf6593382 4378:785c56bdacc6
    19 from cubicweb import neg_role
    19 from cubicweb import neg_role
    20 from cubicweb.selectors import (match_kwargs, one_line_rset, non_final_entity,
    20 from cubicweb.selectors import (match_kwargs, one_line_rset, non_final_entity,
    21                                 specified_etype_implements, yes)
    21                                 specified_etype_implements, yes)
    22 from cubicweb.view import EntityView
    22 from cubicweb.view import EntityView
    23 from cubicweb import tags
    23 from cubicweb import tags
    24 from cubicweb.web import uicfg, stdmsgs, eid_param
    24 from cubicweb.web import uicfg, stdmsgs, eid_param, \
       
    25      formfields as ff, formwidgets as fw
    25 from cubicweb.web.form import FormViewMixIn, FieldNotFound
    26 from cubicweb.web.form import FormViewMixIn, FieldNotFound
    26 from cubicweb.web.formfields import guess_field
       
    27 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton
       
    28 from cubicweb.web.views import forms
    27 from cubicweb.web.views import forms
    29 
    28 
    30 _pvdc = uicfg.primaryview_display_ctrl
    29 _pvdc = uicfg.primaryview_display_ctrl
    31 
    30 
    32 
    31 
    34     __regid__ = 'deleteconf'
    33     __regid__ = 'deleteconf'
    35     __select__ = non_final_entity()
    34     __select__ = non_final_entity()
    36 
    35 
    37     domid = 'deleteconf'
    36     domid = 'deleteconf'
    38     copy_nav_params = True
    37     copy_nav_params = True
    39     form_buttons = [Button(stdmsgs.BUTTON_DELETE, cwaction='delete'),
    38     form_buttons = [fw.Button(stdmsgs.BUTTON_DELETE, cwaction='delete'),
    40                     Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
    39                     fw.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
    41     @property
    40     @property
    42     def action(self):
    41     def action(self):
    43         return self._cw.build_url('edit')
    42         return self._cw.build_url('edit')
    44 
    43 
    45     def __init__(self, *args, **kwargs):
    44     def __init__(self, *args, **kwargs):
   228         onsubmit = self._onsubmit % event_args
   227         onsubmit = self._onsubmit % event_args
   229         cancelclick = self._cancelclick % (entity.eid, rtype, divid)
   228         cancelclick = self._cancelclick % (entity.eid, rtype, divid)
   230         form = self._cw.vreg['forms'].select(
   229         form = self._cw.vreg['forms'].select(
   231             formid, self._cw, entity=entity, domid='%s-form' % divid,
   230             formid, self._cw, entity=entity, domid='%s-form' % divid,
   232             cssstyle='display: none', onsubmit=onsubmit, action='#',
   231             cssstyle='display: none', onsubmit=onsubmit, action='#',
   233             form_buttons=[SubmitButton(), Button(stdmsgs.BUTTON_CANCEL,
   232             form_buttons=[fw.SubmitButton(),
   234                                                  onclick=cancelclick)],
   233                           fw.Button(stdmsgs.BUTTON_CANCEL, onclick=cancelclick)],
   235             **formargs)
   234             **formargs)
   236         form.event_args = event_args
   235         form.event_args = event_args
   237         return form
   236         return form
   238 
   237 
   239 
   238 
   408 
   407 
   409 class TableEditForm(forms.CompositeForm):
   408 class TableEditForm(forms.CompositeForm):
   410     __regid__ = 'muledit'
   409     __regid__ = 'muledit'
   411     domid = 'entityForm'
   410     domid = 'entityForm'
   412     onsubmit = "return validateForm('%s', null);" % domid
   411     onsubmit = "return validateForm('%s', null);" % domid
   413     form_buttons = [SubmitButton(_('validate modifications on selected items')),
   412     form_buttons = [fw.SubmitButton(_('validate modifications on selected items')),
   414                     ResetButton(_('revert changes'))]
   413                     fw.ResetButton(_('revert changes'))]
   415 
   414 
   416     def __init__(self, req, rset, **kwargs):
   415     def __init__(self, req, rset, **kwargs):
   417         kwargs.setdefault('__redirectrql', rset.printable_rql())
   416         kwargs.setdefault('__redirectrql', rset.printable_rql())
   418         super(TableEditForm, self).__init__(req, rset=rset, **kwargs)
   417         super(TableEditForm, self).__init__(req, rset=rset, **kwargs)
   419         for row in xrange(len(self.cw_rset)):
   418         for row in xrange(len(self.cw_rset)):
   448         # telling which form the edit controller should select (eg difffers
   447         # telling which form the edit controller should select (eg difffers
   449         # between html generation / post handling form)
   448         # between html generation / post handling form)
   450         self.w(form.render(formvid='edition'))
   449         self.w(form.render(formvid='edition'))
   451 
   450 
   452 
   451 
       
   452 # inlined form handling ########################################################
       
   453 
       
   454 class InlinedFormField(ff.Field):
       
   455     def __init__(self, view=None, **kwargs):
       
   456         if view.role == 'object':
       
   457             fieldset = u'%s_object%s' % view.rtype
       
   458         else:
       
   459             fieldset = view.rtype
       
   460         #kwargs.setdefault('fieldset', fieldset)
       
   461         kwargs.setdefault('label', None)
       
   462         super(InlinedFormField, self).__init__(name=view.rtype, role=view.role,
       
   463                                                eidparam=True, **kwargs)
       
   464         self.view = view
       
   465 
       
   466     def render(self, form, renderer):
       
   467         """render this field, which is part of form, using the given form
       
   468         renderer
       
   469         """
       
   470         view = self.view
       
   471         i18nctx = 'inlined:%s.%s.%s' % (form.edited_entity.e_schema,
       
   472                                         view.rtype, view.role)
       
   473         return u'<div class="inline-%s-%s-slot">%s</div>' % (
       
   474             view.rtype, view.role,
       
   475             view.render(i18nctx=i18nctx, row=view.cw_row, col=view.cw_col))
       
   476 
       
   477     def form_init(self, form):
       
   478         """method called before by build_context to trigger potential field
       
   479         initialization requiring the form instance
       
   480         """
       
   481         if self.view.form:
       
   482             self.view.form.build_context(form.formvalues)
       
   483 
       
   484     @property
       
   485     def needs_multipart(self):
       
   486         if self.view.form:
       
   487             # take a look at inlined forms to check (recursively) if they need
       
   488             # multipart handling.
       
   489             return self.view.form.needs_multipart
       
   490         return False
       
   491 
       
   492     def has_been_modified(self, form):
       
   493         return False
       
   494 
       
   495     def process_posted(self, form):
       
   496         pass # handled by the subform
       
   497 
       
   498 
   453 class InlineEntityEditionFormView(FormViewMixIn, EntityView):
   499 class InlineEntityEditionFormView(FormViewMixIn, EntityView):
   454     """
   500     """
   455     :attr peid: the parent entity's eid hosting the inline form
   501     :attr peid: the parent entity's eid hosting the inline form
   456     :attr rtype: the relation bridging `etype` and `peid`
   502     :attr rtype: the relation bridging `etype` and `peid`
   457     :attr role: the role played by the `peid` in the relation
   503     :attr role: the role played by the `peid` in the relation
   458     :attr pform: the parent form where this inlined form is being displayed
   504     :attr pform: the parent form where this inlined form is being displayed
   459     """
   505     """
   460     __regid__ = 'inline-edition'
   506     __regid__ = 'inline-edition'
   461     __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
   507     __select__ = non_final_entity() & match_kwargs('peid', 'rtype')
   462 
   508 
   463     _select_attrs = ('peid', 'rtype', 'role', 'pform')
   509     _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype')
   464     removejs = "removeInlinedEntity('%s', '%s', '%s')"
   510     removejs = "removeInlinedEntity('%s', '%s', '%s')"
   465 
   511 
   466     def __init__(self, *args, **kwargs):
   512     def __init__(self, *args, **kwargs):
   467         for attr in self._select_attrs:
   513         for attr in self._select_attrs:
   468             setattr(self, attr, kwargs.pop(attr, None))
   514             setattr(self, attr, kwargs.pop(attr, None))
   546     :attr etype: the entity type being created in the inline form
   592     :attr etype: the entity type being created in the inline form
   547     """
   593     """
   548     __regid__ = 'inline-creation'
   594     __regid__ = 'inline-creation'
   549     __select__ = (match_kwargs('peid', 'rtype')
   595     __select__ = (match_kwargs('peid', 'rtype')
   550                   & specified_etype_implements('Any'))
   596                   & specified_etype_implements('Any'))
   551     _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',)
       
   552 
   597 
   553     @property
   598     @property
   554     def removejs(self):
   599     def removejs(self):
   555         entity = self._entity()
   600         entity = self._entity()
   556         card = entity.e_schema.rdef(self.rtype, neg_role(self.role)).role_cardinality(self.role)
   601         card = entity.e_schema.rdef(self.rtype, neg_role(self.role)).role_cardinality(self.role)
   557         # when one is adding an inline entity for a relation of a single card,
   602         # when one is adding an inline entity for a relation of a single card,
   558         # the 'add a new xxx' link disappears. If the user then cancel the addition,
   603         # the 'add a new xxx' link disappears. If the user then cancel the addition,
   559         # we have to make this link appears back. This is done by giving add new link
   604         # we have to make this link appears back. This is done by giving add new link
   560         # id to removeInlineForm.
   605         # id to removeInlineForm.
   561         if card not in '?1':
   606         if card not in '?1':
   562             return "removeInlineForm('%s', '%s', '%s')"
   607             return "removeInlineForm('%%s', '%%s', '%s', '%%s')" % self.role
   563         divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid)
   608         divid = "addNew%s%s%s:%s" % (
   564         return "removeInlineForm('%%s', '%%s', '%%s', '%s')" % divid
   609             self.etype, self.rtype, self.role, self.peid)
       
   610         return "removeInlineForm('%%s', '%%s', '%s', '%%s', '%s')" % (
       
   611             self.role, divid)
   565 
   612 
   566     @cached
   613     @cached
   567     def _entity(self):
   614     def _entity(self):
   568         try:
   615         try:
   569             cls = self._cw.vreg['etypes'].etype_class(self.etype)
   616             cls = self._cw.vreg['etypes'].etype_class(self.etype)