web/views/forms.py
changeset 3998 94cc7cad3d2d
parent 3890 d7a270f50f54
parent 3953 19aefd78f61b
child 4047 2989a7d50b28
equal deleted inserted replaced
3895:92ead039d3d0 3998:94cc7cad3d2d
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
     9 
     9 
    10 from warnings import warn
    10 from warnings import warn
    11 
    11 
    12 from logilab.common.compat import any
    12 from logilab.common.compat import any
       
    13 from logilab.common.deprecation import deprecated
    13 
    14 
    14 from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
    15 from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
    15 from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
    16 from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
    16 from cubicweb.web import form, formwidgets as fwdgs
    17 from cubicweb.web import form, formwidgets as fwdgs
    17 from cubicweb.web.controller import NAV_FORM_PARAMETERS
    18 from cubicweb.web.controller import NAV_FORM_PARAMETERS
    87             # skip other parameters, usually given for selection
    88             # skip other parameters, usually given for selection
    88             # (else write a custom class to handle them)
    89             # (else write a custom class to handle them)
    89         if mainform:
    90         if mainform:
    90             self.form_add_hidden('__errorurl', self.session_key())
    91             self.form_add_hidden('__errorurl', self.session_key())
    91             self.form_add_hidden('__domid', self.domid)
    92             self.form_add_hidden('__domid', self.domid)
       
    93             self.restore_previous_post(self.session_key())
       
    94 
    92         # XXX why do we need two different variables (mainform and copy_nav_params ?)
    95         # XXX why do we need two different variables (mainform and copy_nav_params ?)
    93         if self.copy_nav_params:
    96         if self.copy_nav_params:
    94             for param in NAV_FORM_PARAMETERS:
    97             for param in NAV_FORM_PARAMETERS:
    95                 if not param in kwargs:
    98                 if not param in kwargs:
    96                     value = req.form.get(param)
    99                     value = req.form.get(param)
   123         if self.needs_js:
   126         if self.needs_js:
   124             self._cw.add_js(self.needs_js)
   127             self._cw.add_js(self.needs_js)
   125         if self.needs_css:
   128         if self.needs_css:
   126             self._cw.add_css(self.needs_css)
   129             self._cw.add_css(self.needs_css)
   127 
   130 
   128     def form_render(self, **values):
   131     def render(self, formvalues=None, rendervalues=None, renderer=None):
   129         """render this form, using the renderer given in args or the default
   132         """render this form, using the renderer given in args or the default
   130         FormRenderer()
   133         FormRenderer()
   131         """
   134         """
   132         self.build_context(values)
   135         self.build_context(formvalues or {})
   133         renderer = values.pop('renderer', None)
       
   134         if renderer is None:
   136         if renderer is None:
   135             renderer = self.form_default_renderer()
   137             renderer = self.form_default_renderer()
   136         return renderer.render(self, values)
   138         return renderer.render(self, rendervalues or {})
   137 
   139 
   138     def form_default_renderer(self):
   140     def form_default_renderer(self):
   139         return self._cw.vreg['formrenderers'].select(self.form_renderer_id,
   141         return self._cw.vreg['formrenderers'].select(self.form_renderer_id,
   140                                                      self._cw, rset=self.cw_rset,
   142                                                      self._cw, rset=self.cw_rset,
   141                                                      row=self.cw_row, col=self.cw_col)
   143                                                      row=self.cw_row, col=self.cw_col)
   144         """build form context values (the .context attribute which is a
   146         """build form context values (the .context attribute which is a
   145         dictionary with field instance as key associated to a dictionary
   147         dictionary with field instance as key associated to a dictionary
   146         containing field 'name' (qualified), 'id', 'value' (for display, always
   148         containing field 'name' (qualified), 'id', 'value' (for display, always
   147         a string).
   149         a string).
   148 
   150 
   149         rendervalues is an optional dictionary containing extra kwargs given to
   151         rendervalues is an optional dictionary containing extra form values
   150         form_render()
   152         given to render()
   151         """
   153         """
   152         if self.context is not None:
   154         if self.context is not None:
   153             return # already built
   155             return # already built
   154         self.context = context = {}
   156         self.context = context = {}
   155         # ensure rendervalues is a dict
   157         # ensure rendervalues is a dict
   246 
   248 
   247     def _field_has_error(self, field):
   249     def _field_has_error(self, field):
   248         """return true if the field has some error in given validation exception
   250         """return true if the field has some error in given validation exception
   249         """
   251         """
   250         return self.form_valerror and field.name in self.form_valerror.errors
   252         return self.form_valerror and field.name in self.form_valerror.errors
       
   253 
       
   254     @deprecated('use .render(formvalues, rendervalues)')
       
   255     def form_render(self, **values):
       
   256         """render this form, using the renderer given in args or the default
       
   257         FormRenderer()
       
   258         """
       
   259         self.build_context(values)
       
   260         renderer = values.pop('renderer', None)
       
   261         if renderer is None:
       
   262             renderer = self.form_default_renderer()
       
   263         return renderer.render(self, values)
   251 
   264 
   252 
   265 
   253 class EntityFieldsForm(FieldsForm):
   266 class EntityFieldsForm(FieldsForm):
   254     __regid__ = 'base'
   267     __regid__ = 'base'
   255     __select__ = (match_kwargs('entity')
   268     __select__ = (match_kwargs('entity')
   276                     msg = '%s %s' % (msg, self._cw._('and linked'))
   289                     msg = '%s %s' % (msg, self._cw._('and linked'))
   277                 else:
   290                 else:
   278                     msg = self._cw._('entity linked')
   291                     msg = self._cw._('entity linked')
   279         if msg:
   292         if msg:
   280             self.form_add_hidden('__message', msg)
   293             self.form_add_hidden('__message', msg)
       
   294 
       
   295     def session_key(self):
       
   296         """return the key that may be used to store / retreive data about a
       
   297         previous post which failed because of a validation error
       
   298         """
       
   299         try:
       
   300             return self.force_session_key
       
   301         except AttributeError:
       
   302             # XXX if this is a json request, suppose we should redirect to the
       
   303             # entity primary view
       
   304             if self.req.json_request:
       
   305                 return '%s#%s' % (self.edited_entity.absolute_url(), self.domid)
       
   306             return '%s#%s' % (self.req.url(), self.domid)
   281 
   307 
   282     def _field_has_error(self, field):
   308     def _field_has_error(self, field):
   283         """return true if the field has some error in given validation exception
   309         """return true if the field has some error in given validation exception
   284         """
   310         """
   285         return super(EntityFieldsForm, self)._field_has_error(field) \
   311         return super(EntityFieldsForm, self)._field_has_error(field) \
   399         """return dom id for the given field"""
   425         """return dom id for the given field"""
   400         if field.eidparam:
   426         if field.eidparam:
   401             return eid_param(field.id, self.edited_entity.eid)
   427             return eid_param(field.id, self.edited_entity.eid)
   402         return field.id
   428         return field.id
   403 
   429 
       
   430     # XXX all this vocabulary handling should be on the field, no?
       
   431 
   404     def form_field_vocabulary(self, field, limit=None):
   432     def form_field_vocabulary(self, field, limit=None):
   405         """return vocabulary for the given field"""
   433         """return vocabulary for the given field"""
   406         role, rtype = field.role, field.name
   434         role, rtype = field.role, field.name
   407         method = '%s_%s_vocabulary' % (role, rtype)
   435         method = '%s_%s_vocabulary' % (role, rtype)
   408         try:
   436         try: