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' |