2006-03-16 21:18:21 +01:00
|
|
|
'''A Form subclass that provides close to the same API as the old form
|
2006-03-16 01:58:21 +01:00
|
|
|
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):
|
2016-03-24 23:25:53 +01:00
|
|
|
raise NotImplementedError("sub-classes must implement 'action()'")
|
2006-03-16 01:58:21 +01:00
|
|
|
|
|
|
|
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)
|