web/form.py
branchtls-sprint
changeset 1710 8c717cc0b353
parent 1701 9fb5b4741a08
child 1755 1bd225376013
equal deleted inserted replaced
1709:f7110f533d14 1710:8c717cc0b353
    73         # deleting validation errors here breaks form reloading (errors are
    73         # deleting validation errors here breaks form reloading (errors are
    74         # no more available), they have to be deleted by application's publish
    74         # no more available), they have to be deleted by application's publish
    75         # method on successful commit
    75         # method on successful commit
    76         forminfo = self.req.get_session_data(sessionkey, pop=True)
    76         forminfo = self.req.get_session_data(sessionkey, pop=True)
    77         if forminfo:
    77         if forminfo:
    78             self.req.data['formvalues'] = forminfo['values']
    78             # XXX remove req.data assigment once cw.web.widget is killed
    79             self.req.data['formerrors'] = errex = forminfo['errors']
    79             self.req.data['formvalues'] = self.form_previous_values = forminfo['values']
    80             self.req.data['displayederrors'] = set()
    80             self.req.data['formerrors'] = self.form_valerror = forminfo['errors']
       
    81             self.req.data['displayederrors'] = self.form_displayed_errors = set()
    81             # if some validation error occured on entity creation, we have to
    82             # if some validation error occured on entity creation, we have to
    82             # get the original variable name from its attributed eid
    83             # get the original variable name from its attributed eid
    83             foreid = errex.entity
    84             foreid = self.form_valerror.entity
    84             for var, eid in forminfo['eidmap'].items():
    85             for var, eid in forminfo['eidmap'].items():
    85                 if foreid == eid:
    86                 if foreid == eid:
    86                     errex.eid = var
    87                     self.form_valerror.eid = var
    87                     break
    88                     break
    88             else:
    89             else:
    89                 errex.eid = foreid
    90                 self.form_valerror.eid = foreid
       
    91         else:
       
    92             self.form_previous_values = {}
       
    93             self.form_valerror = None
    90 
    94 
    91     # XXX deprecated with new form system. Should disappear
    95     # XXX deprecated with new form system. Should disappear
    92 
    96 
    93     domid = 'entityForm'
    97     domid = 'entityForm'
    94     category = 'form'
    98     category = 'form'
   164     def error_message(self):
   168     def error_message(self):
   165         """return formatted error message
   169         """return formatted error message
   166 
   170 
   167         This method should be called once inlined field errors has been consumed
   171         This method should be called once inlined field errors has been consumed
   168         """
   172         """
   169         errex = self.req.data.get('formerrors')
   173         errex = self.req.data.get('formerrors') or self.form_valerror
   170         # get extra errors
   174         # get extra errors
   171         if errex is not None:
   175         if errex is not None:
   172             errormsg = self.req._('please correct the following errors:')
   176             errormsg = self.req._('please correct the following errors:')
   173             displayed = self.req.data['displayederrors']
   177             displayed = self.req.data.get('displayederrors') or self.form_displayed_errors
   174             errors = sorted((field, err) for field, err in errex.errors.items()
   178             errors = sorted((field, err) for field, err in errex.errors.items()
   175                             if not field in displayed)
   179                             if not field in displayed)
   176             if errors:
   180             if errors:
   177                 if len(errors) > 1:
   181                 if len(errors) > 1:
   178                     templstr = '<li>%s</li>\n'
   182                     templstr = '<li>%s</li>\n'
   331 
   335 
   332         rendervalues is an optional dictionary containing extra kwargs given to
   336         rendervalues is an optional dictionary containing extra kwargs given to
   333         form_render()
   337         form_render()
   334         """
   338         """
   335         self.context = context = {}
   339         self.context = context = {}
   336         # on validation error, we get a dictionary of previously submitted
       
   337         # values
       
   338         self._previous_values = self.req.data.get('formvalues', {})
       
   339         # ensure rendervalues is a dict
   340         # ensure rendervalues is a dict
   340         if rendervalues is None:
   341         if rendervalues is None:
   341             rendervalues = {}
   342             rendervalues = {}
   342         for field in self.fields:
   343         for field in self.fields:
   343             for field in field.actual_fields(self):
   344             for field in field.actual_fields(self):
   359 
   360 
   360         values found in 1. and 2. are expected te be already some 'display'
   361         values found in 1. and 2. are expected te be already some 'display'
   361         value while those found in 3. and 4. are expected to be correctly typed.
   362         value while those found in 3. and 4. are expected to be correctly typed.
   362         """
   363         """
   363         qname = self.form_field_name(field)
   364         qname = self.form_field_name(field)
   364         if qname in self._previous_values:
   365         if qname in self.form_previous_values:
   365             value = self._previous_values[qname]
   366             value = self.form_previous_values[qname]
   366         elif qname in self.req.form:
   367         elif qname in self.req.form:
   367             value = self.req.form[qname]
   368             value = self.req.form[qname]
   368         else:
   369         else:
   369             if field.name in rendervalues:
   370             if field.name in rendervalues:
   370                 value = rendervalues[field.name]
   371                 value = rendervalues[field.name]
   383             value = value(self)
   384             value = value(self)
   384         return value
   385         return value
   385 
   386 
   386     def form_field_error(self, field):
   387     def form_field_error(self, field):
   387         """return validation error for widget's field, if any"""
   388         """return validation error for widget's field, if any"""
   388         errex = self.req.data.get('formerrors')
   389         if self._field_has_error(field):
   389         if errex and self._errex_match_field(errex, field):
   390             self.form_displayed_errors.add(field.name)
   390             self.req.data['displayederrors'].add(field.name)
   391             return u'<span class="error">%s</span>' % self.form_valerror.errors[field.name]
   391             return u'<span class="error">%s</span>' % errex.errors[field.name]
       
   392         return u''
   392         return u''
   393 
   393 
   394     def form_field_format(self, field):
   394     def form_field_format(self, field):
   395         """return MIME type used for the given (text or bytes) field"""
   395         """return MIME type used for the given (text or bytes) field"""
   396         return self.req.property_value('ui.default-text-format')
   396         return self.req.property_value('ui.default-text-format')
   411         """return vocabulary for the given field. Should be overriden in
   411         """return vocabulary for the given field. Should be overriden in
   412         specific forms using fields which requires some vocabulary
   412         specific forms using fields which requires some vocabulary
   413         """
   413         """
   414         raise NotImplementedError
   414         raise NotImplementedError
   415 
   415 
   416     def _errex_match_field(self, errex, field):
   416     def _field_has_error(self, field):
   417         """return true if the field has some error in given validation exception
   417         """return true if the field has some error in given validation exception
   418         """
   418         """
   419         return field.name in errex.errors
   419         return self.form_valerror and field.name in self.form_valerror.errors
   420 
   420 
   421 
   421 
   422 class EntityFieldsForm(FieldsForm):
   422 class EntityFieldsForm(FieldsForm):
   423     __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
   423     __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
   424 
   424 
   441             self.form_add_hidden('__message', msg)
   441             self.form_add_hidden('__message', msg)
   442         # in case of direct instanciation
   442         # in case of direct instanciation
   443         self.schema = self.edited_entity.schema
   443         self.schema = self.edited_entity.schema
   444         self.vreg = self.edited_entity.vreg
   444         self.vreg = self.edited_entity.vreg
   445 
   445 
   446     def _errex_match_field(self, errex, field):
   446     def _field_has_error(self, field):
   447         """return true if the field has some error in given validation exception
   447         """return true if the field has some error in given validation exception
   448         """
   448         """
   449         return errex.eid == self.edited_entity.eid and field.name in errex.errors
   449         return super(EntityFieldsForm, self)._field_has_error(field) \
       
   450                and self.form_valerror.eid == self.edited_entity.eid
   450 
   451 
   451     def _relation_vocabulary(self, rtype, targettype, role,
   452     def _relation_vocabulary(self, rtype, targettype, role,
   452                             limit=None, done=None):
   453                             limit=None, done=None):
   453         """return unrelated entities for a given relation and target entity type
   454         """return unrelated entities for a given relation and target entity type
   454         for use in vocabulary
   455         for use in vocabulary