279 return field |
279 return field |
280 raise FieldNotFound(name) |
280 raise FieldNotFound(name) |
281 |
281 |
282 @iclassmethod |
282 @iclassmethod |
283 def remove_field(cls_or_self, field): |
283 def remove_field(cls_or_self, field): |
|
284 """remove a field from form class or instance""" |
284 if isinstance(cls_or_self, type): |
285 if isinstance(cls_or_self, type): |
285 fields = cls_or_self._fields_ |
286 fields = cls_or_self._fields_ |
286 else: |
287 else: |
287 fields = cls_or_self.fields |
288 fields = cls_or_self.fields |
288 fields.remove(field) |
289 fields.remove(field) |
289 |
290 |
290 @iclassmethod |
291 @iclassmethod |
291 def append_field(cls_or_self, field): |
292 def append_field(cls_or_self, field): |
|
293 """append a field to form class or instance""" |
292 if isinstance(cls_or_self, type): |
294 if isinstance(cls_or_self, type): |
293 fields = cls_or_self._fields_ |
295 fields = cls_or_self._fields_ |
294 else: |
296 else: |
295 fields = cls_or_self.fields |
297 fields = cls_or_self.fields |
296 fields.append(field) |
298 fields.append(field) |
297 |
299 |
298 @property |
300 @property |
299 def form_needs_multipart(self): |
301 def form_needs_multipart(self): |
|
302 """true if the form needs enctype=multipart/form-data""" |
300 return any(field.needs_multipart for field in self.fields) |
303 return any(field.needs_multipart for field in self.fields) |
301 |
304 |
302 def form_add_hidden(self, name, value=None, **kwargs): |
305 def form_add_hidden(self, name, value=None, **kwargs): |
|
306 """add an hidden field to the form""" |
303 field = StringField(name=name, widget=fwdgs.HiddenInput, initial=value, |
307 field = StringField(name=name, widget=fwdgs.HiddenInput, initial=value, |
304 **kwargs) |
308 **kwargs) |
305 if 'id' in kwargs: |
309 if 'id' in kwargs: |
306 # by default, hidden input don't set id attribute. If one is |
310 # by default, hidden input don't set id attribute. If one is |
307 # explicitly specified, ensure it will be set |
311 # explicitly specified, ensure it will be set |
315 self.req.add_js(self.needs_js) |
319 self.req.add_js(self.needs_js) |
316 if self.needs_css: |
320 if self.needs_css: |
317 self.req.add_css(self.needs_css) |
321 self.req.add_css(self.needs_css) |
318 |
322 |
319 def form_render(self, **values): |
323 def form_render(self, **values): |
|
324 """render this form, using the renderer given in args or the default |
|
325 FormRenderer() |
|
326 """ |
320 renderer = values.pop('renderer', FormRenderer()) |
327 renderer = values.pop('renderer', FormRenderer()) |
321 return renderer.render(self, values) |
328 return renderer.render(self, values) |
322 |
329 |
323 def form_build_context(self, values=None): |
330 def form_build_context(self, rendervalues=None): |
|
331 """build form context values (the .context attribute which is a |
|
332 dictionary with field instance as key associated to a dictionary |
|
333 containing field 'name' (qualified), 'id', 'value' (for display, always |
|
334 a string). |
|
335 |
|
336 rendervalues is an optional dictionary containing extra kwargs given to |
|
337 form_render() |
|
338 """ |
324 self.context = context = {} |
339 self.context = context = {} |
325 # on validation error, we get a dictionnary of previously submitted values |
340 # on validation error, we get a dictionnary of previously submitted values |
326 if values is None: |
341 if values is None: |
327 values = {} |
342 values = {} |
328 previous_values = self.req.data.get('formvalues') |
343 previous_values = self.req.data.get('formvalues') |