web/form.py
changeset 3451 6b46d73823f5
parent 3023 7864fee8b4ec
child 3475 9c07e6c48e35
equal deleted inserted replaced
3448:495862266785 3451:6b46d73823f5
    42 
    42 
    43     def session_key(self):
    43     def session_key(self):
    44         """return the key that may be used to store / retreive data about a
    44         """return the key that may be used to store / retreive data about a
    45         previous post which failed because of a validation error
    45         previous post which failed because of a validation error
    46         """
    46         """
    47         return '%s#%s' % (self.req.url(), self.domid)
    47         return '%s#%s' % (self._cw.url(), self.domid)
    48 
    48 
    49     def __init__(self, req, rset, **kwargs):
    49     def __init__(self, req, rset, **kwargs):
    50         super(FormMixIn, self).__init__(req, rset=rset, **kwargs)
    50         super(FormMixIn, self).__init__(req, rset=rset, **kwargs)
    51         self.restore_previous_post(self.session_key())
    51         self.restore_previous_post(self.session_key())
    52 
    52 
    53     def restore_previous_post(self, sessionkey):
    53     def restore_previous_post(self, sessionkey):
    54         # get validation session data which may have been previously set.
    54         # get validation session data which may have been previously set.
    55         # deleting validation errors here breaks form reloading (errors are
    55         # deleting validation errors here breaks form reloading (errors are
    56         # no more available), they have to be deleted by application's publish
    56         # no more available), they have to be deleted by application's publish
    57         # method on successful commit
    57         # method on successful commit
    58         forminfo = self.req.get_session_data(sessionkey, pop=True)
    58         forminfo = self._cw.get_session_data(sessionkey, pop=True)
    59         if forminfo:
    59         if forminfo:
    60             # XXX remove req.data assigment once cw.web.widget is killed
    60             # XXX remove req.data assigment once cw.web.widget is killed
    61             self.req.data['formvalues'] = self.form_previous_values = forminfo['values']
    61             self._cw.data['formvalues'] = self.form_previous_values = forminfo['values']
    62             self.req.data['formerrors'] = self.form_valerror = forminfo['errors']
    62             self._cw.data['formerrors'] = self.form_valerror = forminfo['errors']
    63             self.req.data['displayederrors'] = self.form_displayed_errors = set()
    63             self._cw.data['displayederrors'] = self.form_displayed_errors = set()
    64             # if some validation error occured on entity creation, we have to
    64             # if some validation error occured on entity creation, we have to
    65             # get the original variable name from its attributed eid
    65             # get the original variable name from its attributed eid
    66             foreid = self.form_valerror.entity
    66             foreid = self.form_valerror.entity
    67             for var, eid in forminfo['eidmap'].items():
    67             for var, eid in forminfo['eidmap'].items():
    68                 if foreid == eid:
    68                 if foreid == eid:
    96         return False
    96         return False
    97 
    97 
    98 
    98 
    99     def button(self, label, klass='validateButton', tabindex=None, **kwargs):
    99     def button(self, label, klass='validateButton', tabindex=None, **kwargs):
   100         if tabindex is None:
   100         if tabindex is None:
   101             tabindex = self.req.next_tabindex()
   101             tabindex = self._cw.next_tabindex()
   102         return tags.input(value=label, klass=klass, **kwargs)
   102         return tags.input(value=label, klass=klass, **kwargs)
   103 
   103 
   104     def action_button(self, label, onclick=None, __action=None, **kwargs):
   104     def action_button(self, label, onclick=None, __action=None, **kwargs):
   105         if onclick is None:
   105         if onclick is None:
   106             onclick = "postForm('__action_%s', \'%s\', \'%s\')" % (
   106             onclick = "postForm('__action_%s', \'%s\', \'%s\')" % (
   107                 __action, label, self.domid)
   107                 __action, label, self.domid)
   108         return self.button(label, onclick=onclick, **kwargs)
   108         return self.button(label, onclick=onclick, **kwargs)
   109 
   109 
   110     def button_ok(self, label=None, type='submit', name='defaultsubmit',
   110     def button_ok(self, label=None, type='submit', name='defaultsubmit',
   111                   **kwargs):
   111                   **kwargs):
   112         label = self.req._(label or stdmsgs.BUTTON_OK).capitalize()
   112         label = self._cw._(label or stdmsgs.BUTTON_OK).capitalize()
   113         return self.button(label, name=name, type=type, **kwargs)
   113         return self.button(label, name=name, type=type, **kwargs)
   114 
   114 
   115     def button_apply(self, label=None, type='button', **kwargs):
   115     def button_apply(self, label=None, type='button', **kwargs):
   116         label = self.req._(label or stdmsgs.BUTTON_APPLY).capitalize()
   116         label = self._cw._(label or stdmsgs.BUTTON_APPLY).capitalize()
   117         return self.action_button(label, __action='apply', type=type, **kwargs)
   117         return self.action_button(label, __action='apply', type=type, **kwargs)
   118 
   118 
   119     def button_delete(self, label=None, type='button', **kwargs):
   119     def button_delete(self, label=None, type='button', **kwargs):
   120         label = self.req._(label or stdmsgs.BUTTON_DELETE).capitalize()
   120         label = self._cw._(label or stdmsgs.BUTTON_DELETE).capitalize()
   121         return self.action_button(label, __action='delete', type=type, **kwargs)
   121         return self.action_button(label, __action='delete', type=type, **kwargs)
   122 
   122 
   123     def button_cancel(self, label=None, type='button', **kwargs):
   123     def button_cancel(self, label=None, type='button', **kwargs):
   124         label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
   124         label = self._cw._(label or stdmsgs.BUTTON_CANCEL).capitalize()
   125         return self.action_button(label, __action='cancel', type=type, **kwargs)
   125         return self.action_button(label, __action='cancel', type=type, **kwargs)
   126 
   126 
   127     def button_reset(self, label=None, type='reset', name='__action_cancel',
   127     def button_reset(self, label=None, type='reset', name='__action_cancel',
   128                      **kwargs):
   128                      **kwargs):
   129         label = self.req._(label or stdmsgs.BUTTON_CANCEL).capitalize()
   129         label = self._cw._(label or stdmsgs.BUTTON_CANCEL).capitalize()
   130         return self.button(label, type=type, **kwargs)
   130         return self.button(label, type=type, **kwargs)
   131 
   131 
   132     def need_multipart(self, entity, categories=('primary', 'secondary')):
   132     def need_multipart(self, entity, categories=('primary', 'secondary')):
   133         """return a boolean indicating if form's enctype should be multipart
   133         """return a boolean indicating if form's enctype should be multipart
   134         """
   134         """
   138         # let's find if any of our inlined entities needs multipart
   138         # let's find if any of our inlined entities needs multipart
   139         for rschema, targettypes, x in entity.relations_by_category('inlineview'):
   139         for rschema, targettypes, x in entity.relations_by_category('inlineview'):
   140             assert len(targettypes) == 1, \
   140             assert len(targettypes) == 1, \
   141                    "I'm not able to deal with several targets and inlineview"
   141                    "I'm not able to deal with several targets and inlineview"
   142             ttype = targettypes[0]
   142             ttype = targettypes[0]
   143             inlined_entity = self.vreg.etype_class(ttype)(self.req, None, None)
   143             inlined_entity = self.vreg.etype_class(ttype)(self._cw, None, None)
   144             for irschema, _, x in inlined_entity.relations_by_category(categories):
   144             for irschema, _, x in inlined_entity.relations_by_category(categories):
   145                 if inlined_entity.get_widget(irschema, x).need_multipart:
   145                 if inlined_entity.get_widget(irschema, x).need_multipart:
   146                     return True
   146                     return True
   147         return False
   147         return False
   148 
   148 
   149     def error_message(self):
   149     def error_message(self):
   150         """return formatted error message
   150         """return formatted error message
   151 
   151 
   152         This method should be called once inlined field errors has been consumed
   152         This method should be called once inlined field errors has been consumed
   153         """
   153         """
   154         errex = self.req.data.get('formerrors') or self.form_valerror
   154         errex = self._cw.data.get('formerrors') or self.form_valerror
   155         # get extra errors
   155         # get extra errors
   156         if errex is not None:
   156         if errex is not None:
   157             errormsg = self.req._('please correct the following errors:')
   157             errormsg = self._cw._('please correct the following errors:')
   158             displayed = self.req.data.get('displayederrors') or self.form_displayed_errors
   158             displayed = self._cw.data.get('displayederrors') or self.form_displayed_errors
   159             errors = sorted((field, err) for field, err in errex.errors.items()
   159             errors = sorted((field, err) for field, err in errex.errors.items()
   160                             if not field in displayed)
   160                             if not field in displayed)
   161             if errors:
   161             if errors:
   162                 if len(errors) > 1:
   162                 if len(errors) > 1:
   163                     templstr = '<li>%s</li>\n'
   163                     templstr = '<li>%s</li>\n'
   165                     templstr = '&#160;%s\n'
   165                     templstr = '&#160;%s\n'
   166                 for field, err in errors:
   166                 for field, err in errors:
   167                     if field is None:
   167                     if field is None:
   168                         errormsg += templstr % err
   168                         errormsg += templstr % err
   169                     else:
   169                     else:
   170                         errormsg += templstr % '%s: %s' % (self.req._(field), err)
   170                         errormsg += templstr % '%s: %s' % (self._cw._(field), err)
   171                 if len(errors) > 1:
   171                 if len(errors) > 1:
   172                     errormsg = '<ul>%s</ul>' % errormsg
   172                     errormsg = '<ul>%s</ul>' % errormsg
   173             return u'<div class="errorMessage">%s</div>' % errormsg
   173             return u'<div class="errorMessage">%s</div>' % errormsg
   174         return u''
   174         return u''
   175 
   175