forms: use a template to render radio buttons (#27996)

This commit is contained in:
Frédéric Péters 2018-11-14 15:14:18 +01:00
parent 3e2fecfd9f
commit 70704e7c63
3 changed files with 34 additions and 35 deletions

View File

@ -4518,16 +4518,14 @@ def test_form_page_profile_verified_radio_item_prefill(pub):
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
assert resp.form['f0'].value == 'foo@localhost'
assert 'readonly' in resp.form['f0'].attrs
assert 'disabled' in resp.form['f0'].attrs
for radio in resp.html.findAll('input'):
if radio['name'] == 'f0':
if radio['value'] == 'foo@localhost':
assert radio.attrs.get('checked')
assert radio.attrs.get('readonly')
assert not radio.attrs.get('disabled')
else:
assert not radio.attrs.get('checked')
assert radio.attrs.get('readonly')
assert radio.attrs.get('disabled')
resp.form['f0'].value = 'baz@localhost' # try changing the value
@ -4561,7 +4559,8 @@ def test_item_field_with_disabled_items(http_requests, pub):
data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
resp = get_app(pub).get('/test/')
assert '<option disabled="disabled" value="1">hello</option>' in resp.body
pq = resp.pyquery.remove_namespaces()
assert pq('option[disabled=disabled][value="1"]').text() == 'hello'
resp.form['f0'] = '1'
resp.form['f0'] = '2'
resp = resp.form.submit('submit') # -> validation page
@ -4570,7 +4569,8 @@ def test_item_field_with_disabled_items(http_requests, pub):
assert formdef.data_class().select()[0].data['0_display'] == 'world'
resp = get_app(pub).get('/test/')
assert '<option disabled="disabled" value="1">hello</option>' in resp.body
pq = resp.pyquery.remove_namespaces()
assert pq('option[disabled=disabled][value="1"]').text() == 'hello'
resp.form['f0'] = '1'
resp = resp.form.submit('submit') # -> validation page
assert 'There were errors processing the form' in resp.body
@ -4584,7 +4584,8 @@ def test_item_field_with_disabled_items(http_requests, pub):
data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
resp = get_app(pub).get('/test/')
assert not '<option disabled="disabled" value="1">hello</option>' in resp.body
pq = resp.pyquery.remove_namespaces()
assert len(pq('option[disabled=disabled][value="1"]')) == 0
resp.form['f0'] = '2'
resp = resp.form.submit('submit') # -> validation page
resp = resp.form.submit('submit') # -> submit
@ -4613,7 +4614,8 @@ def test_item_field_with_disabled_items(http_requests, pub):
data = {'data': [{'id': '1', 'text': 'hello', 'disabled': True}, {'id': '2', 'text': 'world'}]}
urlopen.side_effect = lambda *args: StringIO.StringIO(json.dumps(data))
resp = get_app(pub).get('/test/')
assert '<input disabled="disabled" type="radio" name="f0" value="1" />' in resp.body
pq = resp.pyquery.remove_namespaces()
assert len(pq('input[name="f0"][disabled=disabled][value="1"]')) == 1
resp.form['f0'] = '1'
resp.form['f0'] = '2'
resp = resp.form.submit('submit') # -> validation page
@ -4622,7 +4624,8 @@ def test_item_field_with_disabled_items(http_requests, pub):
assert formdef.data_class().select()[0].data['0_display'] == 'world'
resp = get_app(pub).get('/test/')
assert '<input disabled="disabled" type="radio" name="f0" value="1" />' in resp.body
pq = resp.pyquery.remove_namespaces()
assert len(pq('input[name="f0"][disabled=disabled][value="1"]')) == 1
resp.form['f0'] = '1'
resp = resp.form.submit('submit') # -> validation page
assert 'There were errors processing the form' in resp.body

View File

@ -195,39 +195,22 @@ class SubmitWidget(quixote.form.widget.SubmitWidget):
class RadiobuttonsWidget(quixote.form.RadiobuttonsWidget):
template_name = 'qommon/forms/widgets/radiobuttons.html'
def __init__(self, name, value=None, **kwargs):
self.options_with_attributes = kwargs.pop('options_with_attributes', None)
super(RadiobuttonsWidget, self).__init__(name, value=value, **kwargs)
def render_content(self):
include_disabled = False
options = self.options[:]
if self.options_with_attributes:
options = self.options_with_attributes
include_disabled = True
r = TemplateIO(html=True)
def get_options(self):
options = self.options_with_attributes or self.options
for i, option in enumerate(options):
object, description, key = option[:3]
r += htmltext('<label>')
html_attrs = self.attrs.copy()
if self.is_selected(object):
html_attrs['checked'] = 'checked'
elif self.attrs.get('readonly'):
html_attrs['disabled'] = 'disabled'
if self.options_with_attributes and option[-1].get('disabled'):
html_attrs['disabled'] = 'disabled'
label_tag = htmltext('<label class="disabled">')
r += htmltag("input", xml_end=True,
type="radio",
name=self.name,
value=key,
**html_attrs)
r += htmltext('<span>%s</span>') % description
r += htmltext('</label>')
if i != len(options) - 1:
r += htmltext(self.delim)
return r.getvalue()
yield {
'value': key,
'label': description,
'disabled': bool(self.options_with_attributes and option[-1].get('disabled')),
'selected': self.is_selected(object)
}
def checkbox_render_content(self, standalone=True):
attrs = {'id': 'form_' + self.name}

View File

@ -0,0 +1,13 @@
{% extends "qommon/forms/widget.html" %}
{% block widget-control %}
{% for option in widget.get_options %}
<label {% if option.disabled %}class="disabled"{% endif %}><input
{% if option.selected %}checked="checked"
{% elif widget.readonly or option.disabled %}disabled="disabled"{% endif %}
{% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
type="radio" name="{{ widget.name }}"
value="{{ option.value }}"><span>{{ option.label }}</span></label>
{% if not forloop.last %}{{ widget.delim|safe }}{% endif %}
{% endfor %}
{% endblock %}