cubicweb/web/views/forms.py
changeset 11870 3a84a79c4ed5
parent 11767 432f87a63057
child 11910 af969080e7e6
equal deleted inserted replaced
11869:d8b66e3fd335 11870:3a84a79c4ed5
     1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    40 .. autoclass:: cubicweb.web.views.forms.CompositeForm
    40 .. autoclass:: cubicweb.web.views.forms.CompositeForm
    41 
    41 
    42 but you'll use this one rarely.
    42 but you'll use this one rarely.
    43 """
    43 """
    44 
    44 
    45 
       
    46 
       
    47 
       
    48 import time
    45 import time
    49 import inspect
    46 import inspect
    50 
    47 
    51 from six import text_type
    48 from six import text_type
    52 
    49 
   175     def _get_onsubmit(self):
   172     def _get_onsubmit(self):
   176         try:
   173         try:
   177             return self._onsubmit
   174             return self._onsubmit
   178         except AttributeError:
   175         except AttributeError:
   179             return "return freezeFormButtons('%(domid)s');" % dictattr(self)
   176             return "return freezeFormButtons('%(domid)s');" % dictattr(self)
       
   177 
   180     def _set_onsubmit(self, value):
   178     def _set_onsubmit(self, value):
   181         self._onsubmit = value
   179         self._onsubmit = value
       
   180 
   182     onsubmit = property(_get_onsubmit, _set_onsubmit)
   181     onsubmit = property(_get_onsubmit, _set_onsubmit)
   183 
   182 
   184     def add_media(self):
   183     def add_media(self):
   185         """adds media (CSS & JS) required by this widget"""
   184         """adds media (CSS & JS) required by this widget"""
   186         if self.needs_js:
   185         if self.needs_js:
   208         return self._cw.vreg['formrenderers'].select(
   207         return self._cw.vreg['formrenderers'].select(
   209             self.form_renderer_id, self._cw,
   208             self.form_renderer_id, self._cw,
   210             rset=self.cw_rset, row=self.cw_row, col=self.cw_col or 0)
   209             rset=self.cw_rset, row=self.cw_row, col=self.cw_col or 0)
   211 
   210 
   212     formvalues = None
   211     formvalues = None
       
   212 
   213     def build_context(self, formvalues=None):
   213     def build_context(self, formvalues=None):
   214         """build form context values (the .context attribute which is a
   214         """build form context values (the .context attribute which is a
   215         dictionary with field instance as key associated to a dictionary
   215         dictionary with field instance as key associated to a dictionary
   216         containing field 'name' (qualified), 'id', 'value' (for display, always
   216         containing field 'name' (qualified), 'id', 'value' (for display, always
   217         a string).
   217         a string).
   218         """
   218         """
   219         if self.formvalues is not None:
   219         if self.formvalues is not None:
   220             return # already built
   220             return  # already built
   221         self.formvalues = formvalues or {}
   221         self.formvalues = formvalues or {}
   222         # use a copy in case fields are modified while context is built (eg
   222         # use a copy in case fields are modified while context is built (eg
   223         # __linkto handling for instance)
   223         # __linkto handling for instance)
   224         for field in self.fields[:]:
   224         for field in self.fields[:]:
   225             for field in field.actual_fields(self):
   225             for field in field.actual_fields(self):
   237         if eidfields:
   237         if eidfields:
   238             self.add_hidden('_cw_entity_fields', u','.join(eidfields),
   238             self.add_hidden('_cw_entity_fields', u','.join(eidfields),
   239                             eidparam=True)
   239                             eidparam=True)
   240 
   240 
   241     _default_form_action_path = 'edit'
   241     _default_form_action_path = 'edit'
       
   242 
   242     def form_action(self):
   243     def form_action(self):
   243         action = self.action
   244         action = self.action
   244         if action is None:
   245         if action is None:
   245             return self._cw.build_url(self._default_form_action_path)
   246             return self._cw.build_url(self._default_form_action_path)
   246         return action
   247         return action
   254         if editedfields is None:
   255         if editedfields is None:
   255             try:
   256             try:
   256                 editedfields = self._cw.form['_cw_fields']
   257                 editedfields = self._cw.form['_cw_fields']
   257             except KeyError:
   258             except KeyError:
   258                 raise RequestError(self._cw._('no edited fields specified'))
   259                 raise RequestError(self._cw._('no edited fields specified'))
   259         entityform = entity and len(inspect.getargspec(self.field_by_name)) == 4 # XXX
   260         entityform = entity and len(inspect.getargspec(self.field_by_name)) == 4  # XXX
   260         for editedfield in splitstrip(editedfields):
   261         for editedfield in splitstrip(editedfields):
   261             try:
   262             try:
   262                 name, role = editedfield.split('-')
   263                 name, role = editedfield.split('-')
   263             except Exception:
   264             except Exception:
   264                 name = editedfield
   265                 name = editedfield
   273     def process_posted(self):
   274     def process_posted(self):
   274         """use this method to process the content posted by a simple form.  it
   275         """use this method to process the content posted by a simple form.  it
   275         will return a dictionary with field names as key and typed value as
   276         will return a dictionary with field names as key and typed value as
   276         associated value.
   277         associated value.
   277         """
   278         """
   278         with tempattr(self, 'formvalues', {}): # init fields value cache
   279         with tempattr(self, 'formvalues', {}):  # init fields value cache
   279             errors = []
   280             errors = []
   280             processed = {}
   281             processed = {}
   281             for field in self.iter_modified_fields():
   282             for field in self.iter_modified_fields():
   282                 try:
   283                 try:
   283                     for field, value in field.process_posted(self):
   284                     for field, value in field.process_posted(self):
   439     # controller side method (eg POST reception handling)
   440     # controller side method (eg POST reception handling)
   440 
   441 
   441     def actual_eid(self, eid):
   442     def actual_eid(self, eid):
   442         # should be either an int (existant entity) or a variable (to be
   443         # should be either an int (existant entity) or a variable (to be
   443         # created entity)
   444         # created entity)
   444         assert eid or eid == 0, repr(eid) # 0 is a valid eid
   445         assert eid or eid == 0, repr(eid)  # 0 is a valid eid
   445         try:
   446         try:
   446             return int(eid)
   447             return int(eid)
   447         except ValueError:
   448         except ValueError:
   448             try:
   449             try:
   449                 return self._cw.data['eidmap'][eid]
   450                 return self._cw.data['eidmap'][eid]
   468         subform.parent_form = self
   469         subform.parent_form = self
   469         self.forms.append(subform)
   470         self.forms.append(subform)
   470 
   471 
   471     def build_context(self, formvalues=None):
   472     def build_context(self, formvalues=None):
   472         super(CompositeFormMixIn, self).build_context(formvalues)
   473         super(CompositeFormMixIn, self).build_context(formvalues)
   473         for form in self.forms:
   474         for form_ in self.forms:
   474             form.build_context(formvalues)
   475             form_.build_context(formvalues)
   475 
   476 
   476 
   477 
   477 class CompositeForm(CompositeFormMixIn, FieldsForm):
   478 class CompositeForm(CompositeFormMixIn, FieldsForm):
   478     """Form composed of sub-forms. Typical usage is edition of multiple entities
   479     """Form composed of sub-forms. Typical usage is edition of multiple entities
   479     at once.
   480     at once.
   480     """
   481     """
   481 
   482 
       
   483 
   482 class CompositeEntityForm(CompositeFormMixIn, EntityFieldsForm):
   484 class CompositeEntityForm(CompositeFormMixIn, EntityFieldsForm):
   483     pass # XXX why is this class necessary?
   485     pass  # XXX why is this class necessary?