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