forms: flatten list of steps (#8355)

This commit is contained in:
Frédéric Péters 2015-09-26 11:20:28 +02:00
parent a58fcf4cae
commit b4f9caf21f
3 changed files with 62 additions and 56 deletions

View File

@ -1,6 +1,7 @@
import pytest
import hashlib
import os
import re
from webtest import Upload
from wcs.qommon.ident.password_accounts import PasswordAccount
@ -240,6 +241,10 @@ def test_form_string_field_submit(pub):
data = formdef.data_class().get(data_id)
assert data.data == {'0': 'foobar'}
def assert_current_page(resp, page_label):
assert re.findall('<li class=".*?current.*?">.*?<span class="label">(.*?)</span></li>',
resp.body)[0] == page_label
def test_form_multi_page(pub):
formdef = create_formdef()
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),
@ -252,9 +257,11 @@ def test_form_multi_page(pub):
page.forms[0]['f1'] = 'foo'
assert page.forms[0].fields['submit'][0].value_if_submitted() == 'Next'
next_page = page.forms[0].submit('submit')
assert_current_page(next_page, '2nd page')
assert next_page.forms[0]['previous']
next_page.forms[0]['f3'] = 'bar'
next_page = next_page.forms[0].submit('submit')
assert_current_page(next_page, 'Validating')
assert 'Check values then click submit.' in next_page.body
next_page = next_page.forms[0].submit('submit')
assert next_page.status_int == 302
@ -301,14 +308,14 @@ def test_form_multi_page_condition_select(pub):
resp = resp.forms[0].submit('submit')
assert '2nd page' in resp.body
assert not '3rd page' in resp.body
assert '<li class="current"><span>2nd page</span>' in resp.body
assert_current_page(resp, '2nd page')
resp = get_app(pub).get('/test/')
resp.forms[0]['f1'] = 'Bar'
resp = resp.forms[0].submit('submit')
assert not '2nd page' in resp.body
assert '3rd page' in resp.body
assert '<li class="current"><span>3rd page</span>' in resp.body
assert_current_page(resp, '3rd page')
def test_form_multi_page_condition_select_new_varname(pub):
formdef = create_formdef()
@ -330,14 +337,14 @@ def test_form_multi_page_condition_select_new_varname(pub):
resp = resp.forms[0].submit('submit')
assert '2nd page' in resp.body
assert not '3rd page' in resp.body
assert '<li class="current"><span>2nd page</span>' in resp.body
assert_current_page(resp, '2nd page')
resp = get_app(pub).get('/test/')
resp.forms[0]['f1'] = 'Bar'
resp = resp.forms[0].submit('submit')
assert not '2nd page' in resp.body
assert '3rd page' in resp.body
assert '<li class="current"><span>3rd page</span>' in resp.body
assert_current_page(resp, '3rd page')
def test_form_multi_page_condition_checkbox(pub):
formdef = create_formdef()

View File

@ -201,8 +201,6 @@ class FormPage(Directory):
_q_exports = ['', 'listing', 'tempfile', 'tokens', 'schema', 'tryauth',
'auth', 'qrcode', 'autosave', 'code']
steps = [N_("Filling"), N_("Validating"), N_("Receipt")]
def __init__(self, component):
try:
self.formdef = FormDef.get_by_urlname(component)
@ -249,50 +247,57 @@ class FormPage(Directory):
if not user_roles.intersection(other_roles):
raise errors.AccessForbiddenError()
def step(self, no, page_no = 0, log_detail = None, data = None, editing = None):
r = TemplateIO(html=True)
r += htmltext('<div id="steps"><ol>')
steps = self.steps[:]
if not self.formdef.confirmation:
del steps[1]
self.substvars['current_step'] = steps[no]
if no == 0:
def step(self, step_no, page_no = 0, log_detail = None, data = None, editing = None):
if step_no == 0:
self.substvars['current_page_no'] = str(page_no + 1)
if log_detail:
get_logger().info('form %s - step %s (%s)' % (self.formdef.name, steps[no], log_detail))
get_logger().info('form %s - step %s (%s)' % (self.formdef.name, step_no, log_detail))
else:
get_logger().info('form %s - step %s' % (self.formdef.name, steps[no]))
for i, l in enumerate(steps[:-1]):
classes = ['step-%d' % i]
if no == i:
classes.append('current')
elif no < i:
classes.append('step-after')
elif no > i:
classes.append('step-before')
if i+1 == len(steps):
classes.append('last')
if i == 0:
get_logger().info('form %s - step %s' % (self.formdef.name, step_no))
page_labels = []
current_position = 1
page_index = 0
for field in self.formdef.fields:
if field.type != 'page':
continue
if field.is_visible(data, self.formdef):
page_labels.append(field.label)
if page_index == page_no:
current_position = len(page_labels)
page_index += 1
if not page_labels:
page_labels.append(_('Filling'))
if step_no > 0:
current_position = len(page_labels) + step_no
if self.formdef.confirmation and not editing:
page_labels.append(_('Validating'))
r = TemplateIO(html=True)
r += htmltext('<div id="steps"><ol>')
for i, page_label in enumerate(page_labels):
classes = []
index = i + 1
if index == 1:
classes.append('first')
if index == len(page_labels):
classes.append('last')
if index == current_position:
classes.append('current')
elif index < current_position:
classes.append('step-before')
elif index > current_position:
classes.append('step-after')
r += htmltext('<li class="%s">') % ' '.join(classes)
r += htmltext('<span class="marker">%d</span> <span class="label">%s</span>') % (i+1, _(l))
if i == 0 and (no == i or True) and self.page_number > 1:
r += htmltext('<ul>')
t = 0
for field in self.formdef.fields:
if field.type != 'page':
continue
classes = []
if t == page_no and no == i:
classes.append('current')
t += 1
if not field.is_visible(data, self.formdef):
continue
r += htmltext('<li class="%s"><span>%s</span></li>') % (' '.join(classes), field.label)
r += htmltext('</ul>')
r += htmltext('<span class="marker">%d</span> <span class="label">%s</span>') % (
index, page_label)
r += htmltext('</li>')
if editing:
break
r += htmltext('</ol></div>')
return r.getvalue()

View File

@ -186,30 +186,25 @@ button.refresh {
/** steps **/
#steps {
height: 32px;
height: 52px;
margin-bottom: 1em;
background: #f0f0f0;
color: #aaa;
white-space: nowrap;
overflow: hidden;
}
#steps ol {
background: #f0f0f0;
list-style: none;
padding: 0 20px;
}
#steps li {
display: inline;
display: inline-block;
padding-right: 1em;
display: block;
float: left;
width: 30%;
list-style: none;
}
#steps ol ul {
display: none;
}
#steps span.marker {
font-size: 26px;
padding: 2px 9px;
@ -234,11 +229,10 @@ button.refresh {
color: black;
}
#steps ol ul {
#steps li.step-before .label {
display: none;
}
/** logs **/
form#other-log-select {
margin-top: 2em;