forms: consider form pages with only inert fields in validation pages (#37709)

This commit is contained in:
Frédéric Péters 2019-12-08 15:44:23 +01:00
parent fa926506f8
commit fb0632d07f
2 changed files with 61 additions and 39 deletions

View File

@ -1270,6 +1270,28 @@ def test_form_display_locations(pub):
assert 'plop3' in resp.text
assert 'Bla bla bla' in resp.text
def test_multipage_form_display_locations(pub):
formdef = create_formdef()
formdef.fields = [
fields.PageField(id='0', label='1st page', type='page'),
fields.StringField(id='1', label='string1', display_locations=[]),
fields.PageField(id='2', label='2nd page', type='page'),
fields.CommentField(id='3', label='Bla bla bla', type='comment', display_locations=['validation']),
]
formdef.store()
formdef.data_class().wipe()
resp = get_app(pub).get('/test/')
resp.form['f1'] = 'plop1'
resp = resp.form.submit('submit') # -> page 2
resp = resp.form.submit('submit') # -> validation
pq = resp.pyquery.remove_namespaces()
assert not '<h3>1st page</h3>' in resp.text # page 1 title not displayed
assert pq('div[style="display: none;"] [name=f1]') # but page 1 field included, hidden
assert '<h3>2nd page</h3>' in resp.text # page 2 title
assert 'Bla bla bla' in resp.text # and page 2 comment field
def test_form_visit_existing(pub):
user = create_user(pub)
formdef = create_formdef()

View File

@ -605,62 +605,62 @@ class FormDef(StorableObject):
form.attrs['style'] = 'display: none;'
if self.keywords:
form.attrs['data-keywords'] = ' '.join(self.keywords_list)
current_page_fields = []
on_disabled_page = False
on_page = False
for i, field in enumerate(self.fields):
if field.type == 'page':
on_disabled_page = False
if not field.is_visible(dict, self):
on_disabled_page = True
form_field = False
for f in self.fields[self.fields.index(field)+1:]:
if f.key == 'page':
break
if isinstance(f, fields.WidgetField):
form_field = True
break
if form_field is False:
on_disabled_page = True
if on_disabled_page:
form_fields = self.fields
if form_fields and form_fields[0].type != 'page':
# add fake initial page in case it's missing
form_fields = [fields.PageField(label='', type='page')] + form_fields
# 1st pass to group fields on different pages
pages = []
current_page = {}
for field in form_fields:
if field.type == 'page':
current_page = {'page': field, 'fields': []}
current_page['disabled'] = not field.is_visible(dict, self)
pages.append(current_page)
continue
if field.type == 'page':
if on_page:
form.widgets.append(HtmlWidget(htmltext('</div></div>')))
form.widgets.append(HtmlWidget(
htmltext('<div class="page"><h3>%s</h3><div>' % field.label)))
on_page = field
current_page_fields = []
if current_page['disabled']:
continue
if field.type == 'title' and on_page and (
not current_page_fields and
on_page.label == field.label):
if field.type == 'title' and (
not current_page['fields'] and
current_page['page'].label == field.label):
# don't include first title of a page if that title has the
# same text as the page.
continue
if field.type == 'comment' and not field.include_in_validation_page:
if field.type in ('title', 'subtitle', 'comment') and not field.include_in_validation_page:
# don't render field that wouldn't be displayed.
continue
if not field.is_visible(dict, self):
continue
current_page_fields.append(field)
value = dict.get(field.id)
current_page['fields'].append(field)
if not field.include_in_validation_page:
form.widgets.append(HtmlWidget(htmltext('<div style="display: none;">')))
field.add_to_view_form(form, value)
form.widgets.append(HtmlWidget(htmltext('</div>')))
else:
field.add_to_view_form(form, value)
# 2nd pass to create view form
for page in pages:
visible_contents = False
if page['fields'] and any([x.include_in_validation_page for x in page['fields']]):
visible_contents = True
form.widgets.append(HtmlWidget(htmltext('<div class="page">')))
if page['page'].label:
form.widgets.append(HtmlWidget(htmltext('<h3>%s</h3>') % page['page'].label))
form.widgets.append(HtmlWidget(htmltext('<div>')))
if on_page:
form.widgets.append(HtmlWidget(htmltext('</div></div>')))
for field in page['fields']:
value = dict.get(field.id)
if not field.include_in_validation_page:
form.widgets.append(HtmlWidget(htmltext('<div style="display: none;">')))
field.add_to_view_form(form, value)
form.widgets.append(HtmlWidget(htmltext('</div>')))
else:
field.add_to_view_form(form, value)
if visible_contents:
form.widgets.append(HtmlWidget(htmltext('</div></div>')))
return form