debian-quixote3/quixote/form/compatibility.py

99 lines
3.3 KiB
Python

'''A Form subclass that provides close to the same API as the old form
class (useful for transitioning existing forms).
'''
from quixote import get_request, get_path, redirect
from quixote.form import Form as _Form, Widget, StringWidget, FileWidget, \
PasswordWidget, TextWidget, CheckboxWidget, RadiobuttonsWidget, \
SingleSelectWidget, SelectWidget, OptionSelectWidget, \
MultipleSelectWidget, SubmitWidget, HiddenWidget, \
FloatWidget, IntWidget
from quixote.html import url_quote
_widget_names = {
"string" : StringWidget,
"file" : FileWidget,
"password" : PasswordWidget,
"text" : TextWidget,
"checkbox" : CheckboxWidget,
"single_select" : SingleSelectWidget,
"radiobuttons" : RadiobuttonsWidget,
"multiple_select" : MultipleSelectWidget,
"submit_button" : SubmitWidget,
"hidden" : HiddenWidget,
"float" : FloatWidget,
"int" : IntWidget,
"option_select" : OptionSelectWidget,
}
class Form(_Form):
def __init__(self, action_url=None, *args, **kwargs):
_Form.__init__(self, action=action_url, *args, **kwargs)
self.cancel_url = None
self.action_url = self.action
def add_widget(self, widget_class, name, value=None,
title=None, hint=None, required=False, **kwargs):
try:
widget_class = _widget_names[widget_class]
except KeyError:
pass
self.add(widget_class, name, value=value, title=title, hint=hint,
required=required, **kwargs)
def add_submit_button(self, name, value):
self.add_submit(name, value)
def add_cancel_button(self, caption, url):
self.add_submit("cancel", caption)
self.cancel_url = url
def get_action_url(self):
action_url = url_quote(get_path())
query = get_request().get_query()
if query:
action_url += "?" + query
return action_url
def render(self, action_url=None):
if action_url:
self.action_url = action_url
return _Form.render(self)
def process(self):
values = {}
request = get_request()
for name, widget in self._names.items():
values[name] = widget.parse()
return values
def action(self, submit, values):
raise NotImplementedError("sub-classes must implement 'action()'")
def handle(self):
"""handle() -> string
Master method for handling forms. It should be called after
initializing a form. Controls form action based on a request. You
probably should override 'process' and 'action' instead of
overriding this method.
"""
request = get_request()
if not self.is_submitted():
return self.render(self.action_url)
submit = self.get_submit()
if submit == "cancel":
return redirect(self.cancel_url)
values = self.process()
if submit == True:
# The form was submitted by an unregistered submit button, assume
# that the submission was required to update the layout of the form.
self.clear_errors()
return self.render(self.action_url)
if self.has_errors():
return self.render(self.action_url)
else:
return self.action(submit, values)