forms: add support for display location settings to block subfields (#51889)

This commit is contained in:
Frédéric Péters 2021-03-11 21:48:09 +01:00
parent 218b4a8036
commit 025dd54212
5 changed files with 138 additions and 2 deletions

View File

@ -1401,3 +1401,111 @@ def test_block_add_and_locked_field(pub, blocks_feature):
resp.form['f1$element2$f123'] = 'c'
resp = resp.form.submit('submit') # -> validation page
resp = resp.form.submit('submit') # -> submit
def test_block_subfields_display_locations(pub, blocks_feature):
FormDef.wipe()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
fields.TitleField(id='234', label='Blah Title', type='title'),
fields.SubtitleField(id='345', label='Blah Subtitle', type='subtitle'),
fields.CommentField(id='456', label='Blah Comment', type='comment'),
]
block.store()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='1', label='test', type='block:foobar'),
]
formdef.store()
# default mode
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'Blah Field'
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp.text
assert not resp.pyquery('[style="display: none"] [data-field-id="123"]')
assert resp.pyquery('[data-field-id="234"]')
assert not resp.pyquery('[style="display: none"] [data-field-id="234"]')
assert resp.pyquery('[data-field-id="345"]')
assert not resp.pyquery('[style="display: none"] [data-field-id="345"]')
resp = resp.form.submit('submit').follow() # -> submitted
assert 'Blah Field' in resp.text
assert 'Blah Title' in resp.text
assert 'Blah Subtitle' in resp.text
assert 'Blah Comment' not in resp.text
# all on validation page
for field in block.fields:
field.display_locations = ['validation']
block.store()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'Blah Field'
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp.text
assert not resp.pyquery('[style="display: none"] [data-field-id="123"]')
assert resp.pyquery('[data-field-id="234"]')
assert not resp.pyquery('[style="display: none"] [data-field-id="234"]')
assert resp.pyquery('[data-field-id="345"]')
assert not resp.pyquery('[style="display: none"] [data-field-id="345"]')
assert resp.pyquery('[data-field-id="456"]')
assert not resp.pyquery('[style="display: none"] [data-field-id="456"]')
# none on validation page
for field in block.fields:
field.display_locations = []
block.store()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'Blah Field'
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp.text
assert resp.pyquery('[style="display: none"] [data-field-id="123"]')
assert resp.pyquery('[style="display: none"] [data-field-id="234"]')
assert resp.pyquery('[style="display: none"] [data-field-id="345"]')
assert not resp.pyquery('[data-field-id="456"]')
# all on summary page
for field in block.fields:
field.display_locations = ['summary']
block.store()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'Blah Field'
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp.text
resp = resp.form.submit('submit').follow() # -> submitted
assert 'Blah Field' in resp.text
assert 'Blah Title' in resp.text
assert 'Blah Subtitle' in resp.text
assert 'Blah Comment' in resp.text
# none on summary page
for field in block.fields:
field.display_locations = []
block.store()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'Blah Field'
resp = resp.form.submit('submit') # -> validation page
assert 'Check values then click submit.' in resp.text
resp = resp.form.submit('submit').follow() # -> submitted
assert 'Blah Field' not in resp.text
assert 'Blah Title' not in resp.text
assert 'Blah Subtitle' not in resp.text
assert 'Blah Comment' not in resp.text

View File

@ -3230,7 +3230,9 @@ class BlockField(WidgetField):
parts.append(self.block.get_display_value(subvalue))
return ', '.join(parts)
def get_view_value(self, value, **kwargs):
def get_view_value(self, value, summary=False, **kwargs):
from wcs.workflows import template_on_formdata
if 'value_id' not in kwargs:
# when called from get_rst_view_value()
return str(value or '')
@ -3238,8 +3240,28 @@ class BlockField(WidgetField):
r = TemplateIO(html=True)
for i, row_value in enumerate(value['data']):
for field in self.block.fields:
if summary and not field.include_in_summary_page:
continue
if not hasattr(field, 'get_value_info'):
# inert field
if field.include_in_summary_page:
if field.type == 'title':
label = template_on_formdata(None, field.label, autoescape=False)
r += htmltext('<div class="title %s"><h3>%s</h3></div>') % (
field.extra_css_class or '',
label,
)
elif field.type == 'subtitle':
label = template_on_formdata(None, field.label, autoescape=False)
r += htmltext('<div class="subtitle %s"><h4>%s</h4></div>') % (
field.extra_css_class or '',
label,
)
elif field.type == 'comment':
r += htmltext(
'<div class="comment-field %s">%s</div>'
% (field.extra_css_class or '', field.get_text())
)
continue
css_classes = ['field', 'field-type-%s' % field.key]
if field.extra_css_class:

View File

@ -511,7 +511,7 @@ class FormStatusPage(Directory, FormTemplateMixin):
r += htmltext('<div class="value"><i>%s</i></div>') % _('Not set')
else:
r += htmltext('<div class="value">')
s = f.get_view_value(value, **value_details)
s = f.get_view_value(value, summary=True, **value_details)
s = s.replace(str('[download]'), str('%sdownload' % form_url))
r += s
r += htmltext('</div>')

View File

@ -301,6 +301,10 @@ div.dataview .value {
margin-left: 1em;
}
div.dataview .field-type-block > .value {
margin-left: 0;
}
form div.page,
div.dataview div.page {
border: 1px solid #aaa;

View File

@ -3,6 +3,8 @@
{% block widget-content %}
{% for subwidget in widget.get_widgets %}
{% if widget.readonly and not subwidget.field.include_in_validation_page %}<div style="display: none">{% endif %}
{{ subwidget.render|safe }}
{% if widget.readonly and not subwidget.field.include_in_validation_page %}</div>{% endif %}
{% endfor %}
{% if not widget.readonly and widget.remove_button %}<button class="remove-button" title="{% trans "Remove" %}"><span>-</span></button>{% endif %} {% endblock %}