Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #152 from jzellman/master

Enable web.form doctest and add form.GroupedDropdown
  • Loading branch information...
commit a832cb2a71a5059dcf61f6fa64c06bb290159ccd 2 parents c542f9b + fe8c9da
@aaronsw aaronsw authored
Showing with 57 additions and 23 deletions.
  1. +2 −1  test/doctests.py
  2. +55 −22 web/form.py
View
3  test/doctests.py
@@ -5,7 +5,8 @@
def suite():
modules = [
"web.application",
- "web.db",
+ "web.db",
+ "web.form",
"web.http",
"web.net",
"web.session",
View
77 web/form.py
@@ -25,7 +25,7 @@ class Form(object):
>>> f = Form(Textbox("x"))
>>> f.render()
- '<table>\n <tr><th><label for="x">x</label></th><td><input type="text" id="x" name="x"/></td></tr>\n</table>'
+ u'<table>\n <tr><th><label for="x">x</label></th><td><input type="text" id="x" name="x"/></td></tr>\n</table>'
"""
def __init__(self, *inputs, **kw):
self.inputs = inputs
@@ -194,9 +194,9 @@ class Textbox(Input):
"""Textbox input.
>>> Textbox(name='foo', value='bar').render()
- '<input type="text" id="foo" value="bar" name="foo"/>'
+ u'<input type="text" id="foo" value="bar" name="foo"/>'
>>> Textbox(name='foo', value=0).render()
- '<input type="text" id="foo" value="0" name="foo"/>'
+ u'<input type="text" id="foo" value="0" name="foo"/>'
"""
def get_type(self):
return 'text'
@@ -205,7 +205,7 @@ class Password(Input):
"""Password input.
>>> Password(name='password', value='secret').render()
- '<input type="password" id="password" value="secret" name="password"/>'
+ u'<input type="password" id="password" value="secret" name="password"/>'
"""
def get_type(self):
@@ -215,7 +215,7 @@ class Textarea(Input):
"""Textarea input.
>>> Textarea(name='foo', value='bar').render()
- '<textarea id="foo" name="foo">bar</textarea>'
+ u'<textarea id="foo" name="foo">bar</textarea>'
"""
def render(self):
attrs = self.attrs.copy()
@@ -227,9 +227,9 @@ class Dropdown(Input):
r"""Dropdown/select input.
>>> Dropdown(name='foo', args=['a', 'b', 'c'], value='b').render()
- '<select id="foo" name="foo">\n <option value="a">a</option>\n <option selected="selected" value="b">b</option>\n <option value="c">c</option>\n</select>\n'
+ u'<select id="foo" name="foo">\n <option value="a">a</option>\n <option selected="selected" value="b">b</option>\n <option value="c">c</option>\n</select>\n'
>>> Dropdown(name='foo', args=[('a', 'aa'), ('b', 'bb'), ('c', 'cc')], value='b').render()
- '<select id="foo" name="foo">\n <option value="a">aa</option>\n <option selected="selected" value="b">bb</option>\n <option value="c">cc</option>\n</select>\n'
+ u'<select id="foo" name="foo">\n <option value="a">aa</option>\n <option selected="selected" value="b">bb</option>\n <option value="c">cc</option>\n</select>\n'
"""
def __init__(self, name, args, *validators, **attrs):
self.args = args
@@ -242,15 +242,48 @@ def render(self):
x = '<select %s>\n' % attrs
for arg in self.args:
- if isinstance(arg, (tuple, list)):
- value, desc= arg
- else:
- value, desc = arg, arg
+ x += self._render_option(arg)
+
+ x += '</select>\n'
+ return x
+
+ def _render_option(self, arg, indent=' '):
+ if isinstance(arg, (tuple, list)):
+ value, desc= arg
+ else:
+ value, desc = arg, arg
+
+ if self.value == value or (isinstance(self.value, list) and value in self.value):
+ select_p = ' selected="selected"'
+ else:
+ select_p = ''
+ return indent + '<option%s value="%s">%s</option>\n' % (select_p, net.websafe(value), net.websafe(desc))
+
+
+class GroupedDropdown(Dropdown):
+ r"""Grouped Dropdown/select input.
+
+ >>> GroupedDropdown(name='car_type', args=(('Swedish Cars', ('Volvo', 'Saab')), ('German Cars', ('Mercedes', 'Audi'))), value='Audi').render()
+ u'<select id="car_type" name="car_type">\n <optgroup label="Swedish Cars">\n <option value="Volvo">Volvo</option>\n <option value="Saab">Saab</option>\n </optgroup>\n <optgroup label="German Cars">\n <option value="Mercedes">Mercedes</option>\n <option selected="selected" value="Audi">Audi</option>\n </optgroup>\n</select>\n'
+ >>> GroupedDropdown(name='car_type', args=(('Swedish Cars', (('v', 'Volvo'), ('s', 'Saab'))), ('German Cars', (('m', 'Mercedes'), ('a', 'Audi')))), value='a').render()
+ u'<select id="car_type" name="car_type">\n <optgroup label="Swedish Cars">\n <option value="v">Volvo</option>\n <option value="s">Saab</option>\n </optgroup>\n <optgroup label="German Cars">\n <option value="m">Mercedes</option>\n <option selected="selected" value="a">Audi</option>\n </optgroup>\n</select>\n'
- if self.value == value or (isinstance(self.value, list) and value in self.value):
- select_p = ' selected="selected"'
- else: select_p = ''
- x += ' <option%s value="%s">%s</option>\n' % (select_p, net.websafe(value), net.websafe(desc))
+ """
+ def __init__(self, name, args, *validators, **attrs):
+ self.args = args
+ super(Dropdown, self).__init__(name, *validators, **attrs)
+
+ def render(self):
+ attrs = self.attrs.copy()
+ attrs['name'] = self.name
+
+ x = '<select %s>\n' % attrs
+
+ for label, options in self.args:
+ x += ' <optgroup label="%s">\n' % net.websafe(label)
+ for arg in options:
+ x += self._render_option(arg, indent = ' ')
+ x += ' </optgroup>\n'
x += '</select>\n'
return x
@@ -281,14 +314,14 @@ class Checkbox(Input):
"""Checkbox input.
>>> Checkbox('foo', value='bar', checked=True).render()
- '<input checked="checked" type="checkbox" id="foo_bar" value="bar" name="foo"/>'
+ u'<input checked="checked" type="checkbox" id="foo_bar" value="bar" name="foo"/>'
>>> Checkbox('foo', value='bar').render()
- '<input type="checkbox" id="foo_bar" value="bar" name="foo"/>'
+ u'<input type="checkbox" id="foo_bar" value="bar" name="foo"/>'
>>> c = Checkbox('foo', value='bar')
>>> c.validate('on')
True
>>> c.render()
- '<input checked="checked" type="checkbox" id="foo_bar" value="bar" name="foo"/>'
+ u'<input checked="checked" type="checkbox" id="foo_bar" value="bar" name="foo"/>'
"""
def __init__(self, name, *validators, **attrs):
self.checked = attrs.pop('checked', False)
@@ -318,9 +351,9 @@ class Button(Input):
"""HTML Button.
>>> Button("save").render()
- '<button id="save" name="save">save</button>'
+ u'<button id="save" name="save">save</button>'
>>> Button("action", value="save", html="<b>Save Changes</b>").render()
- '<button id="action" value="save" name="action"><b>Save Changes</b></button>'
+ u'<button id="action" value="save" name="action"><b>Save Changes</b></button>'
"""
def __init__(self, name, *validators, **attrs):
super(Button, self).__init__(name, *validators, **attrs)
@@ -338,7 +371,7 @@ class Hidden(Input):
"""Hidden Input.
>>> Hidden(name='foo', value='bar').render()
- '<input type="hidden" id="foo" value="bar" name="foo"/>'
+ u'<input type="hidden" id="foo" value="bar" name="foo"/>'
"""
def is_hidden(self):
return True
@@ -350,7 +383,7 @@ class File(Input):
"""File input.
>>> File(name='f').render()
- '<input type="file" id="f" name="f"/>'
+ u'<input type="file" id="f" name="f"/>'
"""
def get_type(self):
return 'file'
Please sign in to comment.
Something went wrong with that request. Please try again.